组件知识库

{
"kb": [
{
"name": "PC端代码规范",
"category": "代码规范",
"content": "## 代码规范\r\n* 采用Vue2框架,defineComponent定义组件; 使用typescript,但不要使用装饰器. data字段/computed方法参数与返回值/methods方法参数与参回值需有TS类型定义. data字段类型优先使用as关键字做类型定义\r\n* 采用`scss` 定义样式\r\n* 使用微盛组件库的组件前需要先导包并注册组件,从`@wshoto/pc-base-ui`中导入.\r\n* 如果页面包含WsTable表格组件,紧临表格上方的按钮需放入WsTable插槽中\r\n* 如果页面包含WsFilterGroup组件,组件已经内置了“查询”、“重置”按钮,不需要重复生成。"
},
{
"name": "lib-base",
"category": "全局组件",
"content": "# 基础库\r\n基础库也称为前端基础包,或lib-base, 属于微盛NPM私有包,包括三个功能\r\n- request 网络请求\r\n- serverDownload 通过`request`方式实现文件下载\r\n- baseInfo 基础信息,基础信息又分为\r\n * userInfo 用户信息\r\n * productInfo 产品信息\r\n * versionInfo 版本信息\r\n\r\n## 微盛网络请求规范\r\n\r\n仅支持调用微盛网络请求方法`request`发起网络请求,禁止调用axios、fetch发起请求。\r\n\r\n### `request`导入方式\r\n从NPM包`@wshoto/lib-base`中导入`request`方法,示例:\r\n```js\r\nimport { request } from '@wshoto/lib-base';\r\n```\r\n### `request`类型定义\r\n\r\n```ts\r\nexport type Method =\r\n | 'get' | 'GET'\r\n | 'delete' | 'DELETE'\r\n | 'head' | 'HEAD'\r\n | 'options' | 'OPTIONS'\r\n | 'post' | 'POST'\r\n | 'put' | 'PUT'\r\n | 'patch' | 'PATCH'\r\n | 'purge' | 'PURGE'\r\n | 'link' | 'LINK'\r\n | 'unlink' | 'UNLINK'\r\n\r\nexport type ResponseType =\r\n | 'arraybuffer'\r\n | 'blob'\r\n | 'document'\r\n | 'json'\r\n | 'text'\r\n | 'stream'\r\n\r\nexport interface AxiosRequestConfig {\r\n // 请求URL\r\n url?: string;\r\n\r\n // 请求METHOD\r\n method?: Method;\r\n\r\n //请求URL前缀\r\n baseURL?: string;\r\n\r\n //请求url query参数\r\n params?: any;\r\n\r\n //post请求体\r\n data?: any;\r\n\r\n //返回类型\r\n responseType?: ResponseType;\r\n}\r\n\r\nexport function request<T = any>(config:AxiosRequestConfig): Promise<T>;\r\n```\r\n\r\n### 请求示例\r\n\r\n列表接口返回参数类型定义\r\n```ts\r\nimport { request } from '@wshoto/lib-base';\r\n\r\ninterface ListResponse<T> {\r\n\t// 列表总数量\r\n\ttotal: number;\r\n\r\n\t// 当前页码\r\n\tcurrentIndex: number;\r\n\r\n\t// 每页显示条目数量\r\n\tpageSize: number;\r\n\r\n\t//列表数组\r\n\trecords: List<T>;\r\n}\r\n\r\ninterface ListItem {\r\n\t\"name\": \"婷美母婴体验群\",\r\n\t\"number\": 8,\r\n\t\"createTime\": \"2024-07-29 11:32:02\",\r\n}\r\n\r\n// 请求列表接口\r\nfunction getList() {\r\n\treturn request<ListResponse<ListItem>>({\r\n\t\turl: '/bff/customer/list',\r\n\t\tmethod: 'GET'\r\n\t});\r\n}\r\n```\r\n\r\n\r\n## serverDownload 文件下载\r\n\r\n以`request`请求形式实服务端文件下载, 和A链接下载方式的区别:request请求形式可在request header上添加TOKEN信息,以及可指定保存到本地的文件名。\r\n\r\n### 导入方式\r\n从NPM包`@wshoto/lib-base`中具名导入`serverDownload`方法,示例:\r\n```js\r\nimport { serverDownload } from '@wshoto/lib-base';\r\n```\r\n### `serverDownload`类型定义\r\n\r\n```ts\r\nimport type { AxiosRequestConfig } from \"axios\";\r\n\r\n/**\r\n * 以request方式实现下载\r\n * @param config request请求配置\r\n * @param fileName 保存到本地的文件名\r\n * @return Promise<boolean> 返回true时代表下载成功\r\n */\r\nexport function serverDownload(config: AxiosRequestConfig, fileName: string): Promise<boolean>;\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-button @click=\"download\">下载模板</ws-button>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n methods: {\r\n download() {\r\n return serverDownload({\r\n // 下载地址示例\r\n url: `/bff/authority/private/pc/template/download`,\r\n method: 'post',\r\n }, '模板.xlsx')\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n\r\n## BaseInfo 基础信息\r\n\r\n包含用户,租户,版本,产品等**基础**信息。\r\n\r\n### 导入方式\r\n`lib-base`中包含三大模块,用户信息-`userInfo`、产品信息-`productInfo`、版本信息-`versionInfo`\r\n```js\r\n\r\n<script>\r\n import {\r\n versionInfo,\r\n userInfo,\r\n productInfo\r\n } from \"@wshoto/lib-base\";\r\n</script>\r\n```\r\n\r\n### 常见用法\r\n#### 获取用户信息\r\n```ts\r\nimport { userInfo } from '@wshoto/lib-base';\r\n\r\nexport default {\r\n mounted() {\r\n const { userId, corpId } = userInfo;\r\n console.log(userId, corpId);\r\n }\r\n}\r\n```\r\n\r\n#### 获取当前安装的应用版本\r\n```ts\r\n\r\nimport { versionInfo } from '@wshoto/lib-base';\r\nexport default {\r\n mounted() {\r\n const { versionName } = versionInfo;\r\n console.log(versionName);\r\n }\r\n}\r\n```\r\n\r\n#### 判断当前用户是否有某个菜单的权限\r\n\r\n```ts\r\n\r\nimport { versionInfo } from '@wshoto/lib-base'; \r\nexport default {\r\n methods: {\r\n menuAuthHandler() {\r\n const { authMenuWhiteList } = versionInfo;\r\n const menuName = 'customer'; // 客户管理菜单标识\r\n return authMenuWhiteList.some(item => item.label === menuName);\r\n } \r\n }\r\n}\r\n```\r\n\r\n### 获取安装的产品名称信息\r\n```ts\r\nimport { productInfo } from '@wshoto/lib-base';\r\nexport default {\r\n computed: {\r\n productName() {\r\n return productInfo.productName;\r\n }\r\n }\r\n}\r\n```\r\n\r\n### 错误示例\r\n注意:`userInfo,versionInfo,productInfo` 中的数据需在运行时获取内部字段值,而不是在引用后立即通过字面量接收。推荐在`methods`,`computed`或者生命周期中通过解构赋值\r\n```ts\r\nimport { userInfo } from '@wshoto/lib-base';\r\nconst userId = userInfo.userId;\r\nexport default {\r\n mounted() {\r\n // 这种方式获取到的userId为空\r\n console.log(userId);\r\n }\r\n}\r\n```\r\n\r\n### userInfo 类型定义为UserInfo,详细字段如下\r\n```ts\r\n\r\ntype UserInfo = {\r\n userId?: string; // 用户id 仅企微场景存在\r\n corpId?: string; // 企业id 仅企微场景存在\r\n corpName?: string; // 企业名称 仅企微场景存在\r\n authRole?: 1 | 2 | 3 | null; // 1 超级管理员 2 分级管理员 3 普通成员 null 默认值 仅企微场景存在\r\n qrCode?: string; // 员工二维码 仅企微场景存在\r\n token?: string; // 接口调用凭证 仅企微场景存在\r\n unionId?: string; // 微信端开放平台unionId 仅微信场景存在\r\n openId?: string; // 微信端公众平台openId 仅微信场景存在\r\n nickName?: string; // 微信端用户昵称 仅微信场景存在\r\n headImgurl?: string; // 微信端用户头像 仅微信场景存在\r\n avatar: string; // 用户头像\r\n}\r\n```\r\n### versionInfo 类型定义为VersionInfo,详细字段如下\r\n注意:微信场景中没有versionInfo\r\n```ts\r\n\r\ntype VersionInfo = {\r\n isSaas: boolean; // 标品标识, 如果是saas/oem版本,返回true, 私有化版本返回false\r\n isOem: boolean; // 是否是OEM\r\n isOpenCustomFieldService: boolean; // 是否开通了自定义字段服务\r\n isCrmOpen: boolean; // crm功能设置的开关状态\r\n isMallOpen: boolean; // 商城功能设置的开关状态\r\n companyMode?: boolean; // 是否开始企业模式\r\n newCrmVersion?: boolean; // 是否是crm新版本\r\n coopModeType: '0' | '1' | '2' | '3' | '4'; // 协作模式 0(关闭协作模式) 1(多负责人非企业模式),2(多负责人企业模式),3(锁定负责人非企业模式),4(锁定负责人企业模式)\r\n functionModelSwitch: Array<string>; // 功能的开关状态集合\r\n /* 功能插件列表 */ \r\n plugins: Array<{\r\n pluginCode: string; // 插件类型\r\n pluginName: string; // 插件名称\r\n expiredState: boolean; // 过期状态\r\n maxUse: number; // 最大使用人数\r\n remainderDay: number; // 剩余天数\r\n endTime: string; // 插件到期时间\r\n gmtCreate: string // 插件创建时间\r\n }>;\r\n countdownDays: number; // 产品版本剩余时间\r\n expiredState: boolean; // 产品版本是否过期\r\n createTime: string; // 产品创建时间\r\n endTime: string; // 产品到期时间\r\n maxUse: number; // 产品最大使用人数\r\n numberOfUsers: number; // 产品已使用人数\r\n editionNo: '0' | '1' | '2' | '3'; // 产品版本标识 0体验版;1标准版;2高级版;3定制版\r\n versionName: 'platform' | 'crm' | 'shopassist' | 'finance' | 'chat'; // 应用版本类型\r\n loginMode: 0 | 1; // 登录模式 0先到先得 1管理员分配\r\n corpSubIndustry: string; // 企业所属行业。当企业未设置该属性时,值为空\r\n tenantFlag: number; // 租户标志位 需要使用与运算进行判断 具体可以问下居易,随风\r\n authMenuWhiteList: Array<{ label: string }>; // 权限菜单列表 label集合\r\n isSidebar: boolean; // 是否从侧边栏进入\r\n authBtnWhiteList: Array<string>; // 按钮权限列表\r\n versionConfig?: {\r\n // 海报类型,online - 稿定海报 offlin - 本地海报\r\n posterType?: 'online' | 'offline',\r\n // 是否开启员工辅助认证\r\n userCertification?: boolean,\r\n // 是否开启员工活码批量创建\r\n qrcodeBatchCreate?: boolean,\r\n // 是否开启员工活码批量编辑\r\n qrcodeBatchEdit?: boolean,\r\n // 是否开启活码短链\r\n qrcodeShortLink?: boolean,\r\n // 是否识客群码短链\r\n chatCodeShortLink?: boolean,\r\n // 门店活码是否支持配置识客群码\r\n storeChatCode?: boolean,\r\n // 是否支持门店自动创建活码\r\n storeQrcode?: boolean,\r\n // 企业群发朋友圈是否显示客户最近回复时间\r\n chatCodeRecentReplyTime?: boolean,\r\n // 是否开启销售统计\r\n salesStatistics?: boolean,\r\n // 是否开启汇报-数据简报\r\n reportDataBrief?: boolean,\r\n // 是否支持批量导入网页,\r\n batchImportWeb?: boolean,\r\n // 是否支持批量导入视频\r\n batchImportVideo?: boolean,\r\n // 是否支持批量导入小程序\r\n batchImportMiniProgram?: boolean,\r\n // 是否支持企业群发标签筛选\r\n corpMessageTagFilter?: boolean,\r\n // 是否开启人群包\r\n crowdPackage?: boolean,\r\n // 是否开启上下游标签 UP_DOWN_STREAM_TAG\r\n appShareTagEnable?: boolean,\r\n // 会话存档模式,专区模式 or 秘钥模式\r\n defaultSaMode?: 'dataZone' | 'secretKey',\r\n // 会话存档是否有历史数据\r\n saHistoryData?: boolean,\r\n // 临时变量,前端当前在使用的会话存档模式是否是专区模式 专区模式 or 秘钥模式\r\n currentSaMode?: 'dataZone' | 'secretKey',\r\n // 上下游标准化营销\r\n appShareMarketing?: boolean,\r\n // 上下游群发\r\n appShareMessageTask?: boolean,\r\n // 组合素材批量导入文本\r\n batchImportTextForPackageMaterial?: boolean,\r\n },\r\n installTime?: null | string; // 应用安装时间\r\n commonStatus: 0 | 1 | 2; // 通用功能状态 0-未开通 1-已开通 2-已过期\r\n sessionStatus: 0 | 1 | 2; // 会话存档功能状态 0-未开通 1-已开通 2-已过期\r\n suiteId: string; // 当前安装的三方应用id\r\n permanentAgentId: string // 当前安装三方应用的agentId\r\n}\r\n```\r\n### productInfo 类型定义为ProductInfo,详细字段如下\r\n```ts\r\n\r\ntype ProductInfo = Readonly<{\r\n WEB_TITLE: string; // 网页标签title\r\n FAVICON: string; // 网页标签icon\r\n PRODUCT_NAME: string; // 产品简称,例如:企微管家\r\n PRODUCT_FULL_NAME: string; // 产品全称,例如:微盛企微管家\r\n CREATIVE_CLOUD_APPID: string; // 创意云APPID\r\n CREATIVE_CLOUD_SECRET: string; // 创意云SECRET\r\n CREATIVE_CLOUD_COPY_RIGHT: string; // 创意云版权信息\r\n SYSTEM_LOGO: string; // 内页logo\r\n LOGIN_LOGO: string; // 登录页logo\r\n QR_CODE: string; // 客户二维码\r\n COPY_RIGHT: string; // 公司版权信息\r\n IS_OEM: 1 | 2; // 1 OEM 2 非OEM\r\n SERVICE_TEL: string; // 客服电话\r\n WECHAT_APP_ID: string; // 微信端appId\r\n FILE_STORAGE: 'cos' | 'oss' | 'server'; // 上传方式\r\n FAST_DFS_IMAGE_URL_PREFIX: string; // fastdfs域名前缀\r\n EXTRA: { // 额外的拓展字段\r\n MALL_MIN_VERSION: Record<string, any> // 商城小程序功能限定最低版本\r\n }\r\n}>\r\n```"
},
{
"name": "style",
"category": "PC端组件库",
"content": "## 样式规范\r\n\r\n统一样式以为用户提供一致的UI体验,以及便于主题定制。\r\n\r\n\r\n### 全局css变量\r\n网页中已经嵌入全局CSS变量,当网页中出现相同的颜色色值、文字大小、模块间距时,应该使用CSS变量,不要使用常量。\r\n\r\n```css\r\n:root {\r\n /** 主色调 color-primary **/\r\n /** 品牌色/主按钮色 **/\r\n --color-primary: #2b60dd;\r\n /** 主题蓝-深 主按钮点击色 **/\r\n --color-primary-active: #194dc6;\r\n /** 主题蓝-浅 主按钮未激活颜色 */\r\n --color-primary-inactive: #BFCFF4;\r\n /* 主题蓝-hover色 */\r\n --color-primary-hover: #4a77e2;\r\n /** 主题蓝-三级色 主要用于标签,提示反馈 */\r\n --color-primary-tip: #EAEFFC;\r\n /* 主题蓝-次级色 需要在主题色-三级色上叠加色块时使用/选中色 */\r\n --color-primary-tip-active: #E2EAFF;\r\n\r\n\r\n /** 文字色 color-text **/\r\n /** 一级文字色 **/\r\n --color-text-primary: #222;\r\n /** 二级文字色 **/\r\n --color-text-regular: #555;\r\n /** 三级文字色 **/\r\n --color-text-secondary: #999;\r\n /** 默认文案 提示文字色 **/\r\n --color-text-tip: #ccc;\r\n\r\n\r\n /** 背景色 color-background **/\r\n /* 页面背景色 */\r\n --color-background-base: #EDF2F9;\r\n /** 区块背景色、卡片色 **/\r\n --color-background-card: #F7F9FC;\r\n /** 分割线颜色 */\r\n --color-background-line: #E8E9ED;\r\n /** hover-蓝 */\r\n --color-background-hover-primary: #E5ECFF;\r\n /** hover-灰 */\r\n --color-background-hover-gray: #F1F2F4;\r\n\r\n\r\n /** 功能色 color-feat **/\r\n /** 强调橙 **/\r\n --color-feat-accent: #FF9B4E;\r\n /** 成功绿 **/\r\n --color-feat-success: #3DBE74;\r\n /** 错误红 **/\r\n --color-feat-error: #E84A5F;\r\n /** 辅助粉 **/\r\n --color-feat-pink: #EE79D7;\r\n /** 辅助紫 **/\r\n --color-feat-purple: #9B71FE;\r\n /** 错误红三级色 主要用于标签,提示反馈 **/\r\n --color-feat-error-tip: #FCECEF;\r\n /** 强调橙三级色 主要用于标签,提示反馈 **/\r\n --color-feat-accent-tip: #FFF5ED;\r\n /** 成功绿三级色 主要用于标签,提示反馈 **/\r\n --color-feat-success-tip: #EBF8F1;\r\n\r\n\r\n /* 禁用色 color-disabled */\r\n /** 文案禁用色 **/\r\n --color-disabled-text: #D5D5D5;\r\n /** 输入框置灰色 **/\r\n --color-disabled-input: #F7F7F7;\r\n /* 图标禁用色-蓝 */\r\n --color-disabled-icon-primary: #EAEDF4;\r\n /* 图标禁用色-灰 */\r\n --color-disabled-icon-gray: #ECECEC;\r\n\r\n\r\n /** 关联产品品牌色 color-brand **/\r\n /** 企业微信品牌色 **/\r\n --color-brand-wxwork: #3975c6;\r\n /** 微信品牌色 **/\r\n --color-brand-wxchat: #68c452;\r\n\r\n\r\n /* 字体大小 font-size, 以`--font-size-`开头的尺寸仅适用于设置字体大小`font-size`样式 */\r\n /** 适用一级标题 20px **/\r\n --font-size-title: 20px;\r\n /** 适用区块标题 18px **/\r\n --font-size-block: 18px;\r\n /** 适用按钮文案 16px **/\r\n --font-size-btn: 16px;\r\n /** 适用表单标题、提示文案、默认大小 14px **/\r\n --font-size-base: 14px;\r\n /** 适用摘要、次要信息小号 12px **/\r\n --font-size-desc: 12px;\r\n\r\n /** width、margin、padding **/\r\n /** 一级页面底部padding **/\r\n --page-padding: 40px;\r\n /** 模块之间的间距 **/\r\n --module-margin: 24px;\r\n /** 模块内边距 **/\r\n --module-padding: 16px;\r\n}\r\n\r\n```\r\n\r\n\r\n### 全局class样式\r\n网页中已经内置了以下全局class样式,可直接引用,不要在组件样式定义中重复定义\r\n```css\r\n.ws-page-auto {\r\n padding: 32px 40px 0 40px;\r\n background-color: #fff;\r\n}\r\n.ws-page-normal {\r\n width: 1200px;\r\n background-color: #fff;\r\n margin: 0 auto;\r\n}\r\n.ws-content-center {\r\n margin-left: auto;\r\n margin-right: auto;\r\n padding: 24px 0;\r\n box-sizing: content-box;\r\n}\r\n.ws-content {\r\n padding: 24px;\r\n box-sizing: content-box;\r\n}\r\n.ws-spacing {\r\n margin: 0;\r\n margin-left: 2px;\r\n margin-right: 2px;\r\n height: 1px;\r\n background-color: #e8e9ed;\r\n}\r\n```\r\n\r\n\r\n### 模块首页\r\n\r\n页面分为两类:模块首页和模块内页。模块首页是指左侧包含导航菜单、右侧内容区域宽度自适应屏幕的页面。模块首页也称为“一级页”。\r\n模块首页顶层元素需包含class类名`ws-page-auto`。模块区域间如果需要添加水平分隔线,可使用class`ws-spacing`, 通常用于模块介绍组件和表格筛选容器组件之间。模块首页示例:\r\n:::demo\r\n```html\r\n<template>\r\n <div class=\"ws-page-auto\">\r\n <!-- 模块介绍 -->\r\n <ws-page-guide />\r\n <!-- 水平分隔线 -->\r\n <div class=\"ws-spacing\" />\r\n <ws-filter-group>\r\n <!-- 此处省略了筛选项 -->\r\n </ws-filter-group>\r\n </div>\r\n</template>\r\n```\r\n:::\r\n\r\n### 模块内页\r\n模块内页是指左侧没有导航菜单、顶部为`BreadCrumb`面包屑组件、内容宽度固定的页面。模块内页也称为“内页”。\r\n内页顶层元素需包含class类名`ws-page-normal`。此样式可实现在父元素中水平居中。 \r\n内页中的内容区域如果需要水平居中,需配置类名`ws-content-center`,手动设置宽度,模块内页内容居中对齐示例:\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <div class='ws-page-normal'>\r\n <bread-crumb :show-back='true' pageTitle='页面标题' />\r\n <div class='ws-content-center' style=\"width: 1040px; background-color: #999\">\r\n 内容区域位置水平居中\r\n </div>\r\n </div>\r\n</template>\r\n```\r\n:::\r\n\r\n内页中的内容区域如果需要左对齐,需配置类名`ws-content`,此时并不需要手动设置宽度,宽度根据内容确定,模块内页内容左对齐示例:\r\n:::demo\r\n```html\r\n<template>\r\n <div class='ws-page-normal intercept-rule'>\r\n <bread-crumb :show-back='true' pageTitle='页面标题' />\r\n <div class='ws-content'>\r\n 内容区域位置左对齐\r\n </div>\r\n </div>\r\n</template>\r\n```\r\n:::\r\n\r\n\r\n### 模块分隔符"
},
{
"name": "ws-button",
"category": "PC端组件库",
"content": "## WsButton 按钮\r\n业务中常用的操作按钮。 按钮样式符合微盛UI规范,页面应该仅使用WsButton,不要使用ElButton\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsButton`组件, 并在页面中注册\r\n\r\n```vue\r\n\r\n<script>\r\n import {WsButton} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsButton\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n\r\n### 基础用法\r\n\r\n基础的按钮用法。\r\n可配置配置`type`控制按钮的显示样式,如果未配置,默认值为`default`\r\n:::demo\r\n```html\r\n <el-row style=\"display: flex; gap: 12px;\">\r\n <ws-button>默认按钮</ws-button>\r\n <ws-button type='primary'>主要按钮</ws-button>\r\n <ws-button type='info'>信息按钮</ws-button>\r\n <ws-button type='border'>描边按钮</ws-button>\r\n <ws-button type='borderBG' circle>圆角按钮</ws-button>\r\n </el-row>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 禁用状态\r\n\r\n按钮不可用状态。\r\n\r\n:::demo\r\n```html\r\n <el-row style=\"display: flex; gap: 12px;\">\r\n <ws-button disabled>默认按钮</ws-button>\r\n <ws-button type='primary' disabled>主要按钮</ws-button>\r\n <ws-button type='info' disabled>信息按钮</ws-button>\r\n <ws-button type='border' disabled>描边按钮</ws-button>\r\n <ws-button type='borderBG' disabled circle>圆角按钮</ws-button>\r\n </el-row>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 文字按钮\r\n\r\n没有边框和背景色的按钮。\r\n\r\n:::demo\r\n```html\r\n <el-row style=\"display: flex; gap: 12px;\">\r\n <ws-button type='text'>文字按钮</ws-button>\r\n <ws-button type='text' disabled>文字按钮禁止状态</ws-button>\r\n </el-row>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 自定义内容按钮\r\n\r\n按钮内容可通过`default`插槽自定义配置\r\n\r\n:::demo\r\n\r\n```html\r\n <el-row style=\"display: flex; align-items: center; gap: 12px;\">\r\n <ws-button type='primary'>\r\n <i style=\"margin-right: 2px;\" class=\"el-icon-plus\"></i>\r\n 主要按钮带左icon\r\n </ws-button>\r\n \r\n <ws-button type='text'>\r\n 文字按钮带右icon\r\n <i style=\"margin-left: 2px;\" class=\"el-icon-plus\"></i>\r\n </ws-button>\r\n\r\n <ws-button type='text' disabled>\r\n 文字按钮带右icon禁止状态\r\n <i style=\"margin-left: 2px;\" class=\"el-icon-plus\"></i>\r\n </ws-button>\r\n </el-row>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 加载中\r\n\r\n点击按钮后进行数据加载操作,在按钮上显示加载状态。\r\n\r\n:::demo 要设置为 loading 状态,只要设置`loading`属性为`true`即可。\r\n\r\n```html\r\n<ws-button type=\"primary\" :loading=\"true\">加载中</ws-button>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 不同尺寸\r\n\r\nButton 组件提供除了两种尺寸`medium`、`small`,通过设置`size`属性来配置它们,可以在不同场景下选择合适的按钮尺寸。如不配置`size`,默认尺寸为`small`。\r\n\r\n\r\n:::demo\r\n\r\n```html\r\n<el-row>\r\n <ws-button>默认按钮</ws-button>\r\n <ws-button size=\"small\">小型按钮</ws-button>\r\n <ws-button size=\"medium\">中型按钮</ws-button>\r\n</el-row>\r\n<el-row style=\"margin-top: 10px\">\r\n <ws-button circle>默认按钮</ws-button>\r\n <ws-button size=\"small\" circle>小型按钮</ws-button>\r\n <ws-button size=\"medium\" circle>中型按钮</ws-button>\r\n</el-row>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------|-----------|---------|-------------------------------------|---------|\r\n| type | 按钮主题类型 | string | default/primary/ border/borderBG/info/text | default |\r\n| size | 按钮尺寸 | string | medium/small | small |\r\n| disabled | 按钮是否禁用 | boolean | — | true |\r\n| loading | 是否加载中状态 | boolean | — | true |\r\n| circle | 是否为矩形圆角按钮 | boolean | — | false |\r\n\r\n#### Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n|-------|---------| --------- |\r\n| click | 点击事件 | - |\r\n\r\n### Slot\r\n| 参数 | 说明 |\r\n|---------|--------------|\r\n| default | 提供按钮文本及图标的插槽 |"
},
{
"name": "ws-filter-group",
"category": "PC端组件库",
"content": "## WsFilterGroup - 表格数据筛选组件\r\n\r\n和`WsTable`表格组件配合使用,可为表格组件提供数据筛选条件。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsFilterGroup`、`WsFilterItem`组件, 并在页面中注册\r\n\r\n```vue\r\n\r\n<script>\r\n import {WsFilterGroup, WsFilterItem} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsFilterGroup,\r\n WsFilterItem\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n`WsFilterGroup`做为筛选容器,可嵌套`WsFilterItem`筛选项。 默认包括“查询”、“重置”按钮。当`WsFilterItem`条目数量超过一屏时,会在右侧自动显示`展示`、`收起`开关。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group @search=\"getList\" @reset=\"reset\">\r\n <ws-filter-item label=\"活码名称\">\r\n <el-input placeholder=\"请输入活码名称\" clearable v-model=\"searchOptions.qrCode\"/>\r\n </ws-filter-item>\r\n <ws-filter-item label=\"创建人\">\r\n <WeShineFilterDep/>\r\n </ws-filter-item>\r\n <ws-filter-item label=\"筛选项标题\">\r\n <el-select placeholder=\"请选择\" clearable v-model=\"searchOptions.selectValue\">\r\n <el-option v-for=\"item in options\" :key=\"item.value\" :label=\"item.label\" :value=\"item.value\"></el-option>\r\n </el-select>\r\n </ws-filter-item>\r\n <ws-filter-item label=\"跨两列的筛选项\">\r\n <WsDatePicker v-model=\"searchOptions.searchTime\"/>\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n searchOptions: {\r\n qrCode: '',\r\n selectValue: '',\r\n searchTime: []\r\n },\r\n options: [\r\n {\r\n label: '选项1',\r\n value: 1\r\n },\r\n {\r\n label: '选项2',\r\n value: 2\r\n }\r\n ],\r\n pageIndex: 1\r\n };\r\n },\r\n methods: {\r\n search() {\r\n // 点击查询按钮时,需配置当前页码为1,并发起网络请求\r\n this.pageIndex = 1;\r\n this.getList();\r\n },\r\n getList() {\r\n // 根据筛选条件,请求接口\r\n },\r\n reset() {\r\n // 重置筛选项\r\n this.searchOptions.qrCode ='';\r\n this.searchOptions.selectValue = '';\r\n this.searchOptions.searchTime = [];\r\n // 重置后需要发起新的查询\r\n this.search();\r\n }\r\n } \r\n };\r\n</script>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n::: tip\r\n* 筛选项均应支持清空操作;内容清空后,直接清除该筛选条件;比如筛选项中的`el-input`、`el-select`均应配置`clearable`属性支持清空。 特例:下拉菜单组件(比如`el-select`),如包括【全部】选择项时,不应该支持清空操作;\r\n* 点击`查询`按钮后,需设置表格当前页面为1(第一页),并发起查询请求。 点击`重置`按钮后,需重置筛选条件为默认状态。并手动触发查询操作\r\n:::\r\n\r\n### 隐藏操作按钮\r\nWsFilterGroup组件内置`查询`、`重置`、及`展开/收起`按钮, 不需要再次添加`查询`、`重置`按钮。。 当筛选项`WsFilterItem`数量少于3个时,可通过配置参数`show-operation`为`false`,实现隐藏`查询`等操作按钮。\r\n此时需要监听筛选条件变更并主动触发筛选。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label=\"活码名称\">\r\n <el-input placeholder=\"请输入\" v-model=\"searchOptions.qrCode\" clearable @input=\"search\" @clear=\"search\" />\r\n </ws-filter-item>\r\n <ws-filter-item label=\"条件名称\">\r\n <el-input placeholder=\"请输入\" v-model=\"searchOptions.condition\" clearable @input=\"search\" @clear=\"search\" />\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n searchOptions: {\r\n qrCode: '',\r\n condition: ''\r\n },\r\n pageIndex: 1\r\n };\r\n },\r\n methods: {\r\n search() {\r\n // 点击查询按钮时,需配置当前页码为1,并发起网络请求\r\n this.pageIndex = 1;\r\n this.getList();\r\n },\r\n getList() {\r\n // 根据筛选条件,请求接口\r\n }\r\n } \r\n };\r\n</script>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------------|--------------------------|---------|-----|-------|\r\n| search-loading | 查询按钮 loading 状态 | boolean | — | false |\r\n| search-disabled | 查询按钮 disabled 状态 | boolean | — | false |\r\n| show-reset | 是否显示重置按钮 | boolean | — | false |\r\n| reset-loading | 重置按钮 loading 状态 | boolean | — | false |\r\n| reset-disabled | 查询按钮 disabled 状态 | boolean | — | false |\r\n| show-operation | 是否显示`查询`、`重置`、及`展开/收起`按钮 | boolean | — | true |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n|--------|-----------|------|\r\n| search | 点击查询按钮时触发 | - |\r\n| reset | 点击重置按钮时触发 | - |\r\n\r\n### WsFilterGroup Slots\r\n\r\n| 插槽名称 | 说明 |\r\n|-----------|---------------------------------------------|\r\n| - | 内容区域,仅支持`ws-filter-item`组件 |\r\n\r\n### WsFilterItem Slots\r\n\r\n| 插槽名称 | 说明 |\r\n|-------|-----------|\r\n| - | 用于放置各类筛选组件 |"
},
{
"name": "ws-page-guide",
"category": "PC端组件库",
"content": "## WsPageGuide - 模块介绍组件\r\n模块介绍组件通常位于模块列表页面顶部,包括模块标题、模块简介、帮助文档链接、模块简介、按钮区域、操作区域\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsPageGuide`组件, 并在组件中注册\r\n\r\n```vue\r\n\r\n<script>\r\n import {WsPageGuide} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsPageGuide\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n`title`属性为\"模块标题\"; `intro`属性为\"模块简介\"; `link`属性为帮助文档URL地址,当配置`link`属性后,会在标题的右方展示“功能介绍”链接\r\n\r\n:::demo\r\n```html\r\n<ws-page-guide\r\n title=\"敏感内容拦截\"\r\n link=\"https://help.wshoto.com/index.html\"\r\n intro=\"配置拦截规则后,当员工发送给客户的消息包含敏感内容时,将予以提示或禁止发送\">\r\n</ws-page-guide>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 模块介绍\r\n如果模块介绍为纯文本内容,优先使用`intro`属性;否则,可使用`intro`插槽。当模块介绍包括富文本内容时,如链接、按钮,此时必须使用`intro`插槽。`intro`插槽显示在组件的底部。\r\n\r\n:::demo\r\n```html\r\n<ws-page-guide\r\n title=\"敏感内容拦截\"\r\n link=\"https://help.wshoto.com/index.html\">\r\n <template v-slot:intro>\r\n <div><span>针对私域导购、客服场景,只需导入现有知识文档,即可通过大模型输出结果,运营成本降低99.9%。</span><ws-button type=\"text\">使用须知</ws-button></div>\r\n </template> \r\n</ws-page-guide>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 快捷入口\r\n标题右侧的快捷入口 文本按钮可通过`showSideLink`属性配置,当为`true`时显示按钮,默认值为false, 默认不显示\r\n:::demo\r\n```html\r\n<ws-page-guide\r\n title=\"敏感内容拦截\"\r\n link=\"https://help.wshoto.com/index.html#/hhcd_mgnrlj/\"\r\n show-side-link\r\n>\r\n <template v-slot:intro>\r\n <div><span>针对私域导购、客服场景,只需导入现有知识文档,即可通过大模型输出结果,运营成本降低99.9%。</span><ws-button type=\"text\">使用须知</ws-button></div>\r\n </template> \r\n</ws-page-guide>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 按钮区域\r\n`btns`按钮插槽位于组件介绍的下方。可在此添加快捷按钮,点击时跳转到数据创建页等。\r\n按钮区域可使用`ws-button`或`el-button`添加按钮。\r\n:::demo\r\n```html\r\n<ws-page-guide\r\n title=\"敏感内容拦截\"\r\n link=\"https://help.wshoto.com/index.html#/hhcd_mgnrlj/\"\r\n intro=\"配置拦截规则后,当员工发送给客户的消息包含敏感内容时,将予以提示或禁止发送\"\r\n>\r\n <template v-slot:btns>\r\n <el-button type='primary' size='medium'>\r\n 新建拦截规则\r\n </el-button>\r\n <el-button size='medium'>导入拦截规则</el-button>\r\n </template>\r\n</ws-page-guide>\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 操作区域\r\n`operation`操作插槽位于组件右方区域, 标题的右侧\r\n\r\n:::demo\r\n```html\r\n<ws-page-guide\r\n title=\"敏感内容拦截\"\r\n link=\"https://help.wshoto.com/index.html#/hhcd_mgnrlj/\"\r\n intro=\"配置拦截规则后,当员工发送给客户的消息包含敏感内容时,将予以提示或禁止发送\"\r\n>\r\n <template v-slot:btns>\r\n <el-button type='primary' size='medium'>\r\n 新建拦截规则\r\n </el-button>\r\n <el-button size='medium'>导入拦截规则</el-button>\r\n </template>\r\n <template v-slot:operation>\r\n <div>\r\n <p>拦截记录</p>\r\n </div>\r\n </template>\r\n</ws-page-guide>\r\n\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|--------------|--------------------------|---------|--------------|-------|\r\n| title | 页面标题文案,不传则不显示标题头部 | string | - | ’‘ |\r\n| link | 功能介绍按钮的资源链接,不传则不显示功能介绍按钮 | string | - | ’‘ |\r\n| intro | 页面功能简介文案 | string | - | ’‘ |\r\n| showSideLink | 显示\"快捷入口\"链接 | boolean | true\\| false | false |\r\n\r\n### Slots\r\n\r\n| 参数 | 说明 |\r\n| --------- | --------------------------- |\r\n| title | 提供替换标题的插槽 |\r\n| btns | 提供替换按钮操作的插槽 |\r\n| intro | 提供替换页面介绍信息的插槽 |\r\n| operation | 提供替换标题右侧操作的插槽 |\r\n| tips | 用于放置 tipsBar 组件的插槽 |\r\n\r\n### Events\r\n无\r\n\r\n### 开发规范\r\n- 位于WsPageGuide下方且紧临WsPageGuide组件的按钮需要放入WsPageGuide组件`btns`插槽中"
},
{
"name": "ws-filter-dep",
"category": "PC端组件库",
"content": "## WeShineFilterDep - 组织架构筛选器\r\n\r\n用于筛选员工、部门的筛选器,内部集成了 WsFilterTag 和 WeShineDepSelectDialog。也称为人员筛选器\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineFilterDep`组件, 并在页面中注册\r\n\r\n```vue\r\n\r\n<script>\r\n import { WeShineFilterDep } from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineFilterDep\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label=\"创建人\">\r\n <we-shine-filter-dep\r\n v-model=\"selectedCreators\"\r\n dialog-title=\"选择创建人\"\r\n multiple\r\n priority\r\n shape=\"filter\"\r\n @input=\"search\"\r\n />\r\n </ws-filter-item>\r\n </ws-filter-group> \r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n selectedCreators: [],\r\n pageInfo: {\r\n pageSize: 10,\r\n pageIndex: 1\r\n },\r\n };\r\n },\r\n methods: {\r\n search(data) {\r\n // data类型为 Array<DataNode>\r\n this.pageInfo.pageIndex = 1;\r\n this.getList();\r\n }\r\n getList() {\r\n //todo 根据筛选条件请求列表接口\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|-------------------------------------------|--------|\r\n| v-model | 选择的数据 | Array<NodeUser \\| NodeDep> | - | - |\r\n| placeholder | 无选择数据时 WeShineFilterTagGroup 的文案 | String | - | 请选择 |\r\n| allowClear | 是否展示标签组清除按钮 | Boolean | true |\r\n| dialog-title | 弹窗title | String | - | 请选择添加人 |\r\n| confirmText | 弹窗确认按钮文案 | String | - | 确认 |\r\n| cancelText | 弹窗取消按钮文案 | String | - | 取消 |\r\n| priority | 数据源是否带权限 | Boolean | - | false |\r\n| multiple | 是否多选 | Boolean | - | false |\r\n| choiceType | 选择节点类型, 可选类型: user:仅可选员工; department:仅可选部门; both:可选员工及部门 | String | user \\| department \\| both | both |\r\n| expand-on-click-node | 点击部门节点是否展开 | Boolean | - | false |\r\n| show-checked-state | 是否展示节点已选状态 | Boolean | - | true |\r\n| readonly | 节点是否只读 | Boolean | - | false |\r\n| show-select-all | 搜索全选 | Boolean | - | false |\r\n| disable-list | 禁选列表 | Array<NodeUser \\| NodeDep> | | false |\r\n| before-checked | 勾选前钩子 | (data: DataNode) => Promise\\<boolean\\> \\| boolean | | - |\r\n| sourceType | 数据类型类型,可选 priority \\| none-priority \\| custom | string | priority \\| none-priority \\| custom | - |\r\n| load | 自定义数据源,当 sourceType 为 custom 时,需要提供。 | (type: LOAD_TYPES, data?: TreeNode, searchVal?: string) => Promise<Array<DataNode>> | - | - |\r\n| shape | 不同场景下展示形态: select - 创建任务时选择员工或部门,禁止选择成员状态是已禁用,退出企业或已离职的节点,禁止选择账号状态是未开通或已过期的节点;filter - 列表筛选条件场景,列表筛选时选择员工/部门,支持选择“已禁用,退出企业,未开通,已过期”节点,若存在已离职员工吗,则展示”已离职员工“分组;filter-none-auth-node - 列表筛选条件场景(未开通/已过期成员置灰不能选)禁止账号状态为未开通和已过期,目前主要应用于客户/客户群列表数据和统计的筛选场景; | string | select \\| filter \\| filter-none-auth-node | select |\r\n| limit | 筛选场景选人限制,超过500提示,不允许超过1000 | boolean | - | false |\r\n| beforeConfirm | 确定前钩子,根据返回值决定是否关闭弹窗,true-关闭,false-不关闭 | (data: DataNode) => Promise<boolean> | boolean | - | - |\r\n| tagSelect | 是否支持选择员工标签 | boolean | false |\r\n| defaultUserTagSelected | 默认选中的员工标签,需和tagSelect配合使用 | Array\\<{tagId: string, tagName: string}\\> | [] |\r\n| userTagLimit | 员工标签最大的选择数量 | number | 5 |\r\n\r\n\r\n### 类型定义\r\n\r\n```ts\r\n\r\n// 加载类型\r\nenum LOAD_TYPES {\r\n ROOT = 'ROOT', // 初始化\r\n CHILDREN = 'CHILDREN', // 加载下级节点\r\n SEARCH = 'SEARCH' // 搜索节点\r\n}\r\n\r\n// 标签配置\r\ntype TagConfig = {\r\n label: string; // 标签的文本\r\n tips?: string; // hover标签时的提示\r\n button?: string; // 结尾按钮的问题\r\n routerPath?: string; // 点击按钮跳转的路由\r\n message?: string; // 点击按钮弹出的提示\r\n}\r\n\r\n// 节点的标签类型,目前仅一种\r\ntype TagType = 'normal';\r\n\r\n// 节点的标签\r\ntype TagNode = {\r\n text: string, // 标签的文字\r\n type?: TagType, // 节点的标签类型,目前仅一种\r\n popover?: boolean, // hover标签是否需要展示文本\r\n popoverTips?: string, // hover标签时展示的文案\r\n handlerType?: number, // 交互类型,跳转路由或展示提示\r\n} & Pick<TagConfig, 'button' | 'routerPath' | 'message'>\r\n\r\ntype NodeParent = {\r\n id?: number; // 节点的id\r\n count?: number | null, // 如果是部门节点,部门下有多少人\r\n name?: string; // 节点名称,showOriginName为true时,可使用name渲染名称\r\n leaf?: boolean; // 是否是叶子节点\r\n parentId?: number; // 节点的父部门id\r\n showOriginName?: boolean; // 组织架构树节点名称默认使用open-data-box渲染,如果传递showOriginName,可以搭配name直接使用html原生标签渲染\r\n customTags?: TagNode[]; // 节点右侧的标签集合\r\n hiddenTips?: boolean; // 是否隐藏节点展示主部门信息的icon\r\n nodeCustomIcon?: string; // 节点自定义图标 示例 require('./xx.svg')\r\n status?: 0 | 1 | 2 | 4 | 5 | 99; // 员工节点状态:0-无效,不在可见范围内,1-已激活,2-已禁用,4-未激活,5-退出企业,99-已离职\r\n accountStatus?: 1 | 2 | 3; // 账号状态:1-未开通, 2-已开通, 3-已过期\r\n orgPathIds?: Array<number>; // 节点的父部门id集合\r\n}\r\n\r\n// 员工节点类型\r\ntype NodeUser = {\r\n isUser: true; // 是员工节点\r\n userId: string; // 员工id\r\n} & NodeParent;\r\n\r\n// 部门节点类型\r\ntype NodeDep = {\r\n isUser: false; // 非员工节点,即部门节点\r\n deptId: number; // 部门id\r\n depId?: number; // 部门id,冗余字段\r\n children?: Array<NodeUser | NodeDep>;\r\n} & NodeParent\r\n\r\n// 节点类型\r\ntype DataNode = NodeUser | NodeDep;\r\n\r\n// tree节点内部结构\r\ntype TreeNode = {\r\n checked: boolean; // 是否是勾选状态\r\n childNodes: Array<TreeNode>; // 子节点\r\n data: DataNode; // 节点数据\r\n expanded: boolean; // 是否展开\r\n id: number; // 节点id\r\n indeterminate: boolean;\r\n isCurrent: boolean;\r\n isLeaf: boolean; // 叶子节点\r\n level: number; // 节点层级\r\n loaded: boolean; // 节点是否已加载\r\n loading: boolean; // loading状态\r\n parent: TreeNode; // 父节点\r\n text: string;\r\n visible: boolean;\r\n}\r\n\r\n```\r\n\r\n\r\n### Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n|--------------|--------------|--------------------------------|\r\n| check-change | 节点状态发生改变时触发 | data: DataNode, state: boolean |\r\n| node-click | 节点被点击时触发 | data: DataNode |\r\n| open | 打开弹窗前触发 | - |\r\n| close | 关闭弹窗前触发 | - |\r\n| clear | 点击标签组清除按钮时触发 | - |\r\n| input | 确认选中事件 | data: Array<DataNode> |"
},
{
"name": "ws-export-button",
"category": "PC端组件库",
"content": "## WeShineExportButton - 异步导出按钮组件\r\n\r\n异步导出按钮组件可实现点击时异步导出表格列表数据。此组件通常需配合`WsTable`表格组件使用,置于`WsTable`的`operation`插槽中。\r\n异步导出流程分三步:创建导出任务、轮询导出进度、下载。\r\n\r\n- 1、创建导出任务。通过配置组件属性`create-fn`函数提供“创建导出任务”接口请求配置。创建导出任务接口返回导出任务id(字段名`downId`); 如果接口返回字段`downResult`为true, 则会跳到第三步:获取下载地址。\r\n```ts\r\n// 创建导出任务接口返回内容格式\r\ninterface CreateTaskResponse {\r\n downId: string; // 导出任务id\r\n downResult?: boolean; // 是否导出完成。\r\n}\r\n```\r\n- 2、轮询导出进度。通过配置组件属性`get-progress-fn`函数提供“查询导出进度”接口请求配置。此函数的参数类型为`GetProgressRequest`, 其中的down_id值为导出任务id, 来源于“创建导出任务接口”返回体`CreateTaskResponse`中的`downId`字段。接口中返回类型为`GetProgressResponse`。 当导出完成时,会显示“下载”链接。\r\n```ts\r\ninterface GetProgressRequest {\r\n down_id: string; // 导出任务id\r\n}\r\n\r\n// 查询导出进度接口返回内容格式\r\ninterface GetProgressResponse {\r\n downPercent: number; // 导出百分比,示例:100\r\n downResult: boolean; // 标识导出已完成,示例:true\r\n}\r\n```\r\n- 3、下载。通过配置组件属性`get-url-fn`函数提供“获取导出文件下载地址”接口请求配置。 下载分为两种方式,应用内下载与企微转义下载。\r\n * 应用内下载模式:调用聚合层接口实现下载,可以携带用户身份。“获取导出文件下载地址”接口以流式返回下载内容。 可通过配置`downloadMethod`属性为`blob`实现应用内下载。此模式下需配置`fileName`属性为下载的文件名名称,不包含文件后缀,示例:\"活码列表\"\r\n * 企微转义下载模式:如下载内容包含三方应用企微转义内容,如员工/部门信息,需配置为此模式。获取导出文件下载地址接口返回数据类型定义类型可参考`DownloadLinkResponse`。如返回导出文件数量大于1,点击下载时会触发批量下载弹窗。可通过配置`downloadMethod`属性为`href`实现企微转义下载。\r\n```ts\r\ninterface DownloadLinkUrl {\r\n name: string; // 导出文件名称,示例: \"客户列表导出-去重_001_000.xlsx\"\r\n url: string; // 导出文件下载地址,示例:\"https://open.work.weixin.qq.com/wwopen/openData/getTranslateContactOpenData?dataid=oZ-N1NhowjJElv5k2qI16XsOelikc-4ntLDTBkzryQw\"\r\n}\r\n\r\n// 获取导出文件下载地址接口返回内容格式,企微转义下载模式;类型可以为数组类型或由','拼接下载地址形成的字符串\r\ntype DownloadLinkResponse = Array<DownloadLinkUrl> | string;\r\n```\r\n\r\n### 功能\r\n- 异步导出\r\n- 导出进度/完成状态本地缓存,页面刷新或关闭后可恢复状态\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineExportButton`组件, 并在页面中注册\r\n\r\n```html\r\n<script>\r\n import { WeShineExportButton } from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineExportButton\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基本使用\r\n\r\n\r\n:::demo \r\n```html\r\n<template>\r\n <el-row>\r\n <!-- 以企微转义下载模式导出 -->\r\n <we-shine-export-button\r\n btnText='导出列表'\r\n module-id='exportQrcode'\r\n module-file-name='导出文件'\r\n download-method='link'\r\n :create-fn='exportCreate'\r\n :get-progress-fn='exportGetProgress'\r\n :get-url-fn='exportGetDownloadUrl'\r\n />\r\n \r\n <!-- 以应用内下载模式导出 -->\r\n <we-shine-export-button\r\n btnText='应用内导出'\r\n module-id='exportQrcodeBlob'\r\n module-file-name='导出文件'\r\n download-method='blob'\r\n :create-fn='exportCreate'\r\n :get-progress-fn='exportGetProgress'\r\n :get-url-fn='exportDownload'\r\n />\r\n </el-row>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n filterOptions: {\r\n // 表格筛选项 \r\n }\r\n }\r\n },\r\n mounted() {\r\n this.getList();\r\n },\r\n methods: {\r\n // 创建导出任务接口请求配置\r\n exportCreate() {\r\n return {\r\n url: '/bff/customer/private/pc/export/exportByCreate',\r\n method: 'post',\r\n data: this.filterOptions\r\n };\r\n },\r\n // 查询任务导出进度接口请求配置\r\n exportGetProgress(data) {\r\n return {\r\n url: '/bff/customer/private/pc/export/getExportById',\r\n method: 'post',\r\n data: {\r\n downId: data['down_id']\r\n }\r\n };\r\n },\r\n // 获取导出文件下载地址,以企微转义模式实现下载\r\n exportGetDownloadUrl(data) {\r\n return {\r\n url: '/bff/customer/private/pc/export/download',\r\n method: 'post',\r\n data: {\r\n downId: data['down_id']\r\n }\r\n };\r\n },\r\n // 下载文件\r\n exportDownload(data) {\r\n return {\r\n url: '/bff/customer/private/pc/export/download-file',\r\n method: 'post',\r\n data: {\r\n downId: data['down_id']\r\n }\r\n };\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 是否必传 | 可选值 | 默认值 |\r\n| --------- |--------------------------------------------------------------|--------------------------------------------------------------------------| ------ | ------ |-----------------------|\r\n| moduleId | 模块id, 必须全局惟一 | string | 是 | - | - |\r\n| createFn | 创建导出任务(定义的 API 请求) | (data) => AxiosRequestConfig | 是 | - | - |\r\n| getProgressFn | 查询导出进度 (定义的 API 请求) | (params: {down_id: string}) => AxiosRequestConfig | 是 | - | - |\r\n| getUrlFn | 查询导出资源url地址 (定义的 API 请求) | (params: {down_id: string}) => AxiosRequestConfig | 是 | - | - |\r\n| moduleFileName | 下载文件名称, 当为应用内下载时,文件名不应该包含后缀,示例:\"导出列表\" | string | 是 | - | '未命名文件' |\r\n| downloadMethod | 下载方式:href\\|blob\\|false; 企微转义下载:href; 应用内下载:blob; 自定义导出:false | string\\|boolean | 否 | href\\|blob\\|false | href |\r\n| beforeDownLoad | 下载文件前置钩子 | () => Promise\\<boolean\\> \\| boolean | 否 | - | - |\r\n| beforeExport | 点击导出按钮前置钩子 | () => Promise\\<boolean\\> \\| boolean | 否 | - | - |\r\n| disabled | 导致按钮禁止状态 | boolean | 否 | - | false |\r\n| btnText | 按钮文字 | string | 否 | - | 导出列表 |\r\n| btnClass | 按钮class | string | 否 | - | - |\r\n| btnVisible | 是否展示按钮 | boolean | 否 | - | true |\r\n| beforeDownLoadClick | 下载按钮点击前的钩子 | () => Promise\\<boolean\\> \\| boolean | 否 | - | - |\r\n| timeOut | 查询导出进度轮询超时配置,单位毫秒 (自v3.0.0版本) | number | 否 | - | 30 x 60 x 1000 (30分钟) |"
},
{
"name": "ws-table",
"category": "PC端组件库",
"content": "## WsTable - 表格组件\r\n\r\n\r\n基于 [`ElTable`](/#/zh-CN/component/table)、[`ElPagination`](/#/zh-CN/component/pagination) 组件封装, 自带分页器。\r\n\r\n- 表格组件右上方为“统计区域”,可显示表格总行数,如“共XX条数据”。紧临统计区域的左方为`header`插槽。\r\n- 表格组件右下方为分页器区域,组件内部集成了表格分页器`el-pagination`组件;\r\n- 表格组件可嵌套`el-column`表格列组件使用,和`el-table`一致\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n```html\r\n<ws-table\r\n ref=\"table\"\r\n :loading=\"loading\"\r\n row-key=\"id\"\r\n :data=\"tableData\"\r\n :total=\"pagination.total\"\r\n :current-page.sync=\"pagination.pageIndex\"\r\n :page-size.sync=\"pagination.pageSize\"\r\n @current-change=\"handleCurrentChange\"\r\n @size-change=\"handleSizeChange\"\r\n :show-selection=\"true\"\r\n @selection=\"onSelectionChange\"\r\n>\r\n <el-table-column label=\"活码名称\" prop=\"qrcodeName\" min-width=\"160\" fixed=\"left\" />\r\n <el-table-column label=\"活码类型\" prop=\"qrcodeType\" min-width=\"120\">\r\n <template v-slot=\"{row}\">\r\n <span >{{row.qrcodeType === 1 ? '新客入群' : '标签入群'}}</span>\r\n </template>\r\n </el-table-column> \r\n <el-table-column label=\"创建人/部门\" prop=\"deptName\" min-width=\"160\">\r\n <template v-slot=\"scope\">\r\n <div>\r\n <div>{{scope.row.createUserId}}</div>\r\n <div>{{scope.row.deptId}}</div>\r\n </div>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建日期\" prop=\"gmtCreate\" min-width=\"160\" />\r\n</ws-table>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tableData: [],\r\n loading: false,\r\n pagination: {\r\n pageIndex: 1,\r\n pageSize: 10,\r\n total: 0\r\n },\r\n selection: {\r\n isSelectAll: false,\r\n currentSelection: 0,\r\n list: []\r\n }\r\n }\r\n },\r\n mounted() {\r\n this.getList();\r\n },\r\n methods: {\r\n handleSizeChange(val) {\r\n // 每页显示数量变更,重新发起请求 \r\n this.pagination.pageIndex = 1;\r\n this.pagination.pageSize = val;\r\n this.getList();\r\n },\r\n handleCurrentChange(val) {\r\n // 当前页码变更,重新发起请求 \r\n this.pagination.pageIndex = val;\r\n this.getList();\r\n },\r\n onSelectionChange(selection) {\r\n // 选中项发生变更 \r\n const { isSelectAll, currentSelection, list, rows } = selection;\r\n this.selection = selection;\r\n },\r\n getList() {\r\n this.loading = true;\r\n request({\r\n url: '/bff/marketing/private/pc/oldGroupQrCode/list',\r\n method: 'post',\r\n data: {\r\n pageIndex: this.pagination.pageIndex,\r\n pageSize: this.pagination.pageSize,\r\n sortField: this.sortField,\r\n sortType: this.sortType\r\n }\r\n }).then(data => {\r\n this.tableData = data.records || [];\r\n this.pagination.total = data.total;\r\n }).finally(()=> {\r\n this.loading = false;\r\n })\r\n },\r\n\r\n }\r\n}\r\n</script>\r\n\r\n```\r\n:::, 运行效果如图所示\n\n\r\n### 表格列排序\r\n对表格进行排序,可快速查找或对比数据。\r\nWsTable支持列排序的实现方式和ElTable相同。当列表支持分页时,列排序方式仅支持远程排序。\r\n\r\n### 表格分页\r\nWsTable默认支持分页,如需禁止分页,需配置WsTable组件属性`show-pagination`为`false`禁用分页,且需移除分页相关属性,包括:`current-page`、`page-size`、`current-change`、`size-change`属性。\r\n\r\n### 表格操作按钮\r\n- 表格组件顶部左上方及左下方为`operation`插槽区域,可插入WsButton、WeShineExportButton等操作按钮,针对表格选中内容,执行操作。位于列表上方的按钮组件需要置于`operation`插槽中。\r\n\r\n```html\r\n<ws-table>\r\n <template v-slot:operation>\r\n <ws-shine-export-button :btnText=\"导出列表\"></ws-shine-export-button>\r\n </template>\r\n</ws-table>\r\n```\r\n\r\n### 表格行操作\r\n表格最右侧添加“操作”列,嵌入`WsOperationGroup`表格行操作项容器,容器内嵌入`WsOperation`表格行操作项。\r\n每个表格行操作项以“文本链接”的形式展示。可通过配置属性`text`设置文本,支持添加`click`事件监听。\r\n`WsOperation`表格行操作项容器可通过属性`expandNum`设置显示在界面上的操作项数量,超出的部分会折叠隐藏。\r\n\r\n:::demo\r\n```html\r\n<ws-table\r\n ref=\"table\"\r\n :loading=\"loading\"\r\n row-key=\"id\"\r\n :data=\"tableData\"\r\n :total=\"pagination.total\"\r\n :current-page.sync=\"pagination.pageIndex\"\r\n :page-size.sync=\"pagination.pageSize\"\r\n @current-change=\"handleCurrentChange\"\r\n @size-change=\"handleSizeChange\"\r\n :show-selection=\"true\"\r\n @selection=\"onSelectionChange\"\r\n>\r\n <template v-slot:operation>\r\n <!-- 表格上方的操作按钮 -->\r\n <ws-button>批量删除</ws-button>\r\n <we-shine-export-button btnText='导出列表' />\r\n </template>\r\n <el-table-column label=\"活码名称\" prop=\"qrcodeName\" min-width=\"160\" fixed=\"left\" />\r\n <el-table-column label=\"活码类型\" prop=\"qrcodeType\" min-width=\"120\">\r\n <template v-slot=\"{row}\">\r\n <span >{{row.qrcodeType === 1 ? '新客入群' : '标签入群'}}</span>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建人/部门\" prop=\"deptName\" min-width=\"160\">\r\n <template v-slot=\"scope\">\r\n <div>\r\n <div>{{scope.row.createUserId}}</div>\r\n <div>{{scope.row.deptId}}</div>\r\n </div>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建日期\" prop=\"gmtCreate\" min-width=\"160\" />\r\n <el-table-column label=\"操作\" width=\"230\" align=\"center\" fixed=\"right\">\r\n <template v-slot=\"scope\">\r\n <ws-operation-group :expand-num=\"2\">\r\n <ws-operation text=\"编辑\" @click=\"onRowEdit(scope.row)\" />\r\n <ws-operation text=\"删除\" @click=\"onRowDelete(scope.row)\" />\r\n <ws-operation text=\"下载\" />\r\n </ws-operation-group>\r\n </template>\r\n </el-table-column>\r\n</ws-table>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tableData: [],\r\n loading: false,\r\n pagination: {\r\n pageIndex: 1,\r\n pageSize: 10,\r\n total: 0\r\n },\r\n selection: {\r\n isSelectAll: false,\r\n currentSelection: 0,\r\n list: []\r\n }\r\n }\r\n },\r\n mounted() {\r\n this.getList();\r\n },\r\n methods: {\r\n handleSizeChange(val) {\r\n // 每页显示数量变更,重新发起请求 \r\n this.pagination.pageIndex = 1;\r\n this.pagination.pageSize = val;\r\n this.getList();\r\n },\r\n handleCurrentChange(val) {\r\n // 当前页码变更,重新发起请求 \r\n this.pagination.pageIndex = val;\r\n this.getList();\r\n },\r\n onSelectionChange(selection) {\r\n // 选中项发生变更 \r\n const { isSelectAll, currentSelection, list, rows } = selection;\r\n this.selection = selection;\r\n },\r\n getList() {\r\n this.loading = true;\r\n request({\r\n url: '/bff/marketing/private/pc/oldGroupQrCode/list',\r\n method: 'post',\r\n data: {\r\n pageIndex: this.pagination.pageIndex,\r\n pageSize: this.pagination.pageSize,\r\n sortField: this.sortField,\r\n sortType: this.sortType\r\n }\r\n }).then(data => {\r\n this.tableData = data.records || [];\r\n this.pagination.total = data.total;\r\n }).finally(()=> {\r\n this.loading = false;\r\n })\r\n },\r\n onRowEdit(row) {\r\n // 编辑行 \r\n },\r\n onRowDelete(row) {\r\n // todo 调用接口删除数据\r\n // 表格数据删除时需重置选中项\r\n this.$refs.table.resetSelection();\r\n this.getList();\r\n }\r\n }\r\n }\r\n</script>\r\n\r\n```, 运行效果如图所示\n\n\r\n#### WsOperationGroup Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|-----------|--------|--------------|-------|\r\n| expandNum | 默认展开的按钮数量 | number | - | 0 |\r\n| trigger | 触发下拉的行为 | string | hover, click | hover |\r\n\r\n::: tip\r\n开发规范:WsOperationGroup 下需直接包裹 WsOperation 组件\r\n:::\r\n\r\n#### WsOperation Attributes\r\n\r\n基于 `WsButton` 封装,设定了基础规格,需配合 `WsOperationGroup` 组件使用\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------|--------|-----------|-----|--------|\r\n| type | 类型 | text、drag | 必传 | 'text' |\r\n| text | 按钮文本 | string | 选传 | '' |\r\n| disabled | 是否禁用状态 | boolean | — | false |\r\n\r\n\r\n### 表格拖拽\r\n表格支持拖拽,可通过为WsTable添加`row-key`属性,添加`dragChange`事件监听,并在操作栏添加行操作项`ws-operation`,类型为`drag`。 注意表格支持拖拽和支持分页互斥,支持拖拽场景需配置属性`show-pagination`为`false`禁用分页\r\n\r\n:::demo\r\n```html\r\n<!-- 标题+介绍 -->\r\n<ws-table\r\n ref=\"table\"\r\n :loading=\"loading\"\r\n row-key=\"id\"\r\n :data=\"tableData\"\r\n :show-pagination=\"false\"\r\n @dragChange=\"onDragChange\"\r\n>\r\n <el-table-column label=\"活码名称\" prop=\"qrcodeName\" min-width=\"160\" />\r\n <el-table-column label=\"活码类型\" prop=\"qrcodeType\" min-width=\"120\">\r\n <template v-slot=\"{row}\">\r\n <span >{{row.qrcodeType === 1 ? '新客入群' : '标签入群'}}</span>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"创建人/部门\" prop=\"deptName\" min-width=\"160\">\r\n <template v-slot=\"scope\">\r\n <div>\r\n <div>{{scope.row.createUserId}}</div>\r\n <div>{{scope.row.deptId}}</div>\r\n </div>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"操作\" width=\"130\">\r\n <ws-operation-group :expand-num=\"2\" slot-scope=\"scope\">\r\n <ws-operation text=\"推广\" />\r\n <ws-operation type='drag' />\r\n </ws-operation-group>\r\n </el-table-column>\r\n</ws-table>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n tableData: [],\r\n loading: false\r\n }\r\n },\r\n mounted() {\r\n this.getList();\r\n },\r\n methods: {\r\n getList() {\r\n this.loading = true;\r\n request({\r\n url: '/bff/marketing/private/pc/oldGroupQrCode/list',\r\n method: 'get'\r\n }).then(data => {\r\n this.tableData = data.records || [];\r\n }).finally(()=> {\r\n this.loading = false;\r\n })\r\n },\r\n onDragChange({newIndex, oldIndex}){\r\n // 行拖拽结束,需调用接口保存排序 \r\n console.log(newIndex, oldIndex)\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n```\r\n\r\n\r\n### Attributes\r\n\r\nWsTable以下属性和`ElTable`一致:\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n| data | 显示的数据 | array | — | — |\r\n| height | Table 的高度,默认为自动高度。如果 height 为 number 类型,单位 px;如果 height 为 string 类型,则这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。 | string/number | — | — |\r\n| max-height | Table 的最大高度。合法的值为数字或者单位为 px 的高度。 | string/number | — | — |\r\n| stripe | 是否为斑马纹 table | boolean | — | false |\r\n| border | 是否带有纵向边框 | boolean | — | false |\r\n| size | Table 的尺寸 | string | medium / small / mini | — |\r\n| fit | 列的宽度是否自撑开 | boolean | — | true |\r\n| show-header | 是否显示表头 | boolean | — | true |\r\n| highlight-current-row | 是否要高亮当前行 | boolean | — | false |\r\n| current-row-key | 当前行的 key,只写属性 | String,Number | — | — |\r\n| row-class-name | 行的 className 的回调方法,也可以使用字符串为所有行设置一个固定的 className。 | Function({row, rowIndex})/String | — | — |\r\n| row-style | 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style。 | Function({row, rowIndex})/Object | — | — |\r\n| cell-class-name | 单元格的 className 的回调方法,也可以使用字符串为所有单元格设置一个固定的 className。 | Function({row, column, rowIndex, columnIndex})/String | — | — |\r\n| cell-style | 单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style。 | Function({row, column, rowIndex, columnIndex})/Object | — | — |\r\n| header-row-class-name | 表头行的 className 的回调方法,也可以使用字符串为所有表头行设置一个固定的 className。 | Function({row, rowIndex})/String | — | — |\r\n| header-row-style | 表头行的 style 的回调方法,也可以使用一个固定的 Object 为所有表头行设置一样的 Style。 | Function({row, rowIndex})/Object | — | — |\r\n| header-cell-class-name | 表头单元格的 className 的回调方法,也可以使用字符串为所有表头单元格设置一个固定的 className。 | Function({row, column, rowIndex, columnIndex})/String | — | — |\r\n| header-cell-style | 表头单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style。 | Function({row, column, rowIndex, columnIndex})/Object | — | — |\r\n| row-key | 行数据的 Key,用来优化 Table 的渲染;在使用 reserve-selection 功能与显示树形数据时,该属性是必填的。类型为 String 时,支持多层访问:`user.info.id`,但不支持 `user.info[0].id`,此种情况请使用 `Function`。 | Function(row)/String | — | — |\r\n| empty-text | 空数据时显示的文本内容,也可以通过 `slot=\"empty\"` 设置 | String | — | 暂无数据 |\r\n| default-expand-all | 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 | Boolean | — | false |\r\n| expand-row-keys | 可以通过该属性设置 Table 目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。| Array | — | |\r\n| default-sort | 默认的排序列的 prop 和顺序。它的`prop`属性指定默认的排序的列,`order`指定默认排序的顺序| Object | `order`: ascending, descending | 如果只指定了`prop`, 没有指定`order`, 则默认顺序是ascending |\r\n| tooltip-effect | tooltip `effect` 属性 | String | dark/light | | dark |\r\n| show-summary | 是否在表尾显示合计行 | Boolean | — | false |\r\n| sum-text | 合计行第一列的文本 | String | — | 合计 |\r\n| summary-method | 自定义的合计计算方法 | Function({ columns, data }) | — | — |\r\n| span-method | 合并行或列的计算方法 | Function({ row, column, rowIndex, columnIndex }) | — | — |\r\n| select-on-indeterminate | 在多选表格中,当仅有部分行被选中时,点击表头的多选框时的行为。若为 true,则选中所有行;若为 false,则取消选择所有行 | Boolean | — | true |\r\n| indent | 展示树形数据时,树节点的缩进 | Number | — | 16 |\r\n| lazy | 是否懒加载子节点数据 | Boolean | — | — |\r\n| load | 加载子节点数据的函数,lazy 为 true 时生效,函数第二个参数包含了节点的层级信息 | Function(row, treeNode, resolve) | — | — |\r\n| tree-props | 渲染嵌套数据的配置选项 | Object | — | { hasChildren: 'hasChildren', children: 'children' } |\r\n\r\nWsTable新增以下属性:\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --- |-----------------------------------------------------------------| --- | --- |------------|\r\n| rowKey | 数据唯一标识,1:可传数据 KEY 2:可传函数根据业务判断返回唯一标识 string 3: 不传,根据内容生成标识(不建议) | string/Function(data) | 非必填 | |\r\n| loading | 内置的模拟进度条 loading | boolean | — | false |\r\n| hidden-header | 是否隐藏表格顶部 UI 视图 | boolean | — | false |\r\n| show-selection | 是否支持勾选(选择),如果是,添加 type=\"selection\" `勾选列`,相关事件由 `selection` 接管 | boolean | — | false |\r\n| enableSelectAll | 是否可全选 | boolean | — | true |\r\n| canReserve | 非全选条件下,是否保留已选,如搜索 | boolean | — | false |\r\n| selectable | 判断`勾选列`是否可被选中,同el-column selectable属性 | Function(row, index) | — | () => true |\r\n| selectable-tips | 当设置 selectable 属性时,在禁选项可通过此属性展示 hover 提示 | String \\| Function(row, index) | — | '' |\r\n| default-selection | 默认选中数据,用于数据回显 | Array[rowKey] | — | [] |\r\n| default-rows | 默认选中的完整表格数据,用于数据回显 | Array[TableRow] | — | [] |\r\n| disabled-count | 禁选数量总数 | number | — | 0 |\r\n| multiple | 表格是否支持多选,默认为true, 设为 false 代表表格仅支持单选,并将隐藏表头及分页器的全选操作 | boolean | — | true |\r\n| show-pagination | 是否展示分页器,默认展示 | boolean | — | true |\r\n| reactive | 分页器是否自动响应悬浮,仅在响应式布局页面配置。 弹窗内表格、多表格页面和没有菜单的内页不要自动响应悬浮 | boolean | — | false |\r\n| sticky | 表格头部吸顶(v2.5.0更新) | boolean | — | false |\r\n\r\n\r\n### Events\r\nWsTable以下事件和`ElTable`一致:\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|--------------------| ---- |-----------------------------------|\r\n| cell-mouse-enter | 当单元格 hover 进入时会触发该事件 | row, column, cell, event |\r\n| cell-mouse-leave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |\r\n| cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |\r\n| cell-dblclick | 当某个单元格被双击击时会触发该事件 | row, column, cell, event |\r\n| row-click | 当某一行被点击时会触发该事件 | row, column, event |\r\n| row-contextmenu | 当某一行被鼠标右键点击时会触发该事件 | row, column, event |\r\n| row-dblclick | 当某一行被双击时会触发该事件 | row, column, event |\r\n| header-click | 当某一列的表头被点击时会触发该事件 | column, event |\r\n| header-contextmenu | 当某一列的表头被鼠标右键点击时触发该事件 | column, event |\r\n| sort-change | 当表格的排序条件发生变化的时候会触发该事件 | { column, prop, order } |\r\n| filter-change | 当表格的筛选条件发生变化的时候会触发该事件,参数的值是一个对象,对象的 key 是 column 的 columnKey,对应的 value 为用户选择的筛选条件的数组。 | filters |\r\n| current-change | 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性 | currentRow, oldCurrentRow |\r\n| header-dragend | 当拖动表头改变了列的宽度的时候会触发该事件 | newWidth, oldWidth, column, event |\r\n| expand-change | 当用户对某一行展开或者关闭的时候会触发该事件(展开行时,回调的第二个参数为 expandedRows;树形表格时第二参数为 expanded) | row, (expandedRows \\| expanded) |\r\n\r\nWsTable新增事件类型如下:\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|--------------------| ---- |-----------------------------------|\r\n| selection | 当选择项发生变化时会触发该事件 | Selection |\r\n| dragChange | 表格行拖拽结束事件,引起了排序变更 | { newIndex, oldIndex } |\r\n\r\n### Table Methods\r\n| 方法名 | 说明 | 参数 |\r\n|--------------------|---------------------------------------------------------------------| ---- |\r\n| resetSelection | 用于多选表格,清除选中项 | - |\r\n| revertSelection | 用于多选表格,重置勾选指定数据,参数同 *@selection* 事件参数 | Selection |\r\n| clearSelection | 用于多选表格,清空用户的选择 | — |\r\n| toggleRowSelection | 用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中) | row, selected |\r\n| toggleAllSelection | 用于多选表格,切换所有行的选中状态 | - |\r\n| toggleRowExpansion | 用于可展开表格与树形表格,切换某一行的展开状态,如果使用了第二个参数,则是设置这一行展开与否(expanded 为 true 则展开) | row, expanded |\r\n| setCurrentRow | 用于单选表格,设定某一行为选中行,如果调用时不加参数,则会取消目前高亮行的选中状态。 | row |\r\n| clearSort | 用于清空排序条件,数据会恢复成未排序的状态 | — |\r\n| doLayout | 对 Table 进行重新布局。当 Table 或其祖先元素由隐藏切换为显示时,可能需要调用此方法 | — |\r\n| sort | 手动对 Table 进行排序。参数`prop`属性指定排序列,`order`指定排序顺序。 | prop: string, order: string |\r\n\r\n### Table Slots\r\n| name | 说明 |\r\n|------|--------|\r\n| append | 插入至表格最后一行之后的内容,如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。若表格有合计行,该 slot 会位于合计行之上。 |\r\n| operation | 表格操作项,将置于表格顶部及分页器 |\r\n| header | 置于表头右上角的额外操作插槽 |\r\n| empty | 同 el-table 的 slot=\"empty\" |\r\n\r\n### el-column Attributes\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n| type | 对应列的类型。如果设置了 `selection` 则显示多选框;如果设置了 `index` 则显示该行的索引(从 1 开始计算);如果设置了 `expand` 则显示为一个可展开的按钮 | string | selection/index/expand | — |\r\n| index | 如果设置了 `type=index`,可以通过传递 `index` 属性来自定义索引 | number, Function(index) | - | - |\r\n| column-key | column 的 key,如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件 | string | — | — |\r\n| label | 显示的标题 | string | — | — |\r\n| prop | 对应列内容的字段名,也可以使用 property 属性 | string | — | — |\r\n| width | 对应列的宽度 | string | — | — |\r\n| min-width | 对应列的最小宽度,与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列 | string | — | — |\r\n| fixed | 列是否固定在左侧或者右侧,true 表示固定在左侧 | string, boolean | true, left, right | — |\r\n| render-header | 列标题 Label 区域渲染使用的 Function | Function(h, { column, $index }) | — | — |\r\n| sortable | 对应列是否可以排序,如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean, string | true, false, 'custom' | false |\r\n| sort-method | 对数据进行排序的时候使用的方法,仅当 sortable 设置为 true 的时候有效,需返回一个数字,和 Array.sort 表现一致 | Function(a, b) | — | — |\r\n| sort-by | 指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推 | String/Array/Function(row, index) | — | — |\r\n| sort-orders | 数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序 | array | 数组中的元素需为以下三者之一:`ascending` 表示升序,`descending` 表示降序,`null` 表示还原为原始顺序 | ['ascending', 'descending', null] |\r\n| resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true |\r\n| formatter | 用来格式化内容 | Function(row, column, cellValue, index) | — | — |\r\n| show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | Boolean | — | false |\r\n| align | 对齐方式 | String | left/center/right | left |\r\n| header-align | 表头对齐方式,若不设置该项,则使用表格的对齐方式 | String | left/center/right | — |\r\n| class-name | 列的 className | string | — | — |\r\n| label-class-name | 当前列标题的自定义类名 | string | — | — |\r\n| selectable | 仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选 | Function(row, index) | — | — |\r\n| reserve-selection | 仅对 type=selection 的列有效,类型为 Boolean,为 true 则会在数据更新之后保留之前选中的数据(需指定 `row-key`) | Boolean | — | false |\r\n| filters | 数据过滤的选项,数组格式,数组中的元素需要有 text 和 value 属性。 | Array[{ text, value }] | — | — |\r\n| filter-placement | 过滤弹出框的定位 | String | 与 Tooltip 的 `placement` 属性相同 | — |\r\n| filter-multiple | 数据过滤的选项是否多选 | Boolean | — | true |\r\n| filter-method | 数据过滤使用的方法,如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示。 | Function(value, row, column) | — | — |\r\n| filtered-value | 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。 | Array | — | — |\r\n\r\n_为保持表格列的自适应布局,统一使用 `min-width` 代替 `width` 属性_\r\n\r\n### el-column Scoped Slot\r\n| name | 说明 |\r\n|------|--------|\r\n| — | 自定义列的内容,参数为 { row, column, $index } |\r\n| header | 自定义表头的内容. 参数为 { column, $index } |\r\n\r\n\r\n### 类型定义\r\n```ts\r\ninterface Selection {\r\n isSelectAll: boolean; // 是否全选\r\n currentSelection: number; // 勾选数量\r\n list: Array<string>; // 选中的行标识列表。全选时,为反选排除的 rowKey 列表,非全选时为选中的 rowKey 列表\r\n rows: Array<any>; // 选中的行完整数据。全选时,为反选的数据列表,非全选时为选中的数据列表\r\n}\r\n```\r\n\r\n### 坑点\r\n\r\n::: tip 开发规范\r\n如果表格支持分页,需通过表格`sortable`属性配置默认的排序方式,并且data中的排序字段初值值需和`sortable`保持一致,否则会导致界面显示排序方式和实际请求结果排序方式不一致。\r\n:::\r\n\r\n::: tip\r\n开发表格相关业务功能时,必须自测到以下用例:\r\n\r\n1、添加表格全选相关能力时,需检查全选后反选的参数传递是否正确\r\n\r\n2、添加表格筛选条件时,需检查 operation 插槽里的操作项的功能参数传递是否正确。(如导出按钮、批量下载等等)\r\n\r\n:::\r\n\r\n::: tip\r\n开发规范:reactive属性只能在一级列表页使用,弹窗内表格、多表格页面和没有菜单的内页不要自动响应悬浮\r\n:::\r\n\r\n::: tip\r\nenableSelectAll 和 canReserve 属性 让表格支持两种选择模式:\r\n\r\nenableSelectAll: 默认为 跨页全选的 能力。(重新触发筛选条件搜索需要调 resetSelection 清空已选数据)\r\n\r\ncanReserve: 去掉 跨页全选的 能力,让触发筛选条件搜索时保留已选数据,让选择数据可追加。(不能调用 resetSelection 方法)\r\n:::\r\n\r\n\r\n::: tip\r\nsticky 注意事项:表格父容器(包括祖先元素)不能有overflow属性,需设为visible,且需自行检查有无问题。(因实现原理是通过position:sticky来实现的)\r\n:::\r\n\r\n\r\n::: tip\r\n与分页相关的开发规范:\r\n当需要分页时,必须配置current-page属性(非page字段)及 @current-change事件、page-size属性。\r\n\r\n不应该配置page-sizes属性以采用微盛分页规范:10/20/50/100页/条。 如产品要求和规范不符,找 @阿遥 确认。\r\n\r\n不应该配置.sync修饰符,统一事件触发\r\n\r\n如未配置current-page属性会导致因筛选项变更导致ws-table数据源重置时,页码未正确重置回1的问题。\r\n\r\n如未配置page-size属性会导致因筛选项变更导致ws-table数据源重置时,分页器的当前页码会被重置为第一项:10条/页\r\n:::"
},
{
"name": "ws-import-dialog",
"category": "PC端组件库",
"content": "## WsImportDialog - 批量导入对话框\r\n\r\n批量导入对话框组件可批量导入xls,xlsx文件中的数据。\r\n批量导入流程分为三步:下载模版、上传文件、结果展示。\r\n\r\n- 1、下载模版。通过配置组件属性`down-temp-fn`函数,函数返回下载模版链接,返回类型为`Promise<string>`。\r\n- 2、导入文件。通过配置组件属性`import-file-fn`函数,函数返回类型为`Promise<ImportFileResponse>`。返回信息中msg,successCount,failCount用于结果展示;失败情况,downId用于传参下载失败文件。\r\n```typescript\r\n// 导入文件接口返回内容格式\r\ninterface ImportFileResponse {\r\n downId: string;\r\n successCount: number; //导入成功数量\r\n failCount: number //导入失败数量\r\n}\r\n\r\n```\r\n- 3、结果展示。\r\n 如果失败,下载失败文件,通过配置组件属性`get-failure-fn`函数,其中的downId值为导出任务id, 来源于“导入文件函数”返回体`ImportFileResponse`中的`downId`字段。函数中返回类型为`Promise<string>`。 当导入失败时,会显示“导出结果明细”链接。\r\n\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/pc-base-ui`中具名导入`WsImportDialog`组件, 并在页面中注册;\r\n\r\n```js\r\n\r\n<script>\r\n import { WsImportDialog } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsImportDialog\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-button @click=\"dialogVisible = true;\">批量导入</ws-button>\r\n <ws-import-dialog\r\n :title=\"title\"\r\n :keyword=\"keyword\"\r\n :visible.sync=\"dialogVisible\"\r\n :down-temp-fn=\"downTempFn\"\r\n :import-file-fn=\"importFileFn\"\r\n :get-failure-fn=\"getFailureFn\"\r\n @cancel=\"importCancel\"\r\n @confirm=\"importConfirm\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n title: \"批量导入\", //dialog的标题\r\n keyword: \"敏感词\", //数据类型\r\n dialogVisible: false, //是否显示 Dialog\r\n };\r\n },\r\n methods: {\r\n //获取下载模版地址\r\n downTempFn() {\r\n return request({\r\n url: \"/bff/ca/private/pc/getTemplate\",\r\n method: \"post\",\r\n });\r\n },\r\n //导入文件\r\n importFileFn(data) {\r\n return request({\r\n url: \"/bff/ca/private/pc/import\",\r\n method: \"post\",\r\n data,\r\n })\r\n },\r\n // 获取导出失败文件url地址\r\n getFailureFn(downId) {\r\n return request({\r\n url: \"/bff/ca/private/pc/downloadFail\",\r\n method: \"post\",\r\n data: { downId },\r\n errorTips: \"error\",\r\n });\r\n },\r\n // 取消上传\r\n importCancel() {\r\n this.dialogVisible = false;\r\n },\r\n // 确认上传\r\n importConfirm() {\r\n this.dialogVisible = false;\r\n this.$message.success(\"文件上传成功\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|--------------|-----------------------------------|-------------------------------------------------------------------------|-----|-----|\r\n| title | dialog 的标题文案 | string | - | 批量导入|\r\n| maxSize | 允许上传的文件大小,以M为单位 | number | - | 1 |\r\n| keyword | 数据类型,用于显示在校验结果中文案 | string | - | 敏感词 |\r\n| uploadTips | 上传提示语 | string | - | 下载模板并完善信息后,可直接将文件拖拽到此处进行上传,支持xls,xlsx格式 |\r\n| downTempFn | 获取下载模版地址 | ()=\\>Promise\\<string\\> | - | - |\r\n| importFileFn | 导入文件 | (data: File)=\\>Promise\\<ImportFileResponse\\> | - | - |\r\n| getFailureFn | 导出失败文件url地址 | (downId: string)=\\>Promise\\<string\\>| - | - |\r\n| uploadVerify | 自定义校验文件钩子,结果返回true表示文件拦截 | (data: File)=\\>Promise\\<boolean\\>\\| boolean | - | - |\r\n\r\n\r\n### Events\r\n| 名称 | 说明 | 参数 |\r\n|---------|---------|-----|\r\n| confirm | 点击确认时触发 | - |\r\n| cancel | 点击取消时触发 | - |"
},
{
"name": "ws-tag-show",
"category": "PC端组件库",
"content": "## WsTagShow 标签组组件\r\n\r\n标签组组件也叫标签列表组件;可以展示一组标签; 标签样式类似`el-tag`标签,标签组内的标签水平排列,标签间距相等,到达容器边缘后折行展示标签。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`NPM包具名导入`WsTagShow`组件以及`WsTagShowItem`组件, 并在页面中注册\r\n\r\n```html\r\n<script>\r\n import { WsTagShow, WsTagShowItem } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsTagShow,\r\n WsTagShowItem\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基本使用\r\n标签组组件可自适应容器宽高,可以通过样式属性`height`限定标签组最大高度。\r\n标签可配置`max-width`最大宽度属性,当文本内容超过最大宽度时会溢出隐藏。\r\n标签组组件只能嵌入若干个`WsTagShowItem`标签组件。\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-tag-show :list='tagList' :style=\"{height: '64px'}\">\r\n <ws-tag-show-item\r\n v-for='(v, i) in tagList' :key='i'\r\n :maxWidth='100'>\r\n {{v.name}}\r\n </ws-tag-show-item>\r\n </ws-tag-show>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tagList: new Array(40).fill({\r\n name: '测试用的长文本内容'\r\n })\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 隐藏数量标签\r\n标签组组件当达到容器尺寸限制且有部分标签未能展示时,会在最后显示\"+N\"标签,代表隐藏的标签数量,此标签称为隐藏数量标签。\r\n鼠标放在标签组上面,会以popover弹框的形式展示完整的标签列表。\r\n可通过`more`作用域插槽实现隐藏数量标签替换, 作用域中的`num`属性代表隐藏的标签数量。\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-tag-show :list='tagList' :style=\"{height: '64px'}\">\r\n <ws-tag-show-item\r\n v-for='(v, i) in tagList' :key='i'\r\n :maxWidth='100'>\r\n {{v.name}}\r\n </ws-tag-show-item>\r\n <template v-slot:more=\"slotProps\">\r\n <ws-tag-show-item>\r\n +{{slotProps.num}}标签\r\n </ws-tag-show-item>\r\n </template>\r\n </ws-tag-show>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tagList: new Array(40).fill({\r\n name: '测试用的长文本内容'\r\n })\r\n };\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n:::\r\n\r\n### WsTagShow Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|-----------------|--------|-----------------------------------------------------------------------------------------------------------------------------------|---------|\r\n| placement | popover 弹出框出现的位置 | string | 'top' 'top-start' 'top-end' 'bottom' 'bottom-start' 'bottom-end' 'left' 'left-start' 'left-end' 'right' 'right-start' 'right-end' | 'top' |\r\n| trigger | popover 弹出框触发方式 | string | 'hover'、'trigger' | 'hover' |\r\n| list | 数据源 | Array | - | false |\r\n\r\n### WsTagShow Slots\r\n\r\n| name | 说明 |\r\n|---------|----------------|\r\n| default | 标签项插槽 |\r\n| title | popover 上的标题插槽 |\r\n\r\n### WsTagShow Slot-scoped\r\n\r\n| name | 说明 | 参数 |\r\n|------|------|-----------|\r\n| more | 更多插槽 | num: 剩余数量 |\r\n\r\n### WsTagShowItem Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------|-------------------------|--------------------------|---------------|-----|\r\n| maxWidth | 最大宽度, 单位为像素。不设置代表全展示不隐藏 | number | | |\r\n\r\n### WsTagShowItem Slots\r\n\r\n| name | 说明 |\r\n|---------|------|\r\n| default | 名称插槽 |\r\n\r\n:::tip\r\n### 使用问题注意事项\r\n1、组件容器需要定义高度、\r\n2、list 数据源必须传递,以便内部监听变更重绘\r\n3、标签组组件默认插槽不要使用div包裹WsTagShowItem元素\r\n4、控制标签子元素显隐需使用v-if, 不能使用v-show\r\n:::"
},
{
"name": "ws-export",
"category": "PC端组件库",
"content": "## WeShineExport - 通用异步导出按钮组件\r\n(v3.3.1 版本支持)\r\n\r\n### 组件说明\r\n通用异步导出按钮组件基于`el-button` 和 `el-progress`组件实现功能,可实现点击按钮时异步导出表格列表数据,且实时显示导出进度。此组件通常需配合`WsTable`表格组件使用,置于`WsTable`的`operation`插槽中。\r\n异步导出流程分三步:创建导出任务、轮询导出进度、下载。\r\n\r\n通用异步导出按钮组件与异步导出按钮组件的最大的区别在于:通用异步导出按钮组件只需要后端提供对应的场景值 `businessScenario`, 而不需要配置 `create-fn`、`get-progress-fn`、`get-url-fn`三个方法。\r\n\r\n\r\n### 功能\r\n- 异步导出\r\n- 导出进度/完成状态本地缓存,页面刷新或关闭后可恢复状态\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineExport`组件, 并在页面中注册\r\n\r\n```html\r\n<script>\r\n import { WeShineExport } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WeShineExport\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基本使用\r\nmoduleId为前端全局模块唯一id,常见的场景:\r\n在详情页里的导出,此moduleId需要和当前业务的详情id进行关联,如活码详情列表里的导出:`qrcode-XXXXX`\r\n\r\nbusinessScenario属性为后端定义的业务场景值,由后端提供。\r\n\r\ncreateTaskParams属性为创建导出任务接口请求参数,返回值会作为创建导出任务接口的请求参数。一般为表格上方的筛选条件。\r\n\r\n:::demo\r\n```html\r\n\r\n<template>\r\n <we-shine-export\r\n moduleId='WeShineExport-base'\r\n businessScenario='CUSTOMER_CUSTOMER_DISTINCT_EXPORT'\r\n :createTaskParams='createTaskParams'\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n //筛选条件\r\n searchOptions: {'keyWord': ''},\r\n };\r\n },\r\n methods: {\r\n // 创建导出任务接口请求参数\r\n createTaskParams() {\r\n return this.searchOptions;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 通用异步导出前置拦截\r\nbeforeStage方法可对`创建导出任务`、`轮询导出进度`、`下载` 三个阶段进行前置拦截。具体方法定义:\r\n\r\nbeforeStage: (stage: 'create' | 'progress' | 'download', config: AxiosRequestConfig) => Promise\\<AxiosRequestConfig|false\\>\r\n\r\n方法可返回一个Promise.reject 或 Promise\\<false\\> 来控制中断流程,也可返回一个 Promise\\<AxiosRequestConfig\\> 来重新定义此阶段的api请求。\r\n\r\n `创建导出任务`阶段拦截示例\r\n\r\n:::demo\r\n```html\r\n\r\n<template>\r\n <we-shine-export\r\n moduleId='WeShineExport-beforeStage1'\r\n businessScenario='CUSTOMER_CUSTOMER_DISTINCT_EXPORT'\r\n downloadMethod='blob'\r\n :createTaskParams='createTaskParams'\r\n :beforeStage='beforeStage'\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n //筛选条件\r\n searchOptions: {'keyWord': ''},\r\n };\r\n },\r\n methods: {\r\n // 创建导出任务接口请求参数\r\n createTaskParams() {\r\n return this.searchOptions;\r\n },\r\n async beforeStage(stage, config) {\r\n // 创建导出任务前拦截\r\n if(stage === 'create'){\r\n // 发起网络请求,检查是否有导出权限\r\n const shouldIntercept = await request({\r\n url: '/export-check',\r\n method: 'post'\r\n });\r\n return shouldIntercept;\r\n }\r\n return config;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n`下载`阶段拦截示例\r\n\r\n:::demo\r\n```html\r\n\r\n<template>\r\n <we-shine-export\r\n moduleId='WeShineExport-beforeStage2'\r\n businessScenario='CUSTOMER_CUSTOMER_DISTINCT_EXPORT'\r\n downloadMethod='blob'\r\n :createTaskParams='createTaskParams'\r\n :beforeStage='beforeStage'\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n //筛选条件\r\n searchOptions: {'keyWord': ''},\r\n };\r\n },\r\n methods: {\r\n // 创建导出任务接口请求参数\r\n createTaskParams() {\r\n return this.searchOptions;\r\n },\r\n async beforeStage(stage, config) {\r\n // 点击下载前拦截\r\n if(stage === 'download'){\r\n // 发起网络请求,检查是否有权限\r\n const shouldIntercept = await request({\r\n url: '/download-check',\r\n method: 'post'\r\n });\r\n return shouldIntercept;\r\n }\r\n return config;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 定制导出按钮\r\n可使用 button 插槽,对导出按钮做一些定制化的交互,如点击导出按钮打开确认对话框,确认后才开始创建导出任务。\r\n\r\n如下实现:需要通过使用ref获取组件实例,调用`startExport`方法来手动触发导出, 且需要自行控制按钮的导出状态(导出中、禁用)\r\n\r\n:::demo\r\n```html\r\n\r\n<template>\r\n <we-shine-export\r\n ref=\"export\"\r\n moduleId='WeShineExport-button'\r\n businessScenario='CUSTOMER_CUSTOMER_DISTINCT_EXPORT'\r\n :createTaskParams='createTaskParams'>\r\n <template v-slot:button='slotProps'>\r\n <ws-button :disabled='slotProps.exportInProgress' @click='exportBtnClick'>导出列表</ws-button>\r\n </template>\r\n</we-shine-export>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n //筛选条件\r\n searchOptions: {'keyWord': ''},\r\n };\r\n },\r\n methods: {\r\n // 创建导出任务接口请求参数\r\n createTaskParams() {\r\n return this.searchOptions;\r\n },\r\n //导出按钮点击事件\r\n exportBtnClick() {\r\n this.$confirm('确认导出列表吗?', '确认信息', {\r\n confirmButtonText: '确定导出',\r\n cancelButtonText: '取消'\r\n }).then(() => {\r\n this.$refs.export.startExport();\r\n }).catch(() => {})\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n::: tip\r\n导出批量下载:当导出完成后,有多个文件需要下载时,这时需要弹框显示下载列表的场景,不需要额外的配置,只需后端下载文件的接口返回数组(Array\\<DownloadLinkUrl\\>)即可。\r\n(当数组只有一个时,会直接下载,不会触发弹框)\r\n\r\n```ts\r\ninterface DownloadLinkUrl {\r\n name: string; // 导出文件名称,示例: \"客户列表导出-去重_001_000.xlsx\"\r\n url: string; // 导出文件下载地址,示例:\"https://open.work.weixin.qq.com/wwopen/openData/getTranslateContactOpenData?dataid=oZ-N1NhowjJElv5k2qI16XsOelikc-4ntLDTBkzryQw\"\r\n}\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 是否必传 | 可选值 | 默认值 |\r\n| --------- |------------------------------------------------------------------------------| ---------- | ------ | ------ | ------ |\r\n| moduleId | 前端模块id(全局唯一) | string | 是 | - | - |\r\n| businessScenario | 后端定义的导出业务场景值 | string | 是 | - | - |\r\n| createTaskParams | 返回创建导出任务API请求的参数的方法 | () => Record\\<string, any\\> | 是 | - | - |\r\n| beforeStage | 创建导出任务、轮询导出进度、下载方法前置拦截方法 | (stage: 'create' \\| 'progress' \\| 'download', config: AxiosRequestConfig) => Promise\\<AxiosRequestConfig\\|false> | 否 | - | - |\r\n| downloadMethod | 下载方式:href\\|blob, href:下载内容包含三方应用企微转义内容,如员工/部门信息,需配置为此方式。 blob: 不包含三方应用企微转义内容 | string | 否 | href\\|blob | href |\r\n| downloadFileNameHref | href下载方式下的下载文件名称 | string | 否 | - | - |\r\n| exportButtonDisabled | 导出按钮禁用状态 | boolean | 否 | - | false |\r\n| exportButtonText | 导出按钮文字内容 | string | 否 | - | 导出列表 |\r\n| progressLoopTimeOut | 导出任务查询进度超时配置,单位毫秒 | number | 否 | - | 30 x 60 x 1000 (30分钟) |\r\n\r\n### slots\r\n\r\n| 插槽名称 | 说明 | 作用域参数 |\r\n|---------- |-------- |---------- |\r\n| button | 导出按钮 | exportInProgress:布尔值,导出任务进行中|\r\n\r\n\r\n### Methods\r\n\r\n| 方法名称 | 说明 | 参数 |\r\n|---------- |-------- |---------- |\r\n| startExport | 触发创建导出任务 | - |"
},
{
"name": "breadcrumb",
"category": "PC端组件库",
"content": "## BreadCrumb - 面包屑\r\n\r\n面包屑组件仅在模块内页中使用,位于页面顶部,显示当前页面的标题;点击左侧的“返回”按钮,可返回到上一页。\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/pc-base-ui`中具名导入`Breadcrumb`组件, 并在页面中注册;\r\n\r\n```js\r\n\r\n<script>\r\n import { Breadcrumb } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n Breadcrumb\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <bread-crumb pageTitle=\"页面标题\" show-back></bread-crumb>\r\n</template>\r\n\r\n```\r\n:::\r\n\r\n### 返回按钮配置\r\n\r\n返回按钮位于组件左侧,默认的按钮文本为“返回”,可通过配置属性“operationTips\"配置按钮文本。\r\n返回事件是指用法点击`返回`按钮时触发的事件,默认的行为为返回到上一页,可通过配置`backUrl`属性配置点击时跳往的路由地址,也可以可通过配置`backFunc`函数属性实现自定义返回事件。\r\n当`backFunc`函数与`backUrl`属性同时存在时,只会执行`backFunc`函数。\r\n\r\n\r\n```html\r\n<template>\r\n <bread-crumb \r\n pageTitle=\"页面标题\"\r\n show-back\r\n operations-tip=\"企业列表\"\r\n back-url=\"/enterprise-list\" >\r\n </bread-crumb>\r\n</template>\r\n```\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <bread-crumb \r\n pageTitle=\"页面标题\" \r\n show-back\r\n @backFunc=\"backFunc\" >\r\n </bread-crumb>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n methods: {\r\n backFunc() {\r\n // 自定义返回事件,可添加返回前需处理事项\r\n this.$router.push('/enterprise-list')\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------------|----------------|----------|-----|-------|\r\n| showBack | 是否展示返回按钮 | boolean | - | false |\r\n| operationsTip | 返回按钮文本 | string | - | 返回 |\r\n| pageTitle | 页面标题 | string | - | - |\r\n| backUrl | 点击返回按钮跳转到的路由地址 | string | - | - |\r\n| backFunc | 自定义返回事件 | Function | - | - |\r\n| bold | 页面标题是否加粗 | boolean | - | false |"
},
{
"name": "ws-empty",
"category": "PC端组件库",
"content": "## WsEmptyPlaceholder - 缺省占位组件\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineEmptyPlaceholder top=\"48\" text=\"暂无数据\">\r\n <el-button>自定义功能</el-button>\r\n </WeShineEmptyPlaceholder>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {}\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------|-------------------|--------|--------|------|\r\n| top | 组件 `margin-top` 值 | string | number | - | - |\r\n| text | 基本的说明提示文案 | string | - | 暂无数据 |\r\n| tips | 额外的提示文案 | string | - | - |\r\n\r\n### Slots\r\n\r\n| 事件名称 | 说明 | \r\n|------|---------------|\r\n| text | 自定义 text 提示内容 |\r\n| - | 用以在最底部添加自定义功能 |"
},
{
"name": "ws-input-download",
"category": "PC端组件库",
"content": "## WsInputDownload 名称输入组件\r\n\r\n基于 [el-input](/#/zh-CN/component/input) 开发,提供支持校验的文本输入能力。输入文本在下载、导出场景中用做文件名时,必须使用此名称校验输入组件。(比如:创建活码时,活码名称表单项)。\r\n- 名称输入组件能过滤掉特殊字符,特殊字符包括:`?`、`*`、`\"`、`<`、`>`、`|`、`:`、`/`、`\\`、空白字符。名称输入组件里面输入特殊字符时,会弹出错误提示Message。\r\n- 与 [el-input](/#/zh-CN/component/input) 的区别:不支持append、operation、header、empty具名插槽;不支持 Autocomplete Attributes、Autocomplete Slots、Autocomplete Scoped Slot、Autocomplete Events、Autocomplete Methods。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsInputDownload`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WsInputDownload} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsInputDownload\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name\" placeholder=\"请输入内容\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 禁用状态\r\n通过 disabled 属性指定是否禁用 名称输入组件 组件\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name\" placeholder=\"请输入内容\" disabled />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 只读状态\r\n通过 readonly 属性指定 名称输入组件 是否只读,即不可输入状态\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name\" placeholder=\"请输入内容\" readonly />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 可清空\r\n通过 clearable 属性设置 名称输入组件 输入框是否可清空\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name\" placeholder=\"请输入内容\" clearable />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 输入长度限制\r\nmaxlength 是原生属性,用来限制 名称输入组件 输入框的字符长度,其中字符长度是用 Javascript 的字符串长度统计的。对于类型为 text 或 textarea 的名称输入组件,在使用 maxlength 属性限制输入框可输入的最大输入长度的同时,可通过设置 show-word-limit 属性来展示字数统计\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name1\" placeholder=\"不展示字符长度\" :maxlength=\"10\" style=\"margin-bottom:20px\" />\r\n <ws-input-download v-model=\"name2\" placeholder=\"展示字符长度\" :maxlength=\"6\" show-word-limit />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name1: '',\r\n name2: '',\r\n name3: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 带icon的输入框\r\n带有图标标记输入类型。通过 prefix-icon 和 suffix-icon 属性在 名称输入组件 组件首部和尾部增加显示图标\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name1\" placeholder=\"prefix-icon属性\" prefix-icon=\"el-icon-search\" style=\"margin-bottom: 20px\"/>\r\n <ws-input-download v-model=\"name2\" placeholder=\"suffix-icon属性\" suffix-icon=\"el-icon-search\" />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name1: '',\r\n name2: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 尺寸\r\n通过 size 属性指定 名称输入组件 输入框的尺寸,除了默认的大小外,还提供了 medium、small 和 mini 三种尺寸\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name1\" style=\"margin-bottom:20px\" placeholder=\"默认\"/>\r\n <ws-input-download v-model=\"name2\" style=\"margin-bottom:20px\" size=\"medium\" placeholder=\"medium\"/>\r\n <ws-input-download v-model=\"name3\" style=\"margin-bottom:20px\" size=\"small\" placeholder=\"small\"/>\r\n <ws-input-download v-model=\"name4\" size=\"mini\" placeholder=\"mini\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name1: '',\r\n name2: '',\r\n name3: '',\r\n name4: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 文本域\r\n通过将 type 属性的值指定为 textarea,设置 名称输入组件 为可输入多行文本信息的类型\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name1\" type=\"textarea\" placeholder=\"基础用法\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name2\" type=\"textarea\" placeholder=\"自适应内容高度\" autosize style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name3\" type=\"textarea\" placeholder=\"指定最小行数和最大行数\" :autosize=\"{ minRows: 2, maxRows: 6 }\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name4\" type=\"textarea\" placeholder=\"指定输入框行数\" :rows=\"2\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name5\" type=\"textarea\" placeholder=\"禁用缩放\" :rows=\"2\" resize=\"none\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name6\" type=\"textarea\" placeholder=\"水平、垂直方向缩放\" :rows=\"2\" resize=\"both\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name7\" type=\"textarea\" placeholder=\"水平方向缩放\" :rows=\"2\" resize=\"horizontal\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name8\" type=\"textarea\" placeholder=\"垂直方向缩放\" :rows=\"2\" resize=\"vertical\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name1: '',\r\n name2: '',\r\n name3: '',\r\n name4: '',\r\n name5: '',\r\n name6: '',\r\n name7: '',\r\n name8: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 高级使用\r\n- autocomplete/auto-complete - input原生属性,意思为自动完成。即用户在 名称输入组件 输入一部分,后面的自动补全。需要浏览器保存用户输入的内容,以便下一次自动补全。\r\n- name - input原生属性,用于设置 名称输入组件 元素的名称。\r\n- max - input原生属性,设置 名称输入组件 可输入的最大值。\r\n- min - input原生属性,设置 名称输入组件 可输入的最小值。\r\n- step - input原生属性,设置 名称输入组件 输入字段的合法数字间隔。\r\n- autofocus - input原生属性,设置 名称输入组件 输入框自动获取焦点。\r\n- show-password - 设置 名称输入组件 显示切换密码图标。\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"name1\" autocomplete placeholder=\"autocomplete属性\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name2\" placeholder=\"auto-complete属性\" autosize style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name3\" type=\"number\" max=\"5\" placeholder=\"type为number的max属性\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name4\" type=\"number\" min=\"4\" placeholder=\"type为number的min属性\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name5\" type=\"number\" step=\"4\" placeholder=\"type为number的step属性\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name6\" autofocus placeholder=\"autofocus属性\" style=\"margin-bottom: 20px\" />\r\n <ws-input-download v-model=\"name7\" show-password placeholder=\"show-password属性\" />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n name1: '',\r\n name2: '',\r\n name3: '',\r\n name4: '',\r\n name5: '',\r\n name6: '',\r\n name7: '',\r\n name8: '',\r\n name9: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\nWsInputDownload以下属性和`ElInput`一致:\r\n\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------- |---------------- |---------------- |---------------------- |-------- |\r\n| type | 类型 | string | text,textarea 和其他 [原生 input 的 type 值](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types) | text |\r\n| value / v-model | 绑定值 | string / number | — | — |\r\n| maxlength | 原生属性,最大输入长度 | number | — | — |\r\n| minlength | 原生属性,最小输入长度 | number | — | — |\r\n| show-word-limit | 是否显示输入字数统计,只在 `type = \"text\"` 或 `type = \"textarea\"` 时有效 | boolean | — | false |\r\n| placeholder | 输入框占位文本 | string | — | — |\r\n| clearable | 是否可清空 | boolean | — | false |\r\n| show-password | 是否显示切换密码图标| boolean | — | false |\r\n| disabled | 禁用 | boolean | — | false |\r\n| size | 输入框尺寸,只在 `type!=\"textarea\"` 时有效 | string | medium / small / mini | — |\r\n| prefix-icon | 输入框头部图标 | string | — | — |\r\n| suffix-icon | 输入框尾部图标 | string | — | — |\r\n| rows | 输入框行数,只对 `type=\"textarea\"` 有效 | number | — | 2 |\r\n| autosize | 自适应内容高度,只对 `type=\"textarea\"` 有效,可传入对象,如,{ minRows: 2, maxRows: 6 } | boolean / object | — | false |\r\n| autocomplete | 原生属性,自动补全 | string | on, off | off |\r\n| auto-complete | 下个主版本弃用 | string | on, off | off |\r\n| name | 原生属性 | string | — | — |\r\n| readonly | 原生属性,是否只读 | boolean | — | false |\r\n| max | 原生属性,设置最大值 | — | — | — |\r\n| min | 原生属性,设置最小值 | — | — | — |\r\n| step | 原生属性,设置输入字段的合法数字间隔 | — | — | — |\r\n| resize | 控制是否能被用户缩放 | string | none, both, horizontal, vertical | — |\r\n| autofocus | 原生属性,自动获取焦点 | boolean | true, false | false |\r\n| form | 原生属性 | string | — | — |\r\n| label | 输入框关联的label文字 | string | — | — |\r\n| tabindex | 输入框的tabindex | string | - | - |\r\n| validate-event | 输入时是否触发表单的校验 | boolean | - | true |\r\n\r\n### Events\r\nWsInputDownload以下事件和`ElInput`一致:\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n|---------|--------|---------|\r\n| blur | 在 Input 失去焦点时触发 | (event: Event) |\r\n| focus | 在 Input 获得焦点时触发 | (event: Event) |\r\n| change | 仅在输入框失去焦点或用户按下回车时触发 | (value: string \\| number) |\r\n| input | 在 Input 值改变时触发 | (value: string \\| number) |\r\n| clear | 在点击由 `clearable` 属性生成的清空按钮时触发 | — |\r\n\r\n### Methods\r\n\r\n可从外部调用的方法,WsInputDownload以下方法和`ElInput`一致:\r\n\r\n| 方法名 | 说明 | 参数 |\r\n| ---- | ---- | ---- |\r\n| focus | 使 input 获取焦点 | — |\r\n| blur | 使 input 失去焦点 | — |\r\n| select | 选中 input 中的文字 | — |"
},
{
"name": "ws-material-selector",
"category": "PC端组件库",
"content": "## WeShineMaterialSelector - 素材选择组件\r\n集成了内容中心海报,普通素材,轨迹素材,微店,产品库,智能名片,商城中心小程序,抽奖小程序一系列内容素材,另外也支持上传本地图片,视频,文件等。适用于营销业务中选择素材附件等场景,如欢迎语,群发等。\r\n\r\n素材选择组件包含两个按钮,“+ 新建” 与 “+ 从素材中心中选择”按钮。页面上不需要重复实现。\r\n该组件提供了两种方式来添加素材:\r\n1. **新建**:用户可以通过点击“+ 新建”按钮来创建新的临时素材。\r\n2. **从素材中心中选择**:用户可以通过点击“+ 从素材中心中选择”按钮,从已有的素材库中选择素材。\r\n\r\n技术方案文档:[PC端素材组件](https://doc.weixin.qq.com/doc/w3_AFwAQgYkAEgW5u104IPStmj9LZFJL)\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineMaterialSelector`组件, 并在页面中注册\r\n```js\r\n\r\n<script>\r\n import {\r\n WeShineMaterialSelector,\r\n WeShineMaterialSelectorTypes\r\n } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WeShineMaterialSelector\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基础用法\r\n\r\n:::demo\r\n```html\r\n\r\n<we-shine-material-selector \r\n :material-list=\"materialList\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n materialList: [] \r\n } \r\n },\r\n methods: {\r\n onChange(val) {\r\n console.log('val', val); \r\n } \r\n } \r\n }\r\n</script>\r\n```\r\n:::\r\n\r\n### 配置可上传临时素材的类型\r\n可自由配置可上传的临时素材类型,默认为文本,图片,视频,文件,文章,网页,小程序。其中图片、视频、文件是从本地选择,文本、文章、网页、小程序是通过表单创建临时素材\r\n\r\n临时素材:当在内容中心没有满足需要的素材时,可选择从本地上传,或者通过表单的方式创建素材,通过这种方式的素材不会在内容中心中展示。\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :allow-temp-types=\"allowTempTypes\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import {\r\n WeShineMaterialSelectorTypes \r\n } from \"@wshoto/pc-base-ui\"; \r\n export default {\r\n data() {\r\n return {\r\n materialList: [], \r\n allowTempTypes: [\r\n // 文本类型\r\n WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.TEXT,\r\n // 图片类型 \r\n WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.IMAGE,\r\n ], \r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n } \r\n } \r\n }\r\n</script>\r\n```\r\n\r\n### 配置可选择的业务类型\r\n可配置业务类型(弹窗中的一级tab),默认为通用素材,组合素材。可选的有通用素材、组合素材、海报、产品库、微店、营销小程序、商城小程序\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :allow-biz-types=\"allowBizTypes\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import {\r\n WeShineMaterialSelectorTypes\r\n } from \"@wshoto/pc-base-ui\"; \r\n export default {\r\n data() {\r\n return {\r\n materialList: [],\r\n allowBizTypes: [\r\n // 通用素材\r\n WeShineMaterialSelectorTypes.BizTypeEnum.COMMON_MATERIAL,\r\n // 组合素材 \r\n WeShineMaterialSelectorTypes.BizTypeEnum.GROUP_MATERIAL,\r\n // 微店\r\n WeShineMaterialSelectorTypes.BiZTypeEnum.GROUP_MATERIAL\r\n ] \r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n } \r\n } \r\n }\r\n</script>\r\n```\r\n\r\n### 配置可选择的通用素材类型\r\n可配置通用素材下可选择的素材类型,默认为文本,图片,视频,文件,文章,网页,小程序。可选值有:文本、图片、视频、文件、文章、网页、小程序、收集表、智能名片\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :allow-material-types=\"allowMaterialTypes\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import { WeShineMaterialSelectorTypes } from '@wshoto/pc-base-ui' \r\n export default {\r\n data() {\r\n return {\r\n materialList: [],\r\n allowMaterialTypes: [\r\n // 文本\r\n WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.TEXT,\r\n // 图片 \r\n WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.IMAGE,\r\n ] \r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n } \r\n } \r\n }\r\n</script>\r\n```\r\n\r\n\r\n### 文件上传前钩子\r\n适用于本地上传图片,视频,文件时的前置校验,如校验文件大小,文件类型等\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :before-upload=\"beforeUpload\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import { WeShineMaterialSelectorTypes } from '@wshoto/pc-base-ui'\r\n export default {\r\n data() {\r\n return {\r\n materialList: []\r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n },\r\n beforeUpload(file: File) {\r\n if (file.size > 1024 * 1024 * 2) {\r\n this.$message.error('文件大小不能超过2M');\r\n return false;\r\n }\r\n return true; \r\n } \r\n } \r\n }\r\n</script>\r\n```\r\n\r\n\r\n### 选择素材前钩子\r\n适用于选择素材前的前置校验,如群发朋友圈场景下只能选择一个链接类型的素材\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :before-select=\"beforeSelect\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import { WeShineMaterialSelectorTypes } from '@wshoto/pc-base-ui' \r\n export default {\r\n data() {\r\n return {\r\n materialList: []\r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n },\r\n beforeSelect(current, list) {\r\n if (current.businessType === WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.ARTICLE && list.some(item => item.businessType === WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.ARTICLE)) {\r\n this.$message.error('当前场景仅支持选择一个文章素材');\r\n return false;\r\n }\r\n return true; \r\n } \r\n } \r\n }\r\n</script>\r\n```\r\n\r\n\r\n### 自定义配置可切换的发送形式\r\n适用于自定义当前素材可选择的发送形式,默认规则为:普通素材均只能使用普通形式;轨迹素材可使用轨迹形式或者普通形式,默认为轨迹形式。其中特殊场景有:文件大于20m、图片大于10m、excel文件只能使用普通形式,另外收集表可选择的发送形式需根据本身的业务逻辑决定。\r\n\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :send-type-decorator=\"sendTypeDecorator\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import { WeShineMaterialSelectorTypes } from '@wshoto/pc-base-ui' \r\n export default {\r\n data() {\r\n return {\r\n materialList: []\r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n },\r\n sendTypeDecorator(material: WeShineMaterialSelectorTypes.MaterialItem, defaultConfig: WeShineMaterialSelectorTypes.SendTypeDecoratorRes): WeShineMaterialSelectorTypes.SendTypeDecoratorRes {\r\n if (material.businessType === WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.COLLECTION_TABLE) {\r\n return {\r\n allowSendTypes: [WeShineMaterialSelectorTypes.SendTypeEnum.TRACK],\r\n forbiddenSendTypeTips : '当前收集表类型仅支持轨迹形式发送'\r\n }\r\n }\r\n return defaultConfig;\r\n }\r\n } \r\n }\r\n</script>\r\n```\r\n\r\n\r\n### 常用的限制性配置\r\n可配置常见的尺寸、体积限制条件\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :config=\"config\"\r\n @change=\"onChange\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script>\r\n import { WeShineMaterialSelectorTypes } from '@wshoto/pc-base-ui' \r\n export default {\r\n data() {\r\n return {\r\n materialList: [],\r\n config: {\r\n /**\r\n * 图片文件最大体积(单位为M)\r\n */\r\n imgMaxSize: 2,\r\n /**\r\n * 文件最大体积(单位为M)\r\n */\r\n fileMaxSize: 10,\r\n /**\r\n * 视频文件最大体积(单位为M)\r\n */\r\n videoMaxSize: 20,\r\n /**\r\n * 图片像素最大限制(宽 * 高)\r\n */\r\n pxTotalLimit: 1920 * 1080,\r\n /**\r\n * 视频时长限制(单位为秒)\r\n */\r\n videoDuration: 20,\r\n /**\r\n * 视频宽度限制(单位为像素)\r\n */\r\n videoWidth: 720,\r\n /**\r\n * 视频高度限制(单位为像素)\r\n */\r\n videoHeight: 360\r\n }\r\n } \r\n },\r\n methods: {\r\n onChange(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val'); \r\n }\r\n } \r\n }\r\n</script>\r\n```\r\n\r\n\r\n\r\n### props\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------|----------------------------------------------------|------------------------------------------------------------------------------------|----------|---------------------------------------|\r\n|material-list | 默认选中的素材列表 | Array\\<{ id: string, sendType?: SendTypeEnum, businessType?: BusinessTypeEnum }\\> | - | [] |\r\n|scene| 场景类型,主要用于KA定制场景,可判断此字段来决定是否需要执行定开逻辑 | String | - | - |\r\n|allow-temp-types| 支持临时上传的素材类型 | TempMaterialTypesEnum[] | - | \\[2, 3, 4, 6, 7, 8, 9\\] |\r\n|allow-biz-types | 支持选择的业务类型,如 普通素材,组合素材,海报等 | BizTypeEnum[] | - | \\['commonMaterial', 'groupMaterial'\\] |\r\n|allow-material-types | 通用素材中支持选择的素材类型 | MaterialBusinessTypeEnum[] | - | \\[2, 3, 4, 6, 7, 8, 9\\] |\r\n|text-as-material| 是否将文本视为素材(如果为false则不会占用个数的限制,仅会被当做文本字符串填充至业务中的输入框) | boolean | - | false |\r\n|max-count | 最大选择数量 | number | - | 9 |\r\n|draggable | 是否可拖拽 | boolean | - | true |\r\n|before-upload| 上传前的钩子函数(可用于校验文件大小,尺寸,时长等,仅在图片,视频,文件类型下生效) | (file: File) => (Pomise\\<boolean\\> \\| boolean) | - | - |\r\n|before-select| 勾选前的钩子,根据返回值true/false,来决定是否勾选 | (item: MaterialItem, selectedMaterialList: MaterialItem[]) => (Pomise\\<boolean\\> \\| boolean) | - | - |\r\n|send-type-decorator| 自定义发送形式配置 | (item: MaterialItem, defaultConfig: SendTypeDecoratorRes) => SendTypeDecoratorRes | - | - |\r\n|config| 常见限制性条件配置项 | CommonLimitConfig | - | { imgMaxSize: 2 } |\r\n\r\n### Events\r\n| 事件名 | 说明 | 回调参数 |\r\n|--------------|--------------------------|------|\r\n| upload-begin | 上传开始时或重试时发送此事件, 此时不可提交表单 | - |\r\n| complete | 上传完成后,发送完成事件,此时可以提交表单 | () => void |\r\n| change | 选择的素材发生变化后,发送此事件 | (list: MaterialItem[]) => void |\r\n\r\n### Methods\r\n无\r\n\r\n### Slots\r\n无\r\n\r\n### Customize 定开拓展点\r\n```ts\r\n// entry.ts\r\n{\r\n componentConfig: {\r\n // pc端素材组件\r\n PcMaterialSelectComponent: {\r\n // 可自行编排选素材弹窗一级tab,入参为当前素材组件的一级tab集合,定开可自行增删改查,重点关注:传入的component需支持v-model双向数据绑定;scene为场景值,使用选素材组件时传入的值\r\n materialBizTypeDecorate: (tabs: TabComponentItem[], scene: string) => Promise<TabComponentItem[]>,\r\n // 可自行增加从其他渠道选择素材,scene为场景值,使用选素材组件时传入的值,重点关注:传入的component需支持v-model双向数据绑定\r\n entrySlot: (scene: string) => Component\r\n }\r\n }\r\n}\r\n```\r\n\r\n### 类型定义\r\n```ts\r\n/**\r\n * 公共限制配置\r\n */\r\nexport type CommonLimitConfig = Partial<{\r\n /**\r\n * 文本最大长度,字符数非字节数\r\n */\r\n textMaxLength: number,\r\n /**\r\n * 图片文件最大体积(单位为M)\r\n */\r\n imgMaxSize: number,\r\n /**\r\n * 文件最大体积(单位为M)\r\n */\r\n fileMaxSize: number,\r\n /**\r\n * 视频文件最大体积(单位为M)\r\n */\r\n videoMaxSize: number,\r\n /**\r\n * 图片像素最大限制(宽 * 高)\r\n */\r\n pxTotalLimit: number,\r\n /**\r\n * 视频时长限制\r\n */\r\n videoDuration: number,\r\n /**\r\n * 视频宽度限制\r\n */\r\n videoWidth: number,\r\n /**\r\n * 视频高度限制\r\n */\r\n videoHeight: number\r\n}>;\r\n\r\n/**\r\n * 发送类型\r\n */\r\nexport enum SendTypeEnum {\r\n TRACK = 1, // 轨迹形式\r\n NORMAL = 2 // 普通形式\r\n}\r\n\r\n/**\r\n * 带业务属性的素材类型\r\n */\r\nexport enum MaterialBusinessTypeEnum {\r\n // 海报\r\n POSTER = 1,\r\n // 文本\r\n TEXT = 2,\r\n // 图片\r\n IMAGE = 3,\r\n // 文章\r\n ARTICLE = 4,\r\n // 语音\r\n VOICE = 5,\r\n // 视频\r\n VIDEO = 6,\r\n // 文件\r\n FILE = 7,\r\n // 小程序\r\n MIN_APP = 8,\r\n // 网页\r\n LINK = 9,\r\n // 优惠券\r\n COUPON = 10,\r\n // 商品\r\n COMMODITY = 11,\r\n // 活动\r\n ACTIVITY= 12,\r\n // 产品\r\n PRODUCT = 13,\r\n // 素材包\r\n PACKAGE = 14,\r\n // 营销页\r\n MARKETING = 15,\r\n // 收集表\r\n COLLECTION_TABLE = 16,\r\n // 上下游共享\r\n SHADING = 17,\r\n // 智能名片\r\n AI_CARD = 18,\r\n // 微店页面\r\n MICRO_STORE = 19,\r\n // 产品库\r\n PRODUCT_LIB = 23\r\n}\r\n\r\n/**\r\n * 可上传的临时素材类型\r\n */\r\nexport enum TempMaterialTypesEnum {\r\n /* 文本 */\r\n TEXT = 2,\r\n /* 图片 */\r\n IMAGE = 3,\r\n /* 文章 */\r\n ARTICLE = 4,\r\n /* 视频 */\r\n VIDEO = 6,\r\n /* 文件 */\r\n FILE = 7,\r\n /* 小程序 */\r\n MIN_APP = 8,\r\n /* 网页 */\r\n LINK = 9,\r\n}\r\n\r\n/**\r\n * 基础素材类型,对应企微api可发送的素材类型\r\n */\r\nexport enum MaterialBaseTypeEnum {\r\n /* 文本 */\r\n TEXT = 2,\r\n /* 图片 */\r\n IMAGE = 3,\r\n /* 视频 */\r\n VIDEO = 6,\r\n /* 文件 */\r\n FILE = 7,\r\n /* 小程序 */\r\n MIN_APP = 8,\r\n /* 链接 */\r\n LINK = 9,\r\n}\r\n\r\n/**\r\n * 可选择的素材大类(一级tab)\r\n */\r\nexport enum BizTypeEnum {\r\n // 通用素材\r\n COMMON_MATERIAL = 'commonMaterial',\r\n // 组合素材\r\n GROUP_MATERIAL = 'groupMaterial',\r\n // 海报\r\n POSTER = 'poster',\r\n // 商城小程序\r\n MALL_MINI_APP = 'mallMiniApp',\r\n // 抽奖小程序\r\n LOTTERY_MINI_APP = 'lotteryMiniApp',\r\n /* 产品库 */\r\n PRODUCT_LIB = 'productLib',\r\n /* 微店 */\r\n MICRO_STORE = 'microStore'\r\n}\r\n\r\n/**\r\n * 素材基础信息\r\n */\r\ninterface MaterialBaseType {\r\n /** 素材id **/\r\n id: string,\r\n /* 组合素材中子素材存在此字段,表示组合素材的id */\r\n parentId?: string,\r\n /** 文本标题 **/\r\n title: string,\r\n /* 基础媒体类型 */\r\n baseType?: MaterialBaseTypeEnum,\r\n /* 业务类型 */\r\n businessType: MaterialBusinessTypeEnum,\r\n /* 发送类型 */\r\n sendType?: SendTypeEnum,\r\n /** 素材封面 **/\r\n coverImageUrl?: string,\r\n /** 定开拓展字段 **/\r\n extensionMap?: Record<string, any>\r\n}\r\n\r\n/**\r\n * 文本素材\r\n */\r\ninterface TextItem {\r\n /* 文本内容 */\r\n plainText: string\r\n}\r\n\r\n/**\r\n * 图片\r\n */\r\ninterface ImageItem {\r\n /* 图片后缀名,不包含 . */\r\n extension: string,\r\n /* 图片全名称,包含后缀名 */\r\n name: string,\r\n /* 图片宽度 */\r\n width: number,\r\n /* 图片高度 */\r\n height: number,\r\n /* 图片尺寸 单位为B */\r\n size: number,\r\n /* 图片url */\r\n url: string\r\n}\r\n\r\n/**\r\n * 小程序\r\n */\r\ninterface MiniProgramItem {\r\n /* 小程序appId */\r\n appId: string,\r\n /* 小程序路径 */\r\n appPath: string,\r\n /* 小程序原始id */\r\n appOriginalId?: string,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 文章\r\n */\r\ninterface ArticleItem {\r\n /* 文章类型 1 - 自定义文章 3 - 公众号文章 */\r\n articleType?: 1 | 3,\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink: string,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 网页\r\n */\r\ninterface WebItem {\r\n /* 网页原始地址 */\r\n originalLink?: string,\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink: string,\r\n /* 仅用于收集表素材,1 - 轨迹形式 2 - 普通形式 3 - 轨迹形式或者普通形式 */\r\n assignSendType?: 1 | 2 | 3,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 文件\r\n */\r\ninterface FileItem {\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink?: string,\r\n /* 文件后缀名,不包含 . */\r\n extension: string,\r\n name: string,\r\n /* 文件体积,单位为B */\r\n size: number,\r\n /* 文件地址 */\r\n url: string\r\n}\r\n\r\n/**\r\n * 视频\r\n */\r\ninterface VideoItem {\r\n /* 文件后缀名,不包含 . */\r\n extension: string,\r\n /* 图片文件全名称, 包含后缀名 */\r\n name: string,\r\n /* 视频体积 单位为B */\r\n size: number,\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink?: string,\r\n /* 视频地址 */\r\n url: string,\r\n /* 视频宽度,openApi 同步过来的数据无此字段 */\r\n width?: number,\r\n /* 视频高度,openApi 同步过来的数据无此字段 */\r\n height?: number,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 海报\r\n */\r\ninterface PosterItem {\r\n url: string\r\n}\r\n\r\n/**\r\n * 产品库\r\n */\r\nexport type ProductLibItem = {\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink?: string,\r\n productCode: string;\r\n tags: Array<{ id: string; name: string }> | null;\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 聚合素材类型,不同的businessType 对应不同的素材类型\r\n */\r\nexport type MaterialItem = MaterialBaseType & ({\r\n businessType: MaterialBusinessTypeEnum.POSTER,\r\n baseType: MaterialBaseTypeEnum.IMAGE,\r\n contentPoster: PosterItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.TEXT,\r\n businessType: MaterialBusinessTypeEnum.TEXT,\r\n contentText: TextItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.IMAGE,\r\n businessType: MaterialBusinessTypeEnum.IMAGE,\r\n contentImage: ImageItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.MIN_APP,\r\n businessType: MaterialBusinessTypeEnum.MIN_APP | MaterialBusinessTypeEnum.COUPON | MaterialBusinessTypeEnum.COMMODITY | MaterialBusinessTypeEnum.ACTIVITY | MaterialBusinessTypeEnum.MARKETING,\r\n contentApp: MiniProgramItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.LINK,\r\n businessType: MaterialBusinessTypeEnum.ARTICLE,\r\n contentArticle: ArticleItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.LINK,\r\n businessType: MaterialBusinessTypeEnum.LINK | MaterialBusinessTypeEnum.COLLECTION_TABLE | MaterialBusinessTypeEnum.AI_CARD | MaterialBusinessTypeEnum.MICRO_STORE,\r\n contentLink: WebItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.FILE,\r\n businessType: MaterialBusinessTypeEnum.FILE,\r\n contentFile: FileItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.VIDEO,\r\n businessType: MaterialBusinessTypeEnum.VIDEO,\r\n contentVideo: VideoItem\r\n} | {\r\n businessType: MaterialBusinessTypeEnum.PACKAGE,\r\n contentPackage: {\r\n memberMaterialList: MaterialItem[]\r\n }\r\n} | {\r\n baseType: MaterialBaseTypeEnum.LINK,\r\n businessType: MaterialBusinessTypeEnum.PRODUCT_LIB,\r\n contentProduct: ProductLibItem\r\n});\r\n\r\n/**\r\n * 组合素材\r\n */\r\ninterface PackageItem {\r\n memberMaterialList: MaterialItem[]\r\n}\r\n\r\nexport enum StatusEnum {\r\n WAITING = 'WAITING',\r\n UPLOADING = 'UPLOADING',\r\n COMPLETED = 'COMPLETED',\r\n ERROR = 'ERROR',\r\n SUCCESS = 'SUCCESS'\r\n}\r\n\r\nexport type LocalFileOrMaterial = {\r\n file: File,\r\n localId?: string,\r\n progress: number,\r\n material: MaterialItem,\r\n status: StatusEnum\r\n};\r\n\r\n/**\r\n * 素材分类\r\n */\r\nexport type MaterialCategoryItem = {\r\n /* 分类名称 */\r\n name: string,\r\n /* 分类id */\r\n id: string,\r\n /* 子分类 */\r\n childrenCategoryList?: MaterialCategoryItem[]\r\n}\r\n\r\n/**\r\n * 发送形式配置\r\n */\r\nexport type SendTypeDecoratorRes = {\r\n /* 允许选择的发送形式列表 */\r\n allowSendTypes: SendTypeEnum[],\r\n /* 发送形式后的提示文案 */\r\n forbiddenSendTypeTips?: string\r\n}\r\n```"
},
{
"name": "ws-material-select-dialog",
"category": "PC端组件库",
"content": "## WsMaterialSelectDialog - 选素材对话框组件\r\n选素材对话框可用于选择内容中心素材,素材类型包括:海报,普通素材,轨迹素材,微店,产品库,智能名片,商城中心小程序,抽奖小程序等。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsMaterialSelectDialog`组件, 并在页面中注册\r\n```js\r\n\r\n<script>\r\n import {\r\n WsMaterialSelectDialog\r\n } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsMaterialSelectDialog\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n### 基础用法\r\n\r\n:::demo\r\n```html\r\n<ws-button @click=\"visible = true\">选素材</ws-button>\r\n<ws-material-select-dialog\r\n :visible.sync=\"visible\"\r\n :material-list=\"materialList\"\r\n @confirm=\"onConfirm\"\r\n>\r\n</ws-material-select-dialog>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: false,\r\n materialList: []\r\n }\r\n },\r\n methods: {\r\n onConfirm(val) {\r\n console.log('val', val);\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 配置可选择的业务类型\r\n可配置业务类型(弹窗中的一级tab),默认为通用素材,组合素材。可选的有通用素材、组合素材、海报、产品库、微店、营销小程序、商城小程序\r\n\r\n```html\r\n\r\n<ws-material-select-dialog\r\n :material-list=\"materialList\"\r\n :allow-biz-types=\"allowBizTypes\"\r\n @confirm=\"onConfirm\"\r\n>\r\n</ws-material-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import {\r\n WeShineMaterialSelectorTypes\r\n } from \"@wshoto/pc-base-ui\";\r\n export default Vue.extend({\r\n data() {\r\n return {\r\n materialList: [] as WeShineMaterialSelectorTypes.MaterialItem,\r\n allowBizTypes: [\r\n // 通用素材\r\n WeShineMaterialSelectorTypes.BizTypeEnum.COMMON_MATERIAL,\r\n // 组合素材 \r\n WeShineMaterialSelectorTypes.BizTypeEnum.GROUP_MATERIAL,\r\n // 微店\r\n WeShineMaterialSelectorTypes.BiZTypeEnum.MICRO_STORE\r\n ]\r\n }\r\n },\r\n methods: {\r\n onConfirm(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val');\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 配置可选择的通用素材类型\r\n可配置通用素材下可选择的素材类型,默认为文本,图片,视频,文件,文章,网页,小程序。可选值有:文本、图片、视频、文件、文章、网页、小程序、收集表、智能名片\r\n\r\n```html\r\n\r\n<ws-material-select-dialog\r\n :material-list=\"materialList\"\r\n :allow-material-types=\"allowMaterialTypes\"\r\n @confirm=\"onConfirm\"\r\n>\r\n</ws-material-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import {\r\n WeShineMaterialSelectorTypes\r\n } from \"@wshoto/pc-base-ui\";\r\n export default Vue.extend({\r\n data() {\r\n return {\r\n materialList: [] as WeShineMaterialSelectorTypes.MaterialItem,\r\n allowMaterialTypes: [\r\n // 文本\r\n WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.TEXT,\r\n // 图片 \r\n WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.IMAGE,\r\n ]\r\n }\r\n },\r\n methods: {\r\n onConfirm(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val');\r\n }\r\n }\r\n });\r\n</script>\r\n```\r\n\r\n### 选择素材前钩子\r\n适用于选择素材前的前置校验,如群发朋友圈场景下只能选择一个链接类型的素材\r\n\r\n```html\r\n\r\n<ws-material-select-dialog\r\n :material-list=\"materialList\"\r\n :before-select=\"beforeSelect\"\r\n @confirm=\"onConfirm\"\r\n>\r\n</ws-material-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import {\r\n WeShineMaterialSelectorTypes\r\n } from \"@wshoto/pc-base-ui\";\r\n export default Vue.extend({\r\n data() {\r\n return {\r\n materialList: [] as WeShineMaterialSelectorTypes.MaterialItem\r\n }\r\n },\r\n methods: {\r\n onConfirm(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val');\r\n },\r\n beforeSelect(current, list) {\r\n if (current.businessType === WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.ARTICLE && list.some(item => item.businessType === WeShineMaterialSelectorTypes.MaterialBusinessTypeEnum.ARTICLE)) {\r\n this.$message.error('当前场景仅支持选择一个文章素材');\r\n return false;\r\n }\r\n return true;\r\n }\r\n }\r\n });\r\n</script>\r\n```\r\n\r\n\r\n### 常用的限制性配置\r\n可配置常见的尺寸、体积限制条件\r\n\r\n```html\r\n\r\n<we-shine-material-selector\r\n :material-list=\"materialList\"\r\n :config=\"config\"\r\n @confirm=\"onConfirm\"\r\n>\r\n</we-shine-material-selector>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import {\r\n WeShineMaterialSelectorTypes\r\n } from \"@wshoto/pc-base-ui\";\r\n export default Vue.extend({\r\n data() {\r\n return {\r\n materialList: [] as WeShineMaterialSelectorTypes.MaterialItem,\r\n config: {\r\n /**\r\n * 图片文件最大体积(单位为M)\r\n */\r\n imgMaxSize: 2,\r\n /**\r\n * 文件最大体积(单位为M)\r\n */\r\n fileMaxSize: 10,\r\n /**\r\n * 视频文件最大体积(单位为M)\r\n */\r\n videoMaxSize: 20,\r\n /**\r\n * 图片像素最大限制(宽 * 高)\r\n */\r\n pxTotalLimit: 1920 * 1080,\r\n /**\r\n * 视频时长限制(单位为秒)\r\n */\r\n videoDuration: 20,\r\n /**\r\n * 视频宽度限制(单位为像素)\r\n */\r\n videoWidth: 720,\r\n /**\r\n * 视频高度限制(单位为像素)\r\n */\r\n videoHeight: 360\r\n }\r\n }\r\n },\r\n methods: {\r\n onConfirm(val: WeShineMaterialSelectorTypes.MaterialItem) {\r\n console.log('val');\r\n }\r\n }\r\n });\r\n</script>\r\n```\r\n\r\n\r\n\r\n### props\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------------------|----------------------------------------------------|------------------------------------------------------------------------------------|----------|---------------------------------------|\r\n| visible | 控制弹窗的显示与隐藏,需使用.sync修饰符 | boolean | - | false |\r\n| material-list | 默认选中的素材列表 | Array\\<{ id: string, sendType?: SendTypeEnum, businessType?: BusinessTypeEnum }\\> | - | [] |\r\n| scene | 场景类型,主要用于KA定制场景,可判断此字段来决定是否需要执行定开逻辑 | String | - | - |\r\n| allow-biz-types | 支持选择的业务类型,如 普通素材,组合素材,海报等 | BizTypeEnum[] | - | \\['commonMaterial', 'groupMaterial'\\] |\r\n| allow-material-types | 通用素材中支持选择的素材类型 | MaterialBusinessTypeEnum[] | - | \\[2, 3, 4, 6, 7, 8, 9\\] |\r\n| text-as-material | 是否将文本视为素材(如果为false则不会占用个数的限制,仅会被当做文本字符串填充至业务中的输入框) | boolean | - | false |\r\n| max-count | 最大选择数量 | number | - | 9 |\r\n| before-select | 勾选前的钩子,根据返回值true/false,来决定是否勾选 | (item: MaterialItem, selectedMaterialList: MaterialItem[]) => (Pomise\\<boolean\\> \\| boolean) | - | - |\r\n| config | 常见限制性条件配置项 | CommonLimitConfig | - | { imgMaxSize: 2 } |\r\n\r\n### Events\r\n| 事件名 | 说明 | 回调参数 |\r\n|--------------|--------------------------|------|\r\n| confirm | 选择的素材发生变化后,发送此事件 | (list: MaterialItem[]) => void |\r\n\r\n### Methods\r\n无\r\n\r\n### Slots\r\n无\r\n\r\n### Customize 定开拓展点\r\n```ts\r\n// entry.ts\r\n{\r\n componentConfig: {\r\n // pc端素材组件\r\n PcMaterialSelectComponent: {\r\n // 可自行编排选素材弹窗一级tab,入参为当前素材组件的一级tab集合,定开可自行增删改查,重点关注:传入的component需支持v-model双向数据绑定;scene为场景值,使用选素材组件时传入的值\r\n materialBizTypeDecorate: (tabs: TabComponentItem[], scene: string) => Promise<TabComponentItem[]>,\r\n // 可自行增加从其他渠道选择素材,scene为场景值,使用选素材组件时传入的值,重点关注:传入的component需支持v-model双向数据绑定\r\n entrySlot: (scene: string) => Component\r\n }\r\n }\r\n}\r\n```\r\n\r\n### 类型定义\r\n```ts\r\n/**\r\n * 公共限制配置\r\n */\r\nexport type CommonLimitConfig = Partial<{\r\n /**\r\n * 文本最大长度,字符数非字节数\r\n */\r\n textMaxLength: number,\r\n /**\r\n * 图片文件最大体积(单位为M)\r\n */\r\n imgMaxSize: number,\r\n /**\r\n * 文件最大体积(单位为M)\r\n */\r\n fileMaxSize: number,\r\n /**\r\n * 视频文件最大体积(单位为M)\r\n */\r\n videoMaxSize: number,\r\n /**\r\n * 图片像素最大限制(宽 * 高)\r\n */\r\n pxTotalLimit: number,\r\n /**\r\n * 视频时长限制\r\n */\r\n videoDuration: number,\r\n /**\r\n * 视频宽度限制\r\n */\r\n videoWidth: number,\r\n /**\r\n * 视频高度限制\r\n */\r\n videoHeight: number\r\n}>;\r\n\r\n/**\r\n * 发送类型\r\n */\r\nexport enum SendTypeEnum {\r\n TRACK = 1, // 轨迹形式\r\n NORMAL = 2 // 普通形式\r\n}\r\n\r\n/**\r\n * 带业务属性的素材类型\r\n */\r\nexport enum MaterialBusinessTypeEnum {\r\n // 海报\r\n POSTER = 1,\r\n // 文本\r\n TEXT = 2,\r\n // 图片\r\n IMAGE = 3,\r\n // 文章\r\n ARTICLE = 4,\r\n // 语音\r\n VOICE = 5,\r\n // 视频\r\n VIDEO = 6,\r\n // 文件\r\n FILE = 7,\r\n // 小程序\r\n MIN_APP = 8,\r\n // 网页\r\n LINK = 9,\r\n // 优惠券\r\n COUPON = 10,\r\n // 商品\r\n COMMODITY = 11,\r\n // 活动\r\n ACTIVITY= 12,\r\n // 产品\r\n PRODUCT = 13,\r\n // 素材包\r\n PACKAGE = 14,\r\n // 营销页\r\n MARKETING = 15,\r\n // 收集表\r\n COLLECTION_TABLE = 16,\r\n // 上下游共享\r\n SHADING = 17,\r\n // 智能名片\r\n AI_CARD = 18,\r\n // 微店页面\r\n MICRO_STORE = 19,\r\n // 产品库\r\n PRODUCT_LIB = 23\r\n}\r\n\r\n/**\r\n * 可上传的临时素材类型\r\n */\r\nexport enum TempMaterialTypesEnum {\r\n /* 文本 */\r\n TEXT = 2,\r\n /* 图片 */\r\n IMAGE = 3,\r\n /* 文章 */\r\n ARTICLE = 4,\r\n /* 视频 */\r\n VIDEO = 6,\r\n /* 文件 */\r\n FILE = 7,\r\n /* 小程序 */\r\n MIN_APP = 8,\r\n /* 网页 */\r\n LINK = 9,\r\n}\r\n\r\n/**\r\n * 基础素材类型,对应企微api可发送的素材类型\r\n */\r\nexport enum MaterialBaseTypeEnum {\r\n /* 文本 */\r\n TEXT = 2,\r\n /* 图片 */\r\n IMAGE = 3,\r\n /* 视频 */\r\n VIDEO = 6,\r\n /* 文件 */\r\n FILE = 7,\r\n /* 小程序 */\r\n MIN_APP = 8,\r\n /* 链接 */\r\n LINK = 9,\r\n}\r\n\r\n/**\r\n * 可选择的素材大类(一级tab)\r\n */\r\nexport enum BizTypeEnum {\r\n // 通用素材\r\n COMMON_MATERIAL = 'commonMaterial',\r\n // 组合素材\r\n GROUP_MATERIAL = 'groupMaterial',\r\n // 海报\r\n POSTER = 'poster',\r\n // 商城小程序\r\n MALL_MINI_APP = 'mallMiniApp',\r\n // 抽奖小程序\r\n LOTTERY_MINI_APP = 'lotteryMiniApp',\r\n /* 产品库 */\r\n PRODUCT_LIB = 'productLib',\r\n /* 微店 */\r\n MICRO_STORE = 'microStore'\r\n}\r\n\r\n/**\r\n * 素材基础信息\r\n */\r\ninterface MaterialBaseType {\r\n /** 素材id **/\r\n id: string,\r\n /* 组合素材中子素材存在此字段,表示组合素材的id */\r\n parentId?: string,\r\n /** 文本标题 **/\r\n title: string,\r\n /* 基础媒体类型 */\r\n baseType?: MaterialBaseTypeEnum,\r\n /* 业务类型 */\r\n businessType: MaterialBusinessTypeEnum,\r\n /* 发送类型 */\r\n sendType?: SendTypeEnum,\r\n /** 素材封面 **/\r\n coverImageUrl?: string,\r\n /** 定开拓展字段 **/\r\n extensionMap?: Record<string, any>\r\n}\r\n\r\n/**\r\n * 文本素材\r\n */\r\ninterface TextItem {\r\n /* 文本内容 */\r\n plainText: string\r\n}\r\n\r\n/**\r\n * 图片\r\n */\r\ninterface ImageItem {\r\n /* 图片后缀名,不包含 . */\r\n extension: string,\r\n /* 图片全名称,包含后缀名 */\r\n name: string,\r\n /* 图片宽度 */\r\n width: number,\r\n /* 图片高度 */\r\n height: number,\r\n /* 图片尺寸 单位为B */\r\n size: number,\r\n /* 图片url */\r\n url: string\r\n}\r\n\r\n/**\r\n * 小程序\r\n */\r\ninterface MiniProgramItem {\r\n /* 小程序appId */\r\n appId: string,\r\n /* 小程序路径 */\r\n appPath: string,\r\n /* 小程序原始id */\r\n appOriginalId?: string,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 文章\r\n */\r\ninterface ArticleItem {\r\n /* 文章类型 1 - 自定义文章 3 - 公众号文章 */\r\n articleType?: 1 | 3,\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink: string,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 网页\r\n */\r\ninterface WebItem {\r\n /* 网页原始地址 */\r\n originalLink?: string,\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink: string,\r\n /* 仅用于收集表素材,1 - 轨迹形式 2 - 普通形式 3 - 轨迹形式或者普通形式 */\r\n assignSendType?: 1 | 2 | 3,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 文件\r\n */\r\ninterface FileItem {\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink?: string,\r\n /* 文件后缀名,不包含 . */\r\n extension: string,\r\n name: string,\r\n /* 文件体积,单位为B */\r\n size: number,\r\n /* 文件地址 */\r\n url: string\r\n}\r\n\r\n/**\r\n * 视频\r\n */\r\ninterface VideoItem {\r\n /* 文件后缀名,不包含 . */\r\n extension: string,\r\n /* 图片文件全名称, 包含后缀名 */\r\n name: string,\r\n /* 视频体积 单位为B */\r\n size: number,\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink?: string,\r\n /* 视频地址 */\r\n url: string,\r\n /* 视频宽度,openApi 同步过来的数据无此字段 */\r\n width?: number,\r\n /* 视频高度,openApi 同步过来的数据无此字段 */\r\n height?: number,\r\n /* 摘要 */\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 海报\r\n */\r\ninterface PosterItem {\r\n url: string\r\n}\r\n\r\n/**\r\n * 产品库\r\n */\r\nexport type ProductLibItem = {\r\n /* 普通形式预览地址 */\r\n normalPreviewLink?: string,\r\n /* 轨迹形式预览地址 */\r\n trackPreviewLink?: string,\r\n productCode: string;\r\n tags: Array<{ id: string; name: string }> | null;\r\n summary?: string\r\n}\r\n\r\n/**\r\n * 聚合素材类型,不同的businessType 对应不同的素材类型\r\n */\r\nexport type MaterialItem = MaterialBaseType & ({\r\n businessType: MaterialBusinessTypeEnum.POSTER,\r\n baseType: MaterialBaseTypeEnum.IMAGE,\r\n contentPoster: PosterItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.TEXT,\r\n businessType: MaterialBusinessTypeEnum.TEXT,\r\n contentText: TextItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.IMAGE,\r\n businessType: MaterialBusinessTypeEnum.IMAGE,\r\n contentImage: ImageItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.MIN_APP,\r\n businessType: MaterialBusinessTypeEnum.MIN_APP | MaterialBusinessTypeEnum.COUPON | MaterialBusinessTypeEnum.COMMODITY | MaterialBusinessTypeEnum.ACTIVITY | MaterialBusinessTypeEnum.MARKETING,\r\n contentApp: MiniProgramItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.LINK,\r\n businessType: MaterialBusinessTypeEnum.ARTICLE,\r\n contentArticle: ArticleItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.LINK,\r\n businessType: MaterialBusinessTypeEnum.LINK | MaterialBusinessTypeEnum.COLLECTION_TABLE | MaterialBusinessTypeEnum.AI_CARD | MaterialBusinessTypeEnum.MICRO_STORE,\r\n contentLink: WebItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.FILE,\r\n businessType: MaterialBusinessTypeEnum.FILE,\r\n contentFile: FileItem\r\n} | {\r\n baseType: MaterialBaseTypeEnum.VIDEO,\r\n businessType: MaterialBusinessTypeEnum.VIDEO,\r\n contentVideo: VideoItem\r\n} | {\r\n businessType: MaterialBusinessTypeEnum.PACKAGE,\r\n contentPackage: {\r\n memberMaterialList: MaterialItem[]\r\n }\r\n} | {\r\n baseType: MaterialBaseTypeEnum.LINK,\r\n businessType: MaterialBusinessTypeEnum.PRODUCT_LIB,\r\n contentProduct: ProductLibItem\r\n});\r\n\r\n/**\r\n * 组合素材\r\n */\r\ninterface PackageItem {\r\n memberMaterialList: MaterialItem[]\r\n}\r\n\r\nexport enum StatusEnum {\r\n WAITING = 'WAITING',\r\n UPLOADING = 'UPLOADING',\r\n COMPLETED = 'COMPLETED',\r\n ERROR = 'ERROR',\r\n SUCCESS = 'SUCCESS'\r\n}\r\n\r\nexport type LocalFileOrMaterial = {\r\n file: File,\r\n localId?: string,\r\n progress: number,\r\n material: MaterialItem,\r\n status: StatusEnum\r\n};\r\n\r\n/**\r\n * 素材分类\r\n */\r\nexport type MaterialCategoryItem = {\r\n /* 分类名称 */\r\n name: string,\r\n /* 分类id */\r\n id: string,\r\n /* 子分类 */\r\n childrenCategoryList?: MaterialCategoryItem[]\r\n}\r\n\r\n/**\r\n * 发送形式配置\r\n */\r\nexport type SendTypeDecoratorRes = {\r\n /* 允许选择的发送形式列表 */\r\n allowSendTypes: SendTypeEnum[],\r\n /* 发送形式后的提示文案 */\r\n forbiddenSendTypeTips?: string\r\n}\r\n```"
},
{
"name": "ws-line",
"category": "PC端组件库",
"content": "## WsLine - 折线图\r\n\r\n折线图组件,基于 G2 二次封装。常用于详情、统计界面,实现数据可视化\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsLine`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WsLine} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsLine\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-line :params=\"chartParams\"></ws-line>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/06',\r\n count: 100\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/07',\r\n count: 85\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 多组数据\r\n支持多种数据来源和数据变换,以应对不同的数据源来源\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <div>\r\n <el-button\r\n type=\"primary\"\r\n style=\"margin-bottom: 20px;\"\r\n @click=\"chartParams=createParams(['新增客户数', '新增客户群数', '新增群聊数'], 7)\">切换数据</el-button>\r\n <ws-line :params=\"chartParams\"></ws-line>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: []\r\n };\r\n },\r\n created() {\r\n this.chartParams = this.createParams(['新增客户数', '新增客户群数', '新增群聊数'], 7);\r\n },\r\n methods: {\r\n createParams(types, count) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = '2023/10/1' + index;\r\n types.forEach(type => {\r\n const yCount = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, type, count: index === count - 1 ? 100 : yCount });\r\n });\r\n }\r\n return result;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 线条样式\r\n通过 smooth 属性指定 折线图 的线条样式。smooth为 `true` 时,则绘制直线连接的折线图;smooth为 `false` 时,则绘制平滑曲线的折线图\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-line :params=\"chartParams\" :smooth=\"false\"></ws-line>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/06',\r\n count: 100\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/07',\r\n count: 85\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 描点样式\r\n通过 point 属性指定 折线图 描点展示。point为 `true` 时,折线图 展示描点;point为 `false` 时,折线图组件不展示描点\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-line :params=\"chartParams\" point></ws-line>\r\n</template>\r\n\r\n<script>\r\n\r\nexport default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/06',\r\n count: 100\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/07',\r\n count: 85\r\n }\r\n ]\r\n };\r\n }\r\n};\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 格式化X轴,Y轴文本\r\n通过 xFormatter、yFormatter 属性格式化文本。其中xFormatter格式化 `x` 轴;yFormatter格式化 `y` 轴\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <div>\r\n <el-button\r\n type=\"primary\"\r\n style=\"margin-bottom: 20px;\"\r\n @click=\"chartParams=createParams(['新增客户数'], 7)\">切换数据</el-button>\r\n <ws-line :params=\"chartParams\" :xFormatter=\"xFormatter\" :yFormatter=\"yFormatter\"></ws-line>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: []\r\n };\r\n },\r\n created() {\r\n this.chartParams = this.createParams(['新增客户数'], 7);\r\n },\r\n methods: {\r\n createParams(types, count) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = '2023/10/1' + index;\r\n types.forEach(type => {\r\n const yCount = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, type, count: index === count - 1 ? 100 : yCount });\r\n });\r\n }\r\n return result;\r\n },\r\n xFormatter(text) {\r\n return text + '格式化';\r\n },\r\n\r\n yFormatter(text) {\r\n return text + 'k';\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 设置滚动条\r\n通过 scrollbar 属性设置滚动条的展示。当显示区域大小不足以容纳全部信息时,可以将超出部分隐藏,并通过滚动条的横向滑动来显示出被隐藏部分\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <div>\r\n <el-button\r\n type=\"primary\"\r\n style=\"margin-bottom: 20px;\"\r\n @click=\"chartParams=createParams(['新增客户数'], 60)\">切换数据</el-button>\r\n <ws-line :params=\"chartParams\" scrollbar></ws-line>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: []\r\n };\r\n },\r\n created() {\r\n this.chartParams = this.createParams(['新增客户数'], 60);\r\n },\r\n methods: {\r\n createParams(types, count) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = `第${index + 1}天`;\r\n types.forEach(type => {\r\n const yCount = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, type, count: index === count - 1 ? 100 : yCount });\r\n });\r\n }\r\n return result;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 点击事件\r\n通过 clickEvents 属性指定 折线图 点击事件。clickEvents为 `true` 时 ,鼠标移至 折线图 后会有手势样式,且点击 折线图 时tooltipClick事件会生效\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-line :params=\"chartParams\" clickEvents @tooltipClick=\"tooltipClick\"></ws-line>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/06',\r\n count: 100\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/07',\r\n count: 85\r\n }\r\n ]\r\n };\r\n },\r\n methods: {\r\n tooltipClick(params) {\r\n console.log(params);\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 高级使用\r\n- yCount - y轴刻度点的个数\r\n- rate - y轴展示百分比\r\n- height - 设置折线图可视区域高度\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-line :params=\"chartParams\" :yCount=\"5\" rate :height=\"300\"></ws-line>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------|------------|--------------------------|-------|-------|\r\n| params | 展示的数据 | ParamsNode[] | - | - |\r\n| smooth | 线条是否是曲线 | boolean | - | true |\r\n| point | 是否描绘数据点 | boolean | - | false |\r\n| scrollbar | 是否需要展示滚动条 | boolean | - | false |\r\n| height | 图表canvas高度 | number | - | 450 |\r\n| rate | y轴是否展示百分比 | boolean | - | false |\r\n| yCount | y轴刻度(含0) | number | - | 6 |\r\n| xFormatter | 格式化x轴名称 | (text: string) => string | - | - |\r\n| yFormatter | 格式化y轴名称 | (text: string) => string | - | - |\r\n| clickEvents | 是否需要点击趋势图事件、以及手势样式 | boolean | - | false |\r\n\r\n\r\n### ParamsNode Attributes\r\n\r\n| 参数名 | 说明 | 类型 |\r\n|-------|------|--------|\r\n| type | 数据类型 | string |\r\n| xName | x轴名称 | string |\r\n| count | y轴数值 | number |\r\n\r\n### Events\r\n| 事件名称 | 说明 | 参数 |\r\n|--------------|-----------------------------------|----|\r\n| tooltipClick | 点击趋势图事件(只有当clickEvents为true时才会触发) | - |\r\n\r\n### Methods\r\n\r\n| 名称 | 说明 | 参数 |\r\n|---------|--------------|---------------|\r\n| publicChangeSize | 用于更改组件的宽度 | number |"
},
{
"name": "tag-select-dialog",
"category": "PC端组件库",
"content": "## TagSelectDialog - 标签选择器对话框\r\n\r\n标签选择器对话框组件用以从对话框中展示的标签中选择想要的标签,常用于业务中的标签筛选场景,给客户打标签等场景。\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`TagSelectDialog`组件, 并在组件中注册\r\n\r\n```js\r\n\r\n<script>\r\n import { TagSelectDialog } from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n TagSelectDialog\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n`type`属性为\"业务类型\"; `title`属性为\"对话框标题\"; `usage`属性为\"标签用途\",`isRadioGroup`属性为\"是否显示筛选条件\",当配置了`isRadioGroup`为`false`后,标签选择器上方不会出现筛选条件,`confirm`回调事件为确认按钮回调事件。\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <el-card class=\"box-card tag-box\">\r\n <div slot=\"header\" class=\"clearfix\">\r\n <ws-button @click=\"showTagSelectDialog\">打开标签弹框</ws-button>\r\n <ws-button @click=\"tagList = []\">清空</ws-button>\r\n\r\n <TagSelectDialog\r\n ref=\"TagSelectDialog\"\r\n type=\"business\"\r\n title=\"打标签示例\"\r\n usage='MARK_TAG'\r\n :isRadioGroup=\"false\"\r\n :hasRadioGroupAndTagGroup=\"true\"\r\n @confirm=\"handleConfirmTag\"\r\n />\r\n \r\n </div>\r\n\r\n <div v-for=\"v in tagList\" :key=\"v\" style=\"margin-bottom: 10px;\">\r\n <el-tag>{{ v.tagName }}</el-tag>\r\n </div>\r\n </el-card>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tagList: [],\r\n cropTagList: [],\r\n businessTagList: [],\r\n selectedNoAuthBusinessTagList: [],\r\n selectedNoAuthInnerTagList: []\r\n };\r\n },\r\n methods: {\r\n showTagSelectDialog() {\r\n this.$nextTick(() => {\r\n const corpTagIds = this.cropTagList.map(tag => tag.tagId);\r\n const businessTagIds = this.businessTagList.map(tag => tag.tagId);\r\n const noAuthBusinessTagIds = this.selectedNoAuthBusinessTagList.map(tag => tag.tagId);\r\n (this.$refs.TagSelectDialog).businessInit(corpTagIds, businessTagIds, noAuthBusinessTagIds);\r\n });\r\n },\r\n handleConfirmTag({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }) {\r\n this.cropTagList = [...(cropTagList || [])];\r\n this.businessTagList = [...(businessTagList || [])];\r\n this.selectedNoAuthBusinessTagList = [...(noAuthBusinessTagList || [])];\r\n this.tagList = [...this.cropTagList, ...this.businessTagList, ...this.selectedNoAuthBusinessTagList];\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 标签使用场景区分-打标签场景,筛选标签场景\r\n`usage`属性可以用来区分打标签场景或者筛选场景,服务端会根据该参数返回不同权限范围内的标签,它支持两个值:`SEARCH`和`MARK_TAG`,默认为`SEARCH`。\r\n\r\n```html\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog1\"\r\n type=\"business\"\r\n title=\"打标签示例\"\r\n usage='MARK_TAG'\r\n :isFilterBusinessTag=\"true\"\r\n @confirm=\"handleConfirmTag\"\r\n/>\r\n\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog2\"\r\n type=\"business\"\r\n title=\"筛选标签示例\"\r\n usage='SEARCH'\r\n :isFilterBusinessTag=\"true\"\r\n :isRadioGroup=\"true\"\r\n @confirm=\"handleConfirmFilterTag\"\r\n/>\r\n\r\n<script>\r\n import { TagSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n \r\n export default {\r\n data() {\r\n return {\r\n tagIds: [] as string[],\r\n labelType: 1,\r\n tagList: [] as TagSelectDialogTypes.Tags,\r\n filterTagList: [] as TagSelectDialogTypes.Tags\r\n };\r\n },\r\n methods: {\r\n showTagSelectDialog() {\r\n this.$nextTick(() => {\r\n (this.$refs.TagSelectDialog1).businessInit(this.tagList.map(e => e.tagId));\r\n });\r\n },\r\n showTagSelectFilterDialog() {\r\n this.$nextTick(() => {\r\n (this.$refs.TagSelectDialog2).businessInit(this.filterTagList.map(e => e.tagId));\r\n });\r\n },\r\n handleConfirmTag({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.tagList = [...(cropTagList || [])];\r\n this.labelType = radio;\r\n },\r\n handleConfirmFilterTag({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.filterTagList = [...(cropTagList || [])];\r\n this.labelType = radio;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n### 配置不同的标签选择业务类型\r\n`type`属性可以用来区分标签的业务类型,传不一样的`type`对话框的数据源会不一样,`type`支持三个值,客户标签`customer`(已废弃), 客户群标签`group`, 业务标签`business`,具体需要根据需求场景来明确指定,默认为`customer`客户标签,所以一般情况下请传入具体类型。需要注意类型不一样,回显时组件接收值的方法和确定回调时返回的值是不一样的。如果`type`为`business`,需要调用`businessInit`方法回显已选标签,其余type则调用`init`方法;且`confirm`回调中,如果`type`为`business`,回调参数为各类型标签数组+radio的组合返回,其他type则返回的为`list`+`radio`的组合,具体可参考下方的示例的取值。\r\n\r\n```html\r\n\r\n<!-- business为企业标签+业务标签场景,通过isFilterBusinessTag过滤业务标签 -->\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog1\"\r\n type=\"business\"\r\n title=\"过滤业务标签\"\r\n :isFilterBusinessTag=\"true\"\r\n @confirm=\"handleConfirmTag1\"\r\n/>\r\n\r\n<!-- business为企业标签+业务标签场景 -->\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog2\"\r\n type=\"business\"\r\n title=\"选择业务标签\"\r\n @confirm=\"handleConfirmTag2\"\r\n/>\r\n\r\n<!-- business为群标签场景 -->\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog3\"\r\n type=\"group\"\r\n title=\"筛选群标签\"\r\n @confirm=\"handleConfirmTag3\"\r\n/>\r\n\r\n<script>\r\n import { TagSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n \r\n export default {\r\n data() {\r\n return {\r\n tagIds: [] as string[],\r\n labelType1: 1,\r\n labelType2: 1,\r\n labelType3: 1,\r\n tagList1: [] as TagSelectDialogTypes.Tags,\r\n tagList2: [] as TagSelectDialogTypes.Tags,\r\n tagList3: [] as TagSelectDialogTypes.Tags,\r\n cropTagList: [] as TagSelectDialogTypes.Tags,\r\n businessTagList: [] as TagSelectDialogTypes.Tags,\r\n selectedNoAuthBusinessTagList: [] as selectedNoAuthBusinessTagListTypes[]\r\n };\r\n },\r\n methods: {\r\n showTagSelectDialog1() {\r\n this.$nextTick(() => {\r\n (this.$refs.TagSelectDialog1).businessInit(this.tagList.map(e => e.tagId));\r\n });\r\n },\r\n showTagSelectDialog2() {\r\n this.$nextTick(() => {\r\n /**\r\n * 业务标签(business) 初始化方法\r\n * businessInit接受的参数如下\r\n * @param {string[]} corpCheckVal - 企业标签选中 list\r\n * @param {string[]} businessCheckVal - 业务标签选中 list\r\n * @param {string[]} noAuthBusinessCheckVal - 无权限业务标签选中 list\r\n * @param {number} radio - 选中 radio\r\n * @param {boolean} reset - 是否重置(重新请求接口数据 - 由于多个调用一个组件扩展能力)\r\n */\r\n const corpTagIds = this.cropTagList.map(tag => tag.tagId);\r\n const businessTagIds = this.businessTagList.map(tag => tag.tagId);\r\n const noAuthBusinessTagIds = this.selectedNoAuthBusinessTagList.map(tag => tag.tagId);\r\n (this.$refs.TagSelectDialog2 as InstanceType<typeof TagSelectDialog>).businessInit(corpTagIds, businessTagIds, noAuthBusinessTagIds);\r\n });\r\n },\r\n showTagSelectDialog3() {\r\n this.$nextTick(() => {\r\n /**\r\n * 客户标签(customer) or 客户群标签(group) 初始化方法\r\n * init接受的参数如下\r\n * @param {string[]} checkVal - 选中 list\r\n * @param {number} radio - 选中 radio\r\n * @param {string[]} disabledVal - 禁用 list\r\n */\r\n (this.$refs.TagSelectDialog3).init(this.tagList3.map(e => e.tagId));\r\n });\r\n },\r\n handleConfirmTag1({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.tagList1 = [...(cropTagList || [])];\r\n this.labelType1 = radio;\r\n },\r\n handleConfirmTag2({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.cropTagList = [...(cropTagList || [])];\r\n this.businessTagList = [...(businessTagList || [])];\r\n this.selectedNoAuthBusinessTagList = [...(noAuthBusinessTagList || [])];\r\n this.labelType2 = radio;\r\n },\r\n handleConfirmTag3({ list = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.tagList3 = [...(list || [])];\r\n this.labelType3 = radio;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n### 标签选择器关于上方筛选器和标签组条件筛选的场景列举\r\n\r\n在标签筛选场景中,有三种不一样的组合方式,分别由`isRadioGroup`, `isTagGroups`和`hasRadioGroupAndTagGroup`三个属性来分开或者组合控制。属性`isRadioGroup`来控制上方的筛选项展示与否,属性`isRadioGroup`用来控制当前场景下为标签组的筛选场景,确定回调时每一项标签还会传回标签组的id,这与普通的类型返回是不一样的,要注意,配置了`isTagGroups`的情况下,`isRadioGroup`属性不再生效,这两个在业务中互斥的。如果想要标签组筛选和筛选项同时展示,则使用第三种属性`hasRadioGroupAndTagGroup`,注意在配置`isRadioGroup`为`true`的情况下同时配置`hasRadioGroupAndTagGroup`,则上方筛选项会有四种选择,其中会包含一种整合了标签组的筛选项,具体可根据需求来调整传参数。\r\n\r\n```html\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog1\" \r\n type=\"business\" \r\n :isTagGroups=\"true\" \r\n :isFilterBusinessTag=\"true\"\r\n @confirm=\"handleConfirmTag1\"\r\n/>\r\n\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog2\"\r\n type=\"business\"\r\n :isRadioGroup=\"true\"\r\n :isFilterBusinessTag=\"true\"\r\n @confirm=\"handleConfirmTag2\"\r\n/>\r\n\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog3\"\r\n type=\"business\"\r\n :isRadioGroup=\"true\"\r\n :isFilterBusinessTag=\"true\"\r\n :hasRadioGroupAndTagGroup=\"true\"\r\n @confirm=\"handleConfirmTag3\"\r\n/>\r\n\r\n\r\n<script>\r\n import { TagSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n\r\n export default {\r\n data() {\r\n return {\r\n tagIds: [] as string[],\r\n labelType1: 1,\r\n labelType2: 1,\r\n labelType3: 1,\r\n tagList1: [] as TagSelectDialogTypes.Tags,\r\n tagList2: [] as TagSelectDialogTypes.Tags,\r\n tagList3: [] as TagSelectDialogTypes.Tags\r\n };\r\n },\r\n methods: {\r\n showTagSelectDialog1() {\r\n this.$nextTick(() => {\r\n (this.$refs.TagSelectDialog1 as InstanceType<typeof TagSelectDialog>).businessInit(this.tagList.map(e => e.tagId));\r\n });\r\n },\r\n showTagSelectDialog2() {\r\n this.$nextTick(() => {\r\n (this.$refs.TagSelectDialog2 as InstanceType<typeof TagSelectDialog>).businessInit(this.tagList2.map(e => e.tagId));\r\n });\r\n },\r\n showTagSelectDialog3() {\r\n this.$nextTick(() => {\r\n (this.$refs.TagSelectDialog3 as InstanceType<typeof TagSelectDialog>).businessInit(this.tagList3.map(e => e.tagId));\r\n });\r\n },\r\n handleConfirmTag1({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.tagList1 = [...(cropTagList || [])];\r\n this.labelType1 = radio;\r\n },\r\n handleConfirmTag2({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.tagList2 = [...(cropTagList || [])];\r\n this.labelType2 = radio;\r\n },\r\n handleConfirmTag3({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.tagList3 = [...(cropTagList || [])];\r\n this.labelType3 = radio;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 未授权标签的回显场景\r\n在进行打标签的操作场景时,可能会有从接口拿的标签对于当前登录人已经没有操作权限了,但是由于要回显该标签,只能由业务通过组件将这些标签通过属性`selectedNoAuthInnerTagList`传入组件中,或者通过`businessInit`初始化已选标签,组件会进行分类整合回显,且在操作时提供相应的文案。`selectedNoAuthInnerTagList`用于无权限的内部标签的回显,注意是内部标签,不要与业务标签想混合。无权限的业务标签使用`businessInit`方法传参来回显。\r\n\r\n```html\r\n<TagSelectDialog\r\n ref=\"TagSelectDialog\" \r\n type=\"business\"\r\n :selectedNoAuthInnerTagList=\"selectedNoAuthInnerTagList\"\r\n @confirm=\"handleConfirmTag\"\r\n/>\r\n\r\n<script>\r\n import { TagSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n\r\n interface selectedNoAuthBusinessTagListTypes extends TagSelectDialogTypes.Tag {\r\n groupId: string;\r\n groupName: string;\r\n manageGroupName: string\r\n }\r\n\r\n interface selectedNoAuthInnerTagListTypes extends TagSelectDialogTypes.Tag {\r\n tagGroupName: string;\r\n type: number;\r\n tips?: string;\r\n }\r\n \r\n export default {\r\n data() {\r\n return {\r\n cropTagList: [] as TagSelectDialogTypes.Tags,\r\n businessTagList: [] as TagSelectDialogTypes.Tags,\r\n selectedNoAuthBusinessTagList: [] as selectedNoAuthBusinessTagListTypes[],\r\n selectedNoAuthInnerTagList: [] as selectedNoAuthBusinessTagListTypes[],\r\n };\r\n },\r\n methods: {\r\n showTagSelectDialog() {\r\n this.$nextTick(() => {\r\n const corpTagIds = this.cropTagList.map(tag => tag.tagId);\r\n const businessTagIds = this.businessTagList.map(tag => tag.tagId);\r\n const noAuthBusinessTagIds = this.selectedNoAuthBusinessTagList.map(tag => tag.tagId);\r\n (this.$refs.TagSelectDialog as InstanceType<typeof TagSelectDialog>).businessInit(corpTagIds, businessTagIds, noAuthBusinessTagIds);\r\n });\r\n },\r\n handleConfirmTag({ cropTagList = [], businessTagList = [], noAuthBusinessTagList = [], radio }: TagSelectDialogTypes.TagSelectResult) {\r\n this.cropTagList = [...(cropTagList || [])];\r\n this.businessTagList = [...(businessTagList || [])];\r\n this.selectedNoAuthBusinessTagList = [...(noAuthBusinessTagList || [])];\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|--------------------------------------|------------------------------------------------------------------------------------|-----------------------------------|-----------------|-----------|\r\n| title | Dialog 的标题 | string | - | 选择标签 |\r\n| limit | 标签选择的限制,最多选择标签数量 | number | - | - |\r\n| isRadioGroup | 是否显示筛选条件 | boolean | - | false |\r\n| type | 业务标签类型,客户(群)标签: 原客户标签(customer,已弃用,请配置business), 客户群标签(group), 企业标签+业务标签(business) | string | business, group | customer |\r\n| isClue | 线索标识 | boolean | - | false |\r\n| isFilterAuto | 是否过滤自动标签 | boolean | - | false |\r\n| isToppingAuto | 是否置顶自动标签 | boolean | - | false |\r\n| isTagGroups | 是否标签组(目前群发4.0业务使用) | boolean | - | false |\r\n| isFilterBusinessTag | 是否过滤业务标签 | boolean | - | false |\r\n| businessTagRange | 业务标签查询范围 1: 我是管理员“的规则组标签, 2: 我所在管理组的 规则组标签, 3: 全部管理组的业务标签, 4: 带权限查询全部管理组标签 | number | 1,2,3,4 | 0 |\r\n| userId | 查询 userId 管理组业务标签 | string | - | - |\r\n| hasRadioGroupAndTagGroup (v3.0.15支持) | 是否同时存在筛选条件和标签组 (只能在类型为业务标签时使用: type = business) | boolean | - | false |\r\n| radioGroupRender (v3.0.17支持) | 标签关系(且,或,无,同组或,异组且)的渲染函数 (只能在类型为业务标签时使用: type = business) | RadioGroupRenderFunction(见下文) | - | - |\r\n| isFilterInnerTag | 是否过滤内部标签(某些场景下,需要单独过滤内部标签,例如群发朋友圈) | Boolean | false | - |\r\n| usage | 标签场景(MARK_TAG: 打标签,SEARCH:搜索标签),默认为搜索标签场景 | String | SEARCH | - |\r\n| selectedNoAuthInnerTagList | 无权限的内部标签 - 回显 | Array\\<selectedNoAuthInnerTagListTypes\\> | [] | - |\r\n| selectedNoAuthBusinessTagList | 无权限的业务标签 - 回显 | Array\\<selectedNoAuthBusinessTagListTypes\\> | [] | - |\r\n| platform | 用于处理群发等特殊筛选场景,后端通过该值处理 (SCRM:群发等特殊场景,其余默认为空字符串),非明确指出不要使用 | string | '' | 'SCRM'/'' |\r\n| scene | 使用场景, 用于KA在组件内区别场景并替换 | string | - | - |\r\n\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n|---------|----------|-----------------------------------------------------------------------------------------|\r\n| confirm | 点击确定触发事件 | { list, cropTagList, businessTagList, noAuthBusinessTagList, radio } as TagSelectResult |\r\n\r\n#### TagSelectResult\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|-----------------------|-----------|------------------|\r\n| list | Tag[] | 选中 ID 集合 |\r\n| cropTagList | Tag[] | 选中企业标签 ID 集合 |\r\n| businessTagList | Tag[] | 选中业务标签 ID 集合 |\r\n| noAuthBusinessTagList | Tag[] | 选中无权限的业务标签 ID 集合 |\r\n| radio | 1 \\| 2 \\| 3\\| 4 | 选中 radio 类型 |\r\n| tagGroups | TagGroup[] | 选中标签组 |\r\n\r\n#### Tag\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|---------|--------|-------|\r\n| tagId | string | 标签 ID |\r\n| tagName | string | 标签名称 |\r\n| order | number | 标签排序 |\r\n\r\n#### TagGroup\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|------------|--------|-------------------------------------|\r\n| tagId | string | 标签 ID |\r\n| tagName | string | 标签名称 |\r\n| order | number | 标签排序 |\r\n| tagGroupId | string | 标签组 ID |\r\n| strategyId | string | 业务标签组 ID(可选)如果为空则代表这个标签组不从属于某一个具体业务 |\r\n\r\n#### selectedNoAuthInnerTagListTypes\r\nselectedNoAuthInnerTagListTypes 数据类型是在 Tag 基础上扩展\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|--------------|--------|------------------------------------|\r\n| tagId | string | 标签 ID |\r\n| tagName | string | 标签名称 |\r\n| tagGroupName | string | 标签组名称 |\r\n| tagType | string | 标签更细致分类,如\"INTERIOR_TAG\",\"CORP_TAG\" |\r\n| tips | string | 点击该标签时,提示反馈文案 |\r\n\r\n#### radioGroupRender\r\n```typescript\r\nenum TAG_CHOICE_TYPES_ENUM {\r\n /** 满足任意一个标签 */\r\n SOME = 1,\r\n /** 同时满足所选标签 */\r\n EVERY = 2,\r\n /** 满足所选标签“同组为或、异组为且” */\r\n RELATION_WITH_GROUP = 4,\r\n /** 无标签 */\r\n NONE = 3\r\n}\r\n\r\ntype RadioItem = {\r\n // radio绑定的值\r\n value: TAG_CHOICE_TYPES_ENUM,\r\n // radio渲染的文案\r\n label: string,\r\n // 是否禁用\r\n disabled?: boolean,\r\n // 鼠标hover的提示文案\r\n hoverTips?: string\r\n}\r\n\r\ntype RadioGroupRenderFunction = (radioList: TagChoiceType[]) => TagChoiceType[];\r\n```"
},
{
"name": "ws-dialog",
"category": "PC端组件库",
"content": "## WsDialog - 对话框组件\r\n\r\n### 组件说明\r\n基于 ElDialog 组件封装,保留其所有能力,区别在于统一组件样式(如:标题样式、间距宽度),且对内容高度进行了自适应处理。\r\n\r\n### 功能\r\n- 对话框\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsDialog`组件, 并在页面中注册\r\n\r\n```html\r\n<script>\r\n import { WsDialog } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsDialog\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n\r\n### 基本使用\r\n:::demo 对于对话框的宽度,优先考虑`size`属性\r\n```html\r\n\r\n<template>\r\n <ws-button type=\"text\" @click=\"dialogVisible = true\">点击打开对话框</ws-button>\r\n\r\n <ws-dialog title=\"对话框标题\" size=\"large\" :visible.sync=\"dialogVisible\">\r\n <p>内容</p>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <ws-button @click=\"dialogVisible = !dialogVisible\">取 消</ws-button>\r\n <ws-button type=\"primary\">确 定</ws-button>\r\n </div>\r\n </ws-dialog>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n dialogVisible: false\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 内容高度自适应\r\n当auto-content属性为true时,会给dialog的`body`区域添加`overflow-y: auto`,并设置`max-height: 640px`的样式(笔记本屏幕下或屏幕尺寸像素高度为750px以下时,最大高度是440px),以实现内容高度自适应。\r\n\r\n:::demo\r\n```html\r\n\r\n<template>\r\n <ws-button type=\"text\" @click=\"dialogVisible = true\">点击打开对话框</ws-button>\r\n <ws-dialog title=\"内容溢出\" :visible.sync=\"dialogVisible\">\r\n <p v-for=\"item in new Array(40)\">内容</p>\r\n <div slot=\"footer\" class=\"dialog-footer\">\r\n <ws-button @click=\"dialogVisible = false\">取 消</ws-button>\r\n <ws-button type=\"primary\" @click=\"dialogVisible = false\">确 定</ws-button>\r\n </div>\r\n </ws-dialog>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n dialogVisible: false\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --- | --- | --- |---------------| --- |\r\n| width | 对话框组件宽度,优先于 size 属性 | string | — | — |\r\n| size | 对话框组件尺寸,默认的宽度尺寸:small: 400px、large: 960px,在设置 width 属性时,此属性无效 | string | small / large | small |\r\n| auto-content | 是否对 body 内容进行自适应处理 | boolean | — | true |\r\n| border | 是否对 body 内容添加上下边框 | boolean | — | false |\r\n| visible | 是否显示 Dialog,支持 .sync 修饰符 | boolean | — | false |\r\n| title | Dialog 的标题,也可通过具名 slot (见下表)传入 | string | — | — |\r\n| width | Dialog 的宽度 | string | — | 50% |\r\n| fullscreen | 是否为全屏 Dialog | boolean | — | false |\r\n| top | Dialog CSS 中的 margin-top 值 | string | — | 15vh |\r\n| modal | 是否需要遮罩层 | boolean | — | true |\r\n| modal-append-to-body | 遮罩层是否插入至 body 元素上,若为 false,则遮罩层会插入至 Dialog 的父元素上 | boolean | — | true |\r\n| append-to-body | Dialog 自身是否插入至 body 元素上。嵌套的 Dialog 必须指定该属性并赋值为 true | boolean | — | false |\r\n| lock-scroll | 是否在 Dialog 出现时将 body 滚动锁定 | boolean | — | true |\r\n| custom-class | Dialog 的自定义类名 | string | — | — |\r\n| close-on-click-modal | 是否可以通过点击 modal 关闭 Dialog | boolean | — | false |\r\n| close-on-press-escape | 是否可以通过按下 ESC 关闭 Dialog | boolean | — | true |\r\n| show-close | 是否显示关闭按钮 | boolean | — | true |\r\n| before-close | 关闭前的回调,会暂停 Dialog 的关闭 | function(done),done 用于关闭 Dialog | — | — |\r\n| center | 是否对头部和底部采用居中布局 | boolean | — | false |\r\n| destroy-on-close | 关闭时销毁 Dialog 中的元素 | boolean | — | false |\r\n\r\n### Slot\r\n| name | 说明 |\r\n|------|--------|\r\n| — | 对话框的内容 |\r\n| title | 对话框标题区的内容 |\r\n| footer | 对话框按钮操作区的内容 |\r\n\r\n\r\n### Events\r\n| 事件名称 | 说明 | 回调参数 |\r\n|---------- |-------- |---------- |\r\n| open | 对话框打开的回调 | — |\r\n| opened | 对话框打开动画结束时的回调 | — |\r\n| close | 对话框关闭的回调 | — |\r\n| closed | 对话框关闭动画结束时的回调 | — |"
},
{
"name": "open-data-box",
"category": "PC端组件库",
"content": "## OpenDataBox - 企微转译组件\r\n\r\n企微转译组件又称为组织架构企微转译组件,该组件基于企业微信api中通讯录展示组件WWOpenData进行封装,组件运行时可将企业组织架构的员工id或部门id进行转译,转译成功后以文本展示组织架构的员工名称或部门名称;\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/pc-base-ui`中具名导入`OpenDataBox`组件, 并在页面中注册;\r\n\r\n```js\r\n\r\n<script>\r\n import { OpenDataBox } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n OpenDataBox\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用-组织架构员工名称展示\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class=\"ws-details-tip-box\">\r\n <span>员工:</span><open-data-box :name=\"userId\" :isUser=\"true\"/>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: true,\r\n userId: 'laotian'\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 组织架构部门名称展示\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class=\"ws-details-tip-box\">\r\n <span>部门:</span><open-data-box :name=\"deptId\" :isUser='false'/>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: true,\r\n deptId: 207\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------ | ------------------------------------------------------------------ | ------------- | ------ | ------ |\r\n| isUser | 是否为员工id转译场景,true为转译员工、false为转译部门 | boolean | - | false |\r\n| name | 员工id(userId)或部门id(deptId) | string/number | - | - |\r\n| corpid | 企业id, 上下游企业场景展示上下游企业组织架构时,需配置上下游企业id | string | - | - |"
},
{
"name": "ws-upload-img",
"category": "PC端组件库",
"content": "## WeShineUploadImg 图片上传组件\r\n\r\n基于 [el-upload](/#/zh-CN/component/upload) 开发,通过点击上传图片,支持单张、多张图片上传,支持预览、删除、替换图片。\r\n- 支持jpg/png/jpeg格式图片上传。\r\n- 图片上传组件由上传区域和提示语上下排列组合而成,上传后的图片展示区域即为上传区域;鼠标移动到上传图片上,图片底部展示编辑、预览icon,图片右上角展示删除icon。\r\n- 与 [el-upload](/#/zh-CN/component/upload) 的相同点:支持limit、before-upload、on-success、on-error、on-change,除此之外均不支持。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineUploadImg`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WeShineUploadImg} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineUploadImg\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n默认单张上传,上传后,右侧会展示一个\"编辑\"文字按钮\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img :imageList.sync=\"image\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n image: []\r\n };\r\n },\r\n methods: {\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n### 自定义上传区域宽高(图片预览)\r\n仅支持单张图片上传\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img :imageList.sync=\"image\" :width=\"width\" :height=\"height\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n height: 90,\r\n width: 90,\r\n image: []\r\n };\r\n },\r\n methods: {\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n### 多张图片上传\r\n多张图片上传为追加式上传,和单张上传的区别,上传后右侧没有\"编辑\",其他功能一致\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img :imageList.sync=\"image\" :limit='limit'/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n image: [],\r\n limit: 6\r\n };\r\n },\r\n methods: {\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n### 图片大小校验\r\n限制图片上传的大小,单位M,超过限制后展示失败提示语,提示语展示在组件底部。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img :imageList.sync=\"image\" :limitSize=\"limitSize\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n limitSize: 2,\r\n image: []\r\n };\r\n },\r\n methods: {\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 提示语设置\r\n组件默认提示语为“支持jpg/png/jpeg格式,图片大小不能超过`limitSize`M”,可通过插槽`describe`设置提示语。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img :imageList.sync=\"image\" :limitSize=\"limitSize\">\r\n <template v-slot:describe>\r\n <!-- 自定义提示语 -->\r\n <p>自定义尺寸建议1280px*850px,支持jpg/jpeg/png格式,大小不超过{{limitSize}}M</p>\r\n </template>\r\n </we-shine-upload-img>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n limitSize: 2,\r\n image: []\r\n };\r\n },\r\n methods: {\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n\r\n### 图片上传钩子\r\nbefore-upload、on-success、on-error、on-change与[el-upload](/#/zh-CN/component/upload)中使用相同\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img :imageList.sync=\"image\" :before-upload=\"beforeUpload\" :on-success=\"onSuccess\" :on-error='onError' :on-change=\"onChange\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n image: [],\r\n imgLoading: false\r\n };\r\n },\r\n methods: {\r\n // eg:商城装修、微店场景,图片上传后,不可操作,通过`before-upload`、`on-success`、`on-error` 事件回调判断图片是否上传完成。\r\n beforeUpload(file: File) {\r\n // 上传图片前的业务处理\r\n this.imgLoading = true;\r\n },\r\n onSuccess(response: ElUploadResponse, file : File, fileList: array<File>) {\r\n // 图片上传成功时业务处理\r\n this.imgLoading = false;\r\n },\r\n onError(err: Error, file: File, fileList: array<File>) {\r\n // 图片上传失败时业务处理\r\n this.imgLoading = false;\r\n },\r\n onChange(file : File, fileList: array<File>) {\r\n // 图片状态改变时业务处理\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-------------|------------|--------------------------------------------------------------------------|--------------------------------------------|--------|\r\n| limit | 最大允许上传个数 | number | \t— | 1 |\r\n| imageList | 上传图片列表 | Array\\<string\\> | \t— | [] |\r\n| errorText | 接口上传失败时的提示文案 | string | — | '' |\r\n| width | 上传区域的宽度(仅单个上传时有效) | number | — | \t— |\r\n| height | 上传区域的高度(仅单个上传时有效) | number | — | \t— |\r\n| limitSize | 图片上传限制的大小(单位M) | number | \t— | 10 |\r\n| precent | 上传进度百分比 | number | — | — |\r\n| before-upload | 上传图片之前的钩子,参数为上传的图片,若返回 false 或者返回 Promise 且被 reject,则停止上传。 | (file: File) => (Promise\\<boolean\\> \\| boolean \\| void) | — | — |\r\n| on-success | 图片上传成功时的钩子 | (response: ElUploadResponse, file : File, fileList: array\\<File\\>)=>void | — | — |\r\n| on-error | 图片上传失败时的钩子 | (err: Error, file: File, fileList: array\\<File\\>)=>void | — | — |\r\n| on-change | 图片状态改变时的钩子,添加图片、上传成功和上传失败时都会被调用 | (file : File, fileList: array\\<File\\>)=>void | — | — |\r\n\r\n\r\n### Slots\r\n| 参数 | 说明 |\r\n|---------|--------------|\r\n| describe | 提示语区域的插槽 |\r\n\r\n\r\n\r\n\r\n### 类型定义\r\n```ts\r\ntype ElUploadResponse = {\r\n height: number,\r\n key: string,\r\n name: string,\r\n url: string,\r\n size: number,\r\n width: string\r\n};\r\n\r\n```"
},
{
"name": "ws-dep-user-show",
"category": "PC端组件库",
"content": "## WeShineDepUserShow - 组织架构标签组组件\r\n\r\n以标签的形式展示人员与部门列表,一般与`WeShineDepSelectDialog`组件配合使用,用以展示选中的人员或部门。\r\n\r\n- 要注意区分`WsTagShow`组件,`WeShineDepSelectDialog`组件不仅集成了特有的人员和部门的图标样式,还能展人员的部门详情,所以页面中以标签的形式展示人员与部门列表的场景应该使用`WeShineDepSelectDialog`而不是`WsTagShow`。\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineDepUserShow`组件, 并在页面中注册\r\n\r\n```js\r\n<script>\r\n import {WeShineDepUserShow} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineDepUserShow\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <el-card class=\"box-card tag-box\">\r\n <WeShineDepUserShow\r\n tagSize=\"medium\"\r\n :list=\"staffList\"\r\n ></WeShineDepUserShow>\r\n </el-card>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n staffList: [\r\n {'deptId': '1', 'isUser': false}\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n:::\r\n\r\n### 可删除用法\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <el-card class=\"box-card tag-box\">\r\n <WeShineDepUserShow\r\n isClose\r\n tagSize=\"medium\"\r\n :list=\"staffList\"\r\n @clickClose=\"deleteUser\"\r\n ></WeShineDepUserShow>\r\n </el-card>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n staffList: [\r\n {'deptId': '1', 'isUser': false}\r\n ]\r\n };\r\n },\r\n methods: {\r\n // 删除当前展示的人员或部门\r\n deleteUser(staff) {\r\n try {\r\n this.staffList = this.staffList.filter((v) =>\r\n staff.isUser ? v.userId !== staff.userId : v.deptId !== staff.deptId\r\n );\r\n } catch (error) {\r\n }\r\n }\r\n\r\n }\r\n };\r\n</script>\r\n\r\n\r\n```\r\n\r\n:::\r\n\r\n### 展示组织架构选择对话框选中项\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <el-card class=\"box-card tag-box\">\r\n <div slot=\"header\" class=\"clearfix\">\r\n <ws-button @click=\"visible = true\">打开选人</ws-button>\r\n <we-shine-dep-select-dialog\r\n sourceType=\"priority\"\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"staffList\"\r\n @confirm=\"confirm\"\r\n />\r\n </div>\r\n <WeShineDepUserShow\r\n isClose\r\n tagSize=\"medium\"\r\n :list=\"staffList\"\r\n @clickClose=\"deleteUser\"\r\n ></WeShineDepUserShow>\r\n </el-card>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: false,\r\n staffList: [\r\n {'deptId': '1', 'isUser': false}\r\n ]\r\n };\r\n },\r\n methods: {\r\n // 删除当前展示的人员或部门\r\n deleteUser(staff) {\r\n this.staffList = this.staffList.filter((v) =>\r\n staff.isUser ? v.userId !== staff.userId : v.deptId !== staff.deptId\r\n );\r\n },\r\n confirm(payload) {\r\n this.staffList = payload;\r\n }\r\n\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------- |---------------|---------| --------------------- |--------|\r\n| list | 展示的组织架构列表数据 | Array\\<NodeUser \\| NodeDep\\> | - | - |\r\n| maxWidth | 配置展示标签的最大宽度 | Number | - | 100 |\r\n| tagSize | 配置展示标签的大小 | String | medium / small / mini | medium |\r\n| isClose | 是否显示`x`删除图标按钮 | Boolean | - | false |\r\n\r\n### Events\r\n\r\n| 名称 | 说明 | 回调参数 |\r\n| ---------- |---------------|------------------------------------------|\r\n| clickClose | `x`删除图标按钮点击事件 | tag: NodeUser \\| NodeDep , index: number |\r\n\r\n提示:请参考 [NodeUser \\| NodeUser](/components/#/zh-CN/component/WeShineDepSelectDialog) 查看具体数据声明。"
},
{
"name": "ws-details-tip",
"category": "PC端组件库",
"content": "## WeShineDetailsTip - 组织架构详情弹出框\r\n\r\n组件运行时显示为\"i\"图标,鼠标放置在图标上,会展示员工或部门详细信息弹出框,当为员工时,详细信息包括员工名称、员工头像、所属部门,当为部门时,详细信息为所有上级部门名称;\r\n此组件通常配合`open-data-box`组织架构企微转译组件使用,用以显示当前员工或部门的详情。\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineDetailsTip`组件, 并在页面中注册;\r\n\r\n```js\r\n\r\n<script>\r\n import { WeShineDetailsTip } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WeShineDetailsTip\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用-员工详情信息提示\r\n组件默认**不显示**,配置`visible`属性为`true`显示组件。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class=\"ws-details-tip-box\">\r\n <span>员工:</span><open-data-box name='laotian' :isUser='true'/>\r\n <WeShineDetailsTip :visible=\"visible\" :isUser=\"true\" :userId=\"userId\" />\r\n </div>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: true,\r\n userId: 'laotian'\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 部门详情信息提示\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class=\"ws-details-tip-box\">\r\n <span>部门:</span><open-data-box name='207' :isUser='false'/>\r\n <WeShineDetailsTip :visible=\"visible\" :isUser=\"false\" :deptId=\"deptId\" />\r\n </div>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: true,\r\n deptId: 207\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------- |--------------------------------------| ------- | ------ | ------ |\r\n| visible | 是否显示组件 | boolean | - | false |\r\n| isUser | 是否为员工,true为员工、false为部门 | boolean | - | false |\r\n| userId | 员工id | string | - | - |\r\n| deptId | 部门id | string | - | - |\r\n| corpid | 企业id, 上下游企业场景展示上下游企业组织架构时,需配置上下游企业id | string | - | - |"
},
{
"name": "ws-dep-select-dialog",
"category": "PC端组件库",
"content": "## WeShineDepSelectDialog 组织架构选择对话框\r\n\r\n\"组织架构选择对话框\"也称\"选人对话框\",可以选择企业员工和部门。常用于业务中的员工筛选场景,或者创建任务时指定员工等场景。\r\n\r\n组件内部内置了带权限和不带权限两组数据源,也可以配置自定义数据源用于更多场景,组织架构数据是树形结构。节点图标icon可配置。\r\n\r\n\r\n### 导入方式\r\n需从 `@wshoto/pc-base-ui` 中具名导入 `WeShineDepSelectDialog` 组件, 并在页面中注册\r\n\r\n```js\r\n<script>\r\n import { WeShineDepSelectDialog } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WeShineDepSelectDialog\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基础用法\r\n\r\n:::demo\r\n```html\r\n <ws-button @click=\"visible = true;\">选择员工</ws-button>\r\n <we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n title=\"选择员工\"\r\n sourceType=\"priority\"\r\n @confirm=\"confirm\"\r\n >\r\n </we-shine-dep-select-dialog>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: []\r\n }\r\n },\r\n methods: {\r\n confirm(data) {\r\n this.selectedNodes = data\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n:::\r\n\r\n### 配置数据源是否带有权限\r\n数据源是否带有权限,可以通过 `sourceType` 属性配置。 当值是 `priority` 时,代表数据源带权限;当值是 `none-priority` 时,代表数据源不带权限。默认值为`none-priority`,默认数据源不带权限。\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n sourceType=\"priority\"\r\n @confirm=\"confirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog,\r\n }\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[]\r\n }\r\n },\r\n methods: {\r\n confirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 配置自定义数据源\r\n实现自定义数据源,可以通过将 `sourceType` 属性配置为 `custom`,并且配搭 `load` 属性来实现。 `load` 属性的类型定义是:(type: LOAD_TYPES, data?: TreeNode, searchVal?: string) =>\r\n Promise\\<DataNode[]\\>。,`type` 表示组件加载数据的事件类型,当 `type` 是 `ROOT` 时,返回根节点数据。当 `type` 的值是 `CHILDREN` 时,根据参数 `data` 中的父节点Id来获取子节点数据。当 `type` 的值时 `SEARCH` 时,根据参数 `searchVal` 参数来获取数据。\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n sourceType=\"custom\"\r\n :load=\"loadData\"\r\n @confirm=\"confirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog,\r\n }\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[]\r\n }\r\n },\r\n methods: {\r\n confirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n },\r\n\r\n loadData(type, data, searchVal) {\r\n switch (type) {\r\n case 'ROOT':\r\n return Promise.resolve([\r\n {\r\n isUser: false,\r\n deptId: 1,\r\n name: '自定义的部门',\r\n showOriginName: true\r\n }\r\n ]);\r\n\r\n case 'CHILDREN':\r\n return Promise.resolve([\r\n {\r\n isUser: true,\r\n userId: 'liudehua',\r\n name: '刘德华',\r\n showOriginName: true,\r\n leaf: true,\r\n hiddenTips: true\r\n },\r\n {\r\n isUser: true,\r\n userId: 'zhangxueyou',\r\n name: '张学友',\r\n showOriginName: true,\r\n leaf: true,\r\n hiddenTips: true\r\n }\r\n ])\r\n\r\n case 'SEARCH':\r\n return Promise.resolve([\r\n {\r\n isUser: true,\r\n userId: 'jianguo',\r\n name: '建国(模拟搜索结果)',\r\n showOriginName: true,\r\n leaf: true,\r\n hiddenTips: true\r\n }\r\n ]);\r\n }\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 配置可选择的节点类型和单选/多选\r\n可自由配置可选节点类型,节点类型可分成两类:`部门节点` 和 `员工节点`。当 `choiceType` 的值为 `user` 时,表示只能选择 `员工节点`;当 `choiceType` 的值为 `department` 时,表示只能选择 `部门节点`;当 `choiceType` 的值为 `both` 时,表示`部门节点` 和 `员工节点` 都能选择。\r\n是否支持多选,可以通过 `multiple` 属性配置,当为 `true` 时表示可以多选,反之表示仅支持单选,默认值为 `false`, 默认不支持多选。\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n choiceType=\"both\"\r\n multiple\r\n @confirm=\"confirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog\r\n },\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[]\r\n }\r\n },\r\n methods: {\r\n confirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 选择节点前的钩子函数\r\n校验当前选中的节点是否可以被选择,可以通过 `beforeChecked` 属性来配置,`beforeChecked` 属性的类型定义是:(data: DataNode) => (Promise\\<boolean\\> | boolean),当返回值是 `true` 时,表示当前节点可以选择,反之代表不可以选择。参数 `data` 是当前选择节点的信息。\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n :beforeChecked=\"beforeChecked\"\r\n @confirm=\"confirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog\r\n },\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[]\r\n }\r\n },\r\n methods: {\r\n confirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n },\r\n\r\n beforeChecked(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n return true;\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 点击对话框 \"确定\" 按钮的前置钩子函数\r\n用于校验对话框中已选节点集合是否可以被选择,可以通过 `beforeConfirm` 属性来配置,`beforeConfirm` 属性的类型定义是:(data: DataNode[]) => (Promise\\<boolean\\> | boolean),当返回值是 `true` 时,表示已选节点集合校验通过并关闭对话框,反之代表已选节点集合校验不通过,不关闭对话框,需要开发者给出对应提示,例如调用`this.$message.error('xxx')`弹出提示语。参数 `data` 是所有将要被选择的节点集合。配置 `beforeConfirm` 后不要再配置 `confirm` 事件,但需要开发者在 `beforeConfirm` 函数中在校验通过时更新默认选中项。\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n :beforeConfirm=\"beforeConfirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog\r\n },\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[]\r\n }\r\n },\r\n methods: {\r\n beforeConfirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n return true;\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 配置标签功能\r\n筛选具有指定 `员工标签` 的员工集合,可以通过 `tagSelect` 属性配置,当值为 `true` 时表示开启该功能,默认值是 `false`, 默认不开启。\r\n\r\n`defaultUserTagSelected` 属性表示默认选中的 `员工标签`,需和 `tagSelect` 属性配合使用; `userTagLimit` 属性表示 `员工标签` 最大的选择数量。\r\n\r\n\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n sourceType=\"priority\"\r\n tagSelect\r\n :defaultUserTagSelected=\"defaultUserTagSelected\"\r\n :userTagLimit=\"userTagLimit\"\r\n @confirm=\"confirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog\r\n },\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[],\r\n defaultUserTagSelected: [],\r\n userTagLimit: 10\r\n }\r\n },\r\n methods: {\r\n confirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n\r\n### 配置节点icon样式\r\n节点图标icon样式,可以通过 `options` 属性配置,该属性中 `deptIcon` 字段表示部门节点的图标icon,`deptIconDisabled` 字段表示部门节点禁用时图标icon,`userIcon` 字段表示员工节点的图标icon,`userIconDisabled` 字段表示员工节点禁用时图标icon。\r\n\r\n```html\r\n<ws-button @click=\"visible = true\">选择员工</ws-button>\r\n\r\n<we-shine-dep-select-dialog\r\n :visible.sync=\"visible\"\r\n :defaultSelected=\"selectedNodes\"\r\n sourceType=\"priority\"\r\n :options=\"\"\r\n @confirm=\"confirm\"\r\n>\r\n\r\n</we-shine-dep-select-dialog>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { WeShineDepSelectDialog, WeShineDepSelectDialogTypes } from '@wshoto/pc-base-ui';\r\n export default Vue.extends({\r\n components: {\r\n WeShineDepSelectDialog\r\n },\r\n data() {\r\n return {\r\n visible: false,\r\n selectedNodes: [] as WeShineDepSelectDialogTypes.DataNode[],\r\n options: {\r\n deptIcon: require('./assets/deptIcon.png'),\r\n deptIconDisabled: require('./assets/deptIconDisabled.png'),\r\n userIcon: require('./assets/userIcon.png'),\r\n userIconDisabled: require('./assets/userIconDisabled.png'),\r\n }\r\n }\r\n },\r\n methods: {\r\n confirm(data: WeShineDepSelectDialogTypes.DataNode[]) {\r\n this.selectedNodes = data\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n::: tip\r\n注意事项\r\n\r\n权限范围(sourceType):使用前和产品确定数据是否带权限,带权限(priority)指仅可查看管理范围内的员工和部门,不带权限(none-priority)指可查看所有员工和部门,默认不带权限(none-priority);\r\n\r\n使用场景(shape):创建任务选择员工或部门场景(select),禁用“已禁用,退出企业,未开通,已过期”节点;列表筛选时选择员工/部门(filter),支持选择“已禁用,退出企业,未开通,已过期”节点, 若存在离职员工,则展示“已离职员工”分组;列表筛选条件场景(未开通/已过期成员置灰不能选)(filter-none-auth-node)禁止账号状态为未开通和已过期,目前主要应用于客户/客户群列表数据和统计的筛选场景,默认创建任务选择员工或部门场景(select);\r\n\r\n:::\r\n\r\n::: tip\r\n进阶使用\r\n\r\n支持自定义数据:sourceType='custom'搭配load属性配置,可实现自定义数据源;可使用treeDataSource配置出适合业务的数据源,或者使用第三方数据源,数据格式符合DataNode即可;\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n`支持所有 tree 属性`\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|----------------------| ------------ |\r\n| visible | 控制对话框的显示与隐藏,需使用.sync修饰符用。 | boolean | - | - |\r\n| sourceType | 数据源类型(必传): priority:带权限数据源;none-priority:不带权限数据源;custom:自定义数据源。 | string | priority \\| none-priority \\| custom | - |\r\n| choiceType | 选择节点类型。user:员工节点;department:部门节点;both:全部节点。 | string | user\\|department\\|both | both |\r\n| defaultSelected | 默认选中节点集合 | DataNode[] | - | [] |\r\n| load | 用于加载自定义数据,与 `sourceType` 搭配使用,当 `sourceType` 的值为 `custom` 时必传,根据参数返回数据 | (type: LOAD_TYPES, data?: TreeNode, searchVal?: string) => <br /> Promise\\<DataNode[]\\> | - | - |\r\n| disableList | 禁选列表 | DisableList[] | - | [] |\r\n| multiple | 是否开启多选 | boolean | - | false |\r\n| title | 对话框标题。 | string | - | 选择添加人 |\r\n| placeholder | 搜索框提示语placeholder。 | string | - | 当choiceType为`user`时默认值是\"搜索员工\";当choiceType为`department`时默认值是\"搜索部门\";当choiceType为`both`时默认值是\"搜索员工或部门\" |\r\n| confirmText | 对话框确定按钮文案。 | string | - | 确定 |\r\n| cancelText | 对话框取消按钮文案。 | string | - | 取消 |\r\n| noneSelectedTips | 右侧无选中时提示文字 | string | - | 无选择数据 |\r\n| rightTitle | 对话框内右侧已选区域的标题title | string | - | 已选择的员工/部门 |\r\n| showSelectAll | 搜索时是否展示全选按钮。单选时,该配置无效。 | boolean | - | false |\r\n| beforeChecked | 选择节点前的钩子函数,根据返回值决定是否选择节点,true:可被选择,false:不可被选择 | (data: DataNode) => (Promise\\<boolean\\> \\| boolean) | - | - |\r\n| beforeConfirm | 点击对话框确定按钮前的钩子函数,根据返回值决定是否关闭对话框,true:确定选择并关闭对话框,false:已选节点中存在未通过节点,对话框不关闭 | (data: DataNode[]) => (Promise\\<boolean\\> \\| boolean) | - | - |\r\n| shape | 用于指定业务场景下展示指定状态的员工: select:创建任务时选择员工或部门,禁止选择成员状态是已禁用,退出企业或已离职的节点,禁止选择账号状态是未开通或已过期的节点;filter:列表筛选条件场景,列表筛选时选择员工/部门,支持选择“已禁用,退出企业,未开通,已过期”节点,若存在已离职员工吗,则展示”已离职员工“分组;filter-none-auth-node:列表筛选条件场景(未开通/已过期成员置灰不能选)禁止账号状态为未开通和已过期,目前主要应用于客户/客户群列表数据和统计的筛选场景。 | string | select \\| filter \\| filter-none-auth-node | select |\r\n| options | 用于配置节点图标icon,deptIcon:部门节点图标icon;deptIconDisabled:部门节点禁用时图标icon;userIcon:员工节点图标icon;userIconDisabled:员工员工节点禁用时图标icon。 | { deptIcon: string; deptIconDisabled: string; userIcon: string; userIconDisabled: string; } | - | - |\r\n| corpid | 企业id, 若企业存在上下游关系,open-data-box渲染指定企业的员工或部门名称 | string | - | - |\r\n| tagSelect | 是否支持选择员工标签 | boolean | - | false |\r\n| defaultUserTagSelected | 默认选中的员工标签,需和tagSelect配合使用 | Array\\<{tagId: string, tagName: string}\\> | - | [] |\r\n| userTagLimit | 员工标签最大的选择数量 | number | - | 5 |\r\n| openScene | 用于展示不同开通场景下选人组件员工节点的提示,normal: 通用功能开通权限; session : 会话存档开通权限 | string | normal \\| session | normal |\r\n| limit | 用于限制选择人数场景,为提高查询性能,在某些业务场景禁止选择人数超过1000。当该属性为true时,选择人数超200时,点击对话框确定按钮关闭对话框,并toast提示:“已选成员数超过200,查询时间可能比较长,可适当减少成员数”;当选择的成员数量超过1000人,点击对话框确定按钮不关闭对话框,并toast提示:“每次查询最多只能选择1000个成员”; | boolean | - | false |\r\n| formatter | 用于格式化节点数据 | (data: DataNode) => DataNode | - | - |\r\n| departmentPersonTotal | 是否展示部门节点下有多少人,取值count字段 | boolean | - | false |\r\n| confirmDisabled | 对话框确定按钮是否是禁用状态 | boolean | - | false |\r\n\r\n\r\n\r\n### Events\r\n\r\n`支持 tree 所有事件`\r\n\r\n| 名称 | 说明 | 回调参数 |\r\n| --------------- | ----------------------------------------- | ------------------- |\r\n| confirm | 点击对话框确定按钮时的事件,参数为当前已选的节点集合。 | data: DataNode[] |\r\n| cancel | 点击对话框取消按钮时的事件。 | - |\r\n| check-change | 鼠标点击选中或取消某个节点时的触发。第一个参数是节点信息,第二个参数是更新后的节点的选中状态。 | data: DataNode, status: boolean |\r\n| node-click | 鼠标点击某个节点的事件。 | data:  DataNode |\r\n\r\n### Methods\r\n\r\n| 名称 | 说明 | 返回值 |\r\n| --------------- | ---------------- | --------------- |\r\n| getCheckedNodes | 通过ref调用,调用该方法会返回对话框内已选的节点集合。 | DataNode[] |\r\n\r\n### Slots\r\n| 插槽名称 | 说明 | 参数 |\r\n| --------------- | ---------------- | --------------- |\r\n| right-title | 对话框内右侧已选节点区域头部title的插槽 | - |\r\n\r\n### 类型定义\r\n\r\n```ts\r\n\r\n// 加载类型\r\nenum LOAD_TYPES {\r\n ROOT = 'ROOT', // 初始化\r\n CHILDREN = 'CHILDREN', // 加载下级节点\r\n SEARCH = 'SEARCH' // 搜索节点\r\n}\r\n\r\n// 标签配置\r\ntype TagConfig = {\r\n label: string; // 标签的文本\r\n tips?: string; // hover标签时的提示\r\n button?: string; // 结尾按钮的问题\r\n routerPath?: string; // 点击按钮跳转的路由\r\n message?: string; // 点击按钮弹出的提示\r\n}\r\n\r\n// 节点的标签类型,目前仅一种\r\ntype TagType = 'normal';\r\n\r\n// 节点的标签\r\ntype TagNode = {\r\n text: string, // 标签的文字\r\n type?: TagType, // 节点的标签类型,目前仅一种\r\n popover?: boolean, // hover标签是否需要展示文本\r\n popoverTips?: string, // hover标签时展示的文案\r\n handlerType?: number, // 交互类型,跳转路由或展示提示\r\n} & Pick<TagConfig, 'button' | 'routerPath' | 'message'>\r\n\r\ntype NodeParent = {\r\n id?: number; // 节点的id\r\n count?: number | null, // 如果是部门节点,部门下有多少人\r\n name?: string; // 节点名称,showOriginName为true时,可使用name渲染名称\r\n leaf?: boolean; // 是否是叶子节点\r\n parentId?: number; // 节点的父部门id\r\n showOriginName?: boolean; // 组织架构树节点名称默认使用open-data-box渲染,如果传递showOriginName,可以搭配name直接使用html原生标签渲染\r\n customTags?: TagNode[]; // 节点右侧的标签集合\r\n hiddenTips?: boolean; // 是否隐藏节点展示主部门信息的icon\r\n nodeCustomIcon?: string; // 节点自定义图标 示例 require('./xx.svg')\r\n status?: 0 | 1 | 2 | 4 | 5 | 99; // 员工节点状态:0-无效,不在可见范围内,1-已激活,2-已禁用,4-未激活,5-退出企业,99-已离职\r\n accountStatus?: 1 | 2 | 3; // 账号状态:1-未开通, 2-已开通, 3-已过期\r\n orgPathIds?: Array<number>; // 节点的父部门id集合\r\n}\r\n\r\n// 员工节点类型\r\ntype NodeUser = {\r\n isUser: true; // 是员工节点\r\n userId: string; // 员工id\r\n} & NodeParent;\r\n\r\n// 部门节点类型\r\ntype NodeDep = {\r\n isUser: false; // 非员工节点,即部门节点\r\n deptId: number; // 部门id\r\n depId?: number; // 部门id,冗余字段\r\n children?: Array<NodeUser | NodeDep>;\r\n} & NodeParent\r\n\r\n// 节点类型\r\ntype DataNode = NodeUser | NodeDep;\r\n\r\n// tree节点内部结构\r\ntype TreeNode = {\r\n checked: boolean; // 是否是勾选状态\r\n childNodes: Array<TreeNode>; // 子节点\r\n data: DataNode; // 节点数据\r\n expanded: boolean; // 是否展开\r\n id: number; // 节点id\r\n indeterminate: boolean;\r\n isCurrent: boolean;\r\n isLeaf: boolean; // 叶子节点\r\n level: number; // 节点层级\r\n loaded: boolean; // 节点是否已加载\r\n loading: boolean; // loading状态\r\n parent: TreeNode; // 父节点\r\n store: any;\r\n text: string;\r\n visible: boolean;\r\n}\r\n\r\n// 禁用节点类型\r\ntype DisableList = Array<{ userId: string } | { deptId: number, count?: number }>\r\n```"
},
{
"name": "ws-date-picker",
"category": "PC端组件库",
"content": "## WsDatePicker - 日期范围筛选器\r\n\r\n用于日期范围、日期时间范围选择的筛选器,必须在`WsFilterGroup`及`WsFilterItem`包裹下使用。基于[`ElDatePicker`](/#/zh-CN/component/date-picker#attributes)组件封装。\r\n- `type`属性只包含`daterange`、`datetimerange`两种\r\n- `range-separator`属性值内置为'至'\r\n- `default-time`属性值内置为['00:00:00', '23:59:59']\r\n- `start-placeholder`属性值内置为\"开始时间\"\r\n- `end-placeholder`属性值内置为\"结束时间\"\r\n- type为`daterange`时,`format`属性值内置为'yyyy-MM-dd';type为`datetimerange`时,`format`属性值内置为'yyyy-MM-dd HH:mm:ss'\r\n- 其它属性及事件均与`ElDatePicker`保持一致\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsDatePicker`、`WsFilterGroup`、`WsFilterItem`组件, 并在组件中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WsDatePicker, WsFilterGroup, WsFilterItem} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsDatePicker,\r\n WsFilterGroup,\r\n WsFilterItem\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label='日期范围'>\r\n <ws-date-picker\r\n v-model='searchOptions.searchDate' \r\n type='daterange'\r\n >\r\n </ws-date-picker>\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n searchOptions: {\r\n searchDate: []\r\n }\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n:::\r\n\r\n### 日期时间范围筛选\r\n设置type类型为`datetimerange`,可以得到时间范围筛选器\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label='时间范围'>\r\n <ws-date-picker\r\n v-model='searchOptions.searchDateTime' \r\n type='datetimerange'\r\n >\r\n </ws-date-picker>\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n searchOptions: {\r\n searchDateTime: []\r\n }\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 快捷筛选\r\n设置快捷选项,例如最近一周、最近一个月、最近三个月的快捷筛选\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label='日期范围'>\r\n <ws-date-picker\r\n v-model='searchOptions.searchDate'\r\n type='daterange'\r\n :picker-options=\"pickerOptions\"\r\n >\r\n </ws-date-picker>\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n searchOptions: {\r\n searchDate: []\r\n },\r\n pickerOptions: {\r\n shortcuts: [\r\n {\r\n text: '最近一周',\r\n onClick(picker) {\r\n const end = new Date();\r\n const start = new Date();\r\n start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);\r\n picker.$emit('pick', [start, end]);\r\n }\r\n },\r\n {\r\n text: '最近一个月',\r\n onClick(picker) {\r\n const end = new Date();\r\n const start = new Date();\r\n start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);\r\n picker.$emit('pick', [start, end]);\r\n }\r\n },\r\n {\r\n text: '最近三个月',\r\n onClick(picker) {\r\n const end = new Date();\r\n const start = new Date();\r\n start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);\r\n picker.$emit('pick', [start, end]);\r\n }\r\n }\r\n ]\r\n }\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 禁选日期\r\n指定禁选日期范围函数,例如禁选选中的前后90天\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label='日期范围'>\r\n <ws-date-picker\r\n v-model='searchOptions.searchDate'\r\n type='daterange'\r\n :picker-options=\"pickerOptions\"\r\n >\r\n </ws-date-picker>\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n searchOptions: {\r\n searchDate: []\r\n },\r\n pickerOptions: this.pickerOptions\r\n }\r\n },\r\n methods: {\r\n pickerOptions() {\r\n let curMaxDate = dayjs().endOf('day').valueOf();\r\n let curMinDate = dayjs().startOf('day').subtract(90, 'day').valueOf();\r\n return {\r\n disabledDate(time) {\r\n // 当前选中的日期的前后90天\r\n let before = 0;\r\n let after = 0;\r\n if (curMinDate && !curMaxDate) {\r\n before = dayjs(curMinDate).endOf('day').subtract(90, 'day').valueOf();\r\n after = dayjs(curMinDate).startOf('day').add(90, 'day').valueOf();\r\n return (time <= before || time >= after);\r\n }\r\n },\r\n onPick({maxDate, minDate}) {\r\n curMaxDate = maxDate;\r\n curMinDate = minDate;\r\n }\r\n };\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-------------------|----------------------------|----------|-----------------------------------------------------|------ |\r\n| value / v-model | 绑定值 | string[] | — | — |\r\n| type | 显示类型 | string | daterange/datetimerange | daterange |\r\n| readonly | 完全只读 | boolean | — | false |\r\n| disabled | 禁用 | boolean | — | false |\r\n| editable | 文本框可输入 | boolean | — | true |\r\n| clearable | 是否显示清除按钮 | boolean | — | true |\r\n| placeholder | 非范围选择时的占位内容 | string | — | — |\r\n| popper-class | DatePicker 下拉框的类名 | string | — | — |\r\n| picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} |\r\n| default-value | 可选,选择器打开时默认显示的时间 | Date | 可被`new Date()`解析 | — |\r\n| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 见[日期格式](#/zh-CN/component/date-picker#ri-qi-ge-shi) | '' |\r\n| unlink-panels | 在范围选择器里取消两个日期面板之间的联动 | boolean | — | false |\r\n| prefix-icon | 自定义头部图标的类名 | string | — | '' |\r\n| clear-icon | 自定义清空图标的类名 | string | — | el-icon-circle-close |\r\n| validate-event | 输入时是否触发表单的校验 | boolean | - | true |\r\n\r\n### Picker Options\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-----------------------------------------------|-------------------------------------------------------------------|-------------------------------- |-------- |\r\n| shortcuts | 设置快捷选项,需要传入 { text, onClick } 对象用法参考 demo 或下表 | { text: string, onClick: (vm: Vue) =\\> void }[] | — | — |\r\n| disabledDate | 指定禁选日期范围函数,参数为当前日期 | (date: Date) =\\> boolean | — | — |\r\n| cellClassName | 设置日期的className | (date: Date) =\\> string | — | — |\r\n| firstDayOfWeek | 周起始日 | number | 1/2/3/4/5/6/7 | 7 |\r\n| onPick | 选中日期后会执行的回调 | ({ maxDate, minDate }: { maxDate: Date, minDate: Date }) =\\> void | — | — |\r\n\r\n### Shortcuts\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |--------------------|-------------------------------- |-------- |\r\n| text | 标题文本 | string | — | — |\r\n| onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | (vm: Vue) =\\> void | — | — |\r\n\r\n### Events\r\n| 事件名称 | 说明 | 回调参数 |\r\n|---------|--------|---------|\r\n| change | 用户确认选定的值时触发 | 组件绑定值。格式与绑定值一致,可受 `value-format` 控制 |\r\n| blur | 当 input 失去焦点时触发 | 组件实例 |\r\n| focus | 当 input 获得焦点时触发 | 组件实例 |\r\n\r\n### Methods\r\n| 方法名 | 说明 | 参数 |\r\n| ---- | ---- | ---- |\r\n| focus | 使 input 获取焦点 | — |"
},
{
"name": "ws-date-selector",
"category": "PC端组件库",
"content": "## WsDateSelector - 日期范围选择组件\r\n\r\n日期范围选择组件,基于[`ElDatePicker`](/#/zh-CN/component/date-picker#attributes)组件封装。组件可选择日期范围,并支持配置快捷选项操作,例如在日期范围选择器左侧可配置快捷选项:昨日、今日、7日、30日、自定义,被选中的快捷选项会高亮显示;\r\n以下为组件内置ElDatePicker的一些属性配置:\r\n- `type`属性内置为`daterange`\r\n- `default-time`属性值内置为['00:00:00', '23:59:59']\r\n- `start-placeholder`属性值内置为\"开始时间\"\r\n- `end-placeholder`属性值内置为\"结束时间\"\r\n- `range-separator`属性值内置为'至'\r\n- `format`属性值内置为'yyyy-MM-dd'\r\n- `value-format`属性值内置为'timestamp'\r\n- `unlink-panels`属性值内置为true\r\n- `popper-class`属性值内置为'ws-date-selector__picker'\r\n- `prefix-icon`属性值内置为'el-icon-date'\r\n\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/pc-base-ui`中具名导入`WsDateSelector`组件, 并在页面中注册;\r\n\r\n```js\r\n\r\n<script>\r\n import { WsDateSelector } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsDateSelector\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n默认选中七日快捷选项;\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-date-selector\r\n :radio=\"timeScope\"\r\n @change=\"changeDate\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n startTime: '',\r\n endTime: '',\r\n timeScope: 7\r\n };\r\n },\r\n methods: {\r\n changeDate(timeRange){\r\n const {startTime,endTime,radio} = timeRange || {};\r\n this.timeScope = radio;\r\n this.startTime = startTime;\r\n this.endTime = endTime;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 快捷选项配置\r\n- `layout`属性:快捷选项配置,可选值有'yesterday,today,week,month,custom',用英文逗号进行分割,分别代表含义为:'昨日,今日,7日,30日,自定义';默认值为:'today,week,month,custom'显示快捷选项'今日,7日,30日,自定义'。 \r\n- `radio`属性:选中快捷选项值,选中的快捷选项会高亮显示,支持配置修饰符.sync,可选值有:-1、1、0、7、30,分别代表含义为:自定义、昨日、今日、7日、30日,默认值为:7,选中快捷选项7日。 \r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-date-selector\r\n :layout=\"layout\"\r\n :radio=\"timeScope\"\r\n @change=\"changeDate\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n startTime: '',\r\n endTime: '',\r\n layout: 'yesterday,today,week,month,custom', // 快捷选项配置'昨日,今日,7日,30日,自定义'\r\n timeScope: 0, // 快捷选项配置默认选中今日选项\r\n };\r\n },\r\n methods: {\r\n changeDate(timeRange){\r\n const {startTime,endTime,radio} = timeRange || {};\r\n this.timeScope = radio;\r\n if (radio === -1) {\r\n this.startTime = startTime;\r\n this.endTime = endTime;\r\n } else {\r\n this.startTime = '';\r\n this.endTime = '';\r\n }\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 日期范围选择事件与日期范围格式化处理\r\n- `format`属性:dayjs的format方法的格式化占位符,组件change回调事件返回对象中的startTime开始日期、endTime结束日期会根据该值调用dayjs进行格式化处理。可选值为'timestamp'或dayjs中格式化占位符,例如'YYYY-MM-DD HH:mm:ss'、'YYYY-MM-DD',对应返回日期格式如'2024-09-09 16:12:12'、'2024-09-09',当值为timestamp时则返回日期为时间戳格式,默认为:timestamp 。\r\n- `change回调事件`:在日期范围值变更时触发,返回对象包含startTime开始日期、endTime结束日期、radio选中快捷选项值,其中startTime、endTime返回值格式组件内部实现会根据组件配置format日期格式化占位符做为dayjs的format方法的参数对日期进行格式化处理后再进行返回。当属性`format`不设置或设置为`timestamp`时,`change`回调事件中的`startTime`、`endTime`为精确到毫秒的时间戳。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-date-selector\r\n :radio=\"timeScope\"\r\n :format=\"format\"\r\n @change=\"changeDate\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n startTime: '',\r\n endTime: '',\r\n format: 'YYYY-MM-DD HH:mm:ss', //格式化占位符,例如需startTime返回格式为2024-09-09,则配置占位符为YYYY-MM-DD,若需startTime返回格式为2024-09-09 18:30:00,则配置占位符为YYYY-MM-DD HH:mm:ss\r\n timeScope: 0, // 快捷选项配置,默认选中今天\r\n };\r\n },\r\n methods: {\r\n changeDate(timeRange){\r\n const {startTime,endTime,radio} = timeRange || {};\r\n this.timeScope = radio;\r\n this.startTime = startTime;\r\n this.endTime = endTime;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 默认为自定义快捷选项时,可配置initCustomDate显示默认日期范围值;\r\n- `initCustomDate`属性:组件默认选中自定义快捷选项时,回显的日期范围值,只在组件默认设置radio属性为-1时该值生效。\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-date-selector\r\n :radio=\"timeScope\"\r\n :initCustomDate=\"initCustomDate\"\r\n @change=\"changeDate\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n startTime: '',\r\n endTime: '',\r\n timeScope: -1, // 快捷选项配置默认选中今日选项\r\n initCustomDate: [Date.now(),Date.now()] // timeScope初始设置为-1自定义选项时,默认回显的日期范围值;\r\n };\r\n },\r\n methods: {\r\n changeDate(timeRange){\r\n const {startTime,endTime,radio} = timeRange || {};\r\n this.timeScope = radio;\r\n this.startTime = startTime;\r\n this.endTime = endTime;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------------- | --------------------------------------------------------------------------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |\r\n| radio | 快捷选项选中值,选中的快捷选项会高亮显示,支持配置修饰符.sync | number | 可选值有:-1、1、0、7、30,分别代表含义为:自定义、昨日、今日、7日、30日 | 默认值为:7,选中快捷选项7日 |\r\n| layout | 快捷选项配置,支持配置'昨日,今日,7日,30日,自定义'快捷选项; | string | 可选值有'yesterday,today,week,month,custom',用英文逗号进行分割 | 默认值为:'today,week,month,custom'显示快捷选项'今日,7日,30日,自定义' |\r\n| initCustomDate | 组件默认选中自定义快捷选项时,回显的日期范围值,只在组件默认设置radio属性为-1时该值生效 | string[]/number[] | - | - |\r\n| format | dayjs的format方法的格式化占位符,组件change回调事件返回对象中的startTime开始日期、endTime结束日期会根据该值调用dayjs进行格式化处理。 | string | 可选值为'timestamp'或dayjs中格式化占位符,例如'YYYY-MM-DD HH:mm:ss'、'YYYY-MM-DD',对应返回日期格式如'2024-09-09 16:12:12'、'2024-09-09',当值为timestamp时则返回日期为number类型时间戳格式 | 默认值为:timestamp |\r\n| pickerOptions | 当前日期范围选择器特有的配置选项参考下表 | object | - | { disabledDate: time => dayjs(time).startOf('day').valueOf() > Date.now() } |\r\n| clearable | 是否显示日期范围选择器的清除按钮 | boolean | true/false | 默认值为:true |\r\n\r\n### Picker Options\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ------------- | ------ |\r\n| shortcuts | 设置快捷选项,需要传入 { text, onClick } 对象用法参考 demo 或下表 | { text: string, onClick: (vm: Vue) =\\> void }[] | — | — |\r\n| disabledDate | 指定禁选日期范围函数,参数为当前日期 | (date: Date) =\\> boolean | — | — |\r\n| cellClassName | 设置日期的className | (date: Date) =\\> string | — | — |\r\n| firstDayOfWeek | 周起始日 | number | 1/2/3/4/5/6/7 | 7 |\r\n| onPick | 选中日期后会执行的回调 | ({ maxDate, minDate }: { maxDate: Date, minDate: Date }) =\\> void | — | — |\r\n\r\n### Shortcuts\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------- | ---------------------------------------------------------------------------------------------------- | ------------------ | ------ | ------ |\r\n| text | 标题文本 | string | — | — |\r\n| onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | (vm: Vue) =\\> void | — | — |\r\n\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |------------------------------------------------------------------------------------|\r\n| change | 在日期范围值变更时触发,返回对象包含startTime开始日期、endTime结束日期、radio选中快捷选项值,其中startTime、endTime返回值格式组件内部实现会根据组件配置format日期格式化占位符做为dayjs的format方法的参数对日期进行格式化处理后再进行返回 | (value: { startTime: string \\| number; endTime: string \\| number; radio: number }) |"
},
{
"name": "ws-interval",
"category": "PC端组件库",
"content": "## WsInterval - 柱状图\r\n\r\n柱状图组件,基于 G2 二次封装。常用于详情、统计界面,实现数据可视化\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsLine`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WsLine} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsLine\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-interval :params=\"chartParams\"></ws-interval>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/06',\r\n count: 100\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/07',\r\n count: 85\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 多组数据\r\n支持多种数据来源和数据变换,以应对不同的数据源来源\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <div>\r\n <el-button\r\n type=\"primary\"\r\n style=\"margin-bottom: 20px;\"\r\n @click=\"chartParams=createParams(['新增客户数', '新增客户群数', '新增群聊数'], 7)\">切换数据</el-button>\r\n <ws-interval :params=\"chartParams\"></ws-interval>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: []\r\n };\r\n },\r\n created() {\r\n this.chartParams = this.createParams(['新增客户数', '新增客户群数', '新增群聊数'], 7);\r\n },\r\n methods: {\r\n createParams(types, count) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = '2023/10/1' + index;\r\n types.forEach(type => {\r\n const yCount = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, type, count: index === count - 1 ? 100 : yCount });\r\n });\r\n }\r\n return result;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 格式化X轴,Y轴文本\r\n通过 xFormatter、yFormatter 属性格式化文本。其中xFormatter格式化 `x` 轴;yFormatter格式化 `y` 轴\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <div>\r\n <el-button\r\n type=\"primary\"\r\n style=\"margin-bottom: 20px;\"\r\n @click=\"chartParams=createParams(['新增客户数', '新增客户群数', '新增群聊数'], 7)\">切换数据</el-button>\r\n <ws-interval :params=\"chartParams\" :xFormatter=\"xFormatter\" :yFormatter=\"yFormatter\"></ws-interval>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: []\r\n };\r\n },\r\n created() {\r\n this.chartParams = this.createParams(['新增客户数', '新增客户群数', '新增群聊数'], 7);\r\n },\r\n methods: {\r\n createParams(types, count) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = '2023/10/1' + index;\r\n types.forEach(type => {\r\n const yCount = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, type, count: index === count - 1 ? 100 : yCount });\r\n });\r\n }\r\n return result;\r\n },\r\n xFormatter(text) {\r\n return text + '格式化';\r\n },\r\n\r\n yFormatter(text) {\r\n return text + 'k';\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n\r\n### 设置滚动条\r\n通过 scrollbar 属性设置滚动条的展示。当显示区域大小不足以容纳全部信息时,可以将超出部分隐藏,并通过滚动条的横向滑动来显示出被隐藏部分\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <ws-interval :params=\"chartParams\" scrollbar></ws-interval>\r\n</template>\r\n\r\n<script>\r\n\r\n export default {\r\n data() {\r\n return {\r\n chartParams: []\r\n };\r\n },\r\n created() {\r\n this.chartParams = this.createParams(['新增客户数'], 60);\r\n },\r\n methods: {\r\n createParams(types, count) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = `第${index + 1}天`;\r\n types.forEach(type => {\r\n const yCount = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, type, count: index === count - 1 ? 100 : yCount });\r\n });\r\n }\r\n return result;\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 高级使用\r\n- yCount - y轴刻度点的个数\r\n- rate - 柱状图内的y轴数据展示百分比\r\n- height - 设置折线图可视区域高度\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-interval :params=\"chartParams\" :yCount=\"5\" rate :height=\"300\"></ws-interval>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n chartParams: [\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/01',\r\n count: 30\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/02',\r\n count: 60\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/03',\r\n count: 55\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/04',\r\n count: 40\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/05',\r\n count: 67\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/06',\r\n count: 100\r\n },\r\n {\r\n type: '新增客户数',\r\n xName: '2022/08/07',\r\n count: 85\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------|------------|--------------------------|-----|-------|\r\n| params | 展示的数据 | ParamsNode[] | - |\r\n| scrollbar | 是否需要展示滚动条 | boolean | - |\r\n| height | 图表canvas高度 | number | - | 450 |\r\n| rate | 柱状图内的y轴数据是否展示百分比 | boolean | - | false |\r\n| yCount | y轴刻度(含0) | number | - | 6 |\r\n| xFormatter | 格式化x轴名称 | (text: string) => string | - | - |\r\n| yFormatter | 格式化y轴名称 | (text: string) => string | - | - |\r\n\r\n### ParamsNode Attributes\r\n\r\n| 参数名 | 说明 | 类型 |\r\n|-------|------|--------|\r\n| type | 数据类型 | string |\r\n| xName | x轴名称 | string |\r\n| count | y轴数值 | number |"
},
{
"name": "ws-upload-img-box",
"category": "PC端组件库",
"content": "## WeShineUploadImgBox - 图片上传组件简约版\r\n基于 [el-upload](/#/zh-CN/component/upload) 开发,通过点击上传图片,支持单张上传、支持删除、替换图片,自定义上传区域的宽高,与 `WeShineUploadImg` 组件的区别在于该组件只有一个上传区域,仅支持单张上传。\r\n- 该组件仅有上传区域,上传后的图片展示区域即为上传区域;鼠标移动到上传图片上,图片底部展示‘点击修改’、图片右上角展示删除icon。\r\n- 与 [el-upload](/#/zh-CN/component/upload) 的相同点:支持disabled、data、on-progress、before-upload、on-success、on-error、on-change,除此之外均不支持。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineUploadImgBox`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WeShineUploadImgBox} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineUploadImgBox\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: ''\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n### 自定义上传区域宽高(图片预览)\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" :width=\"width\" :height=\"height\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n height: 90,\r\n width: 90,\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 图片大小校验\r\n限制图片上传的大小,单位M,超过限制后弹出提示\"图片大小超出 `limitSize`M 限制,请重新选择\"\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" :limitSize=\"limitSize\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n limitSize: 2,\r\n imageSrc: ''\r\n };\r\n },\r\n methods: {\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 删除icon隐藏\r\n删除icon隐藏后,只能替换图片,不可删除图片。\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" :hasDelete=\"hasDelete\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n hasDelete: false\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 禁用状态\r\n设置`disabled`属性,接受一个`boolean`,设置`true`即可禁用。\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" :disabled='disabled'/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n disabled: true\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 加载状态\r\n设置`isUploading`属性,即可获取当前上传状态。\r\n:::demo\r\n\r\n```html \r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" :isUploading.sync='isUploading'/>\r\n <!-- 当图片未上传或图片上传中,禁用提交按钮 -->\r\n <ws-button type='primary' :disabled='isUploading||!imageSrc' style=\"margin-top: 5px;\">提交</ws-button>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n isUploading: false\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 上传类型\r\n设置`accept`属性,设置可上传的图片类型,默认\"image/*\"。\r\n:::demo\r\n\r\n```html \r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" accept='image/png'/> \r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 设置上传区域\r\n设置上传区域,可使用`trigger`插槽。\r\n:::demo\r\n\r\n```html \r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\">\r\n <template v-slot:trigger>\r\n <!-- 重置上传区域 -->\r\n <p>请上传图片</p>\r\n </template> \r\n </we-shine-upload-img-box>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 设置回显区域\r\n设置回显区域,可使用`view`插槽。\r\n:::demo\r\n\r\n```html \r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\">\r\n <template v-slot:view>\r\n <!-- 重置回显区域 -->\r\n <img :src=\"imageSrc\" style=\"width: 80px; height: 60px\"/>\r\n <div style=\"font-size: 10px;\">\r\n <span>预览</span>\r\n <span>替换</span>\r\n </div>\r\n </template> \r\n </we-shine-upload-img-box>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 实现自动上传\r\n不点击组件,触发图片上传事件\r\n\r\n```html \r\n<template>\r\n <!-- 当业务要求不点击组件,直接触发组件的选择图片 -->\r\n <p @click=\"localUpload()\">点击可上传图片</p>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" ref='localUploadRef'/>\r\n \r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n };\r\n },\r\n methods: {\r\n localUpload() {\r\n this.$refs.localUploadRef && (this.$refs.localUploadRef as InstanceType<typeof WeShineUploadImgBox>).startUpload();\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n\r\n### 触发表单校验\r\n改变上传图片状态时触发表单的校验\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <el-form ref=\"form\" :rules=\"rules\" :model=\"form\">\r\n <el-form-item label='上传图片' prop='imageSrc'>\r\n <we-shine-upload-img-box v-model=\"form.imageSrc\" :validate-event='validateEvent'/>\r\n </el-form-item>\r\n </el-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n form:{\r\n imageSrc: '',\r\n imageSrc1: ''\r\n },\r\n validateEvent: true,\r\n rules: {\r\n imageSrc: [{ required: true, message: '请上传图片', trigger: ['change'] }],\r\n }\r\n };\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n\r\n### 图片上传钩子\r\nbefore-upload、on-success、on-error、on-change、on-progress与[el-upload](/#/zh-CN/component/upload)中使用相同\r\n```html\r\n\r\n<template>\r\n <we-shine-upload-img-box v-model=\"imageSrc\" :before-upload=\"beforeUpload\" :on-success=\"onSuccess\" :on-error=\"onError\" :on-change=\"onChange\" :width='width' :height=\"height\"/>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n imageSrc: '',\r\n width: 80,\r\n height: 80\r\n };\r\n },\r\n methods: {\r\n beforeUpload(file: File) {\r\n // 上传图片前的业务处理\r\n return new Promise((resolve, reject) => {\r\n const { type, size } = file;\r\n // 当设置为png 图片类型,防止手动调整上传类型,二次校验\r\n if (type !== 'image/png') {\r\n reject(new Error('仅支持上传png格式的图片'));\r\n }\r\n resolve(true);\r\n });\r\n },\r\n onSuccess(response: ElUploadResponse, file : File, fileList: array<File>) {\r\n // 图片上传成功时业务处理\r\n const { width, height, url } = e || {}; \r\n if ((width && width !== this.width) || (height && height !== this.height)) {\r\n this.$message.warning('当前上传图片尺寸不符合要求,请按照规定尺寸重新上传'); \r\n this.imageSrc = \"\";\r\n } \r\n },\r\n onError(err: Error, file: File, fileList: array<File>) {\r\n // 图片上传失败时业务处理\r\n },\r\n onChange(file : File, fileList: array<File>) {\r\n // 图片状态改变时业务处理\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n\r\n### Attributes\r\n\r\n| 类型 | 说明 | 类型 | 默认值 |\r\n| ------------ | :----------------------------------: | ------ | ------ |\r\n| v-model | 上传图片地址 | string |-|\r\n| accept | 接受上传的图片类型 | string | image/* |\r\n| width | 上传区域的宽度 | number |60|\r\n| height | 上传区域的高度 | number |60|\r\n| limitSize | 图片上传限制的大小 size(单位M) | number |10 |\r\n| hasDelete | 是否有删除icon | boolean | true |\r\n| disabled | 是否禁用 (同 elementUI) | boolean | false |\r\n| progress | 上传进度百分比 | number | -|\r\n| isUploading | 图片上传状态 | boolean | -|\r\n| validate-event|输入时是否触发表单的校验|\tboolean\t|-\t|true|\r\n| data | 上传时附带的额外参数 (同 elementUI) | Object | -|\r\n| before-upload | 上传图片之前的钩子,参数为上传的图片,若返回 false 或者返回 Promise 且被 reject,则停止上传。 | (file: File) => (Promise\\<boolean\\> \\| boolean \\| void) | - | - |\r\n| on-success | 图片上传成功时的钩子 | (response: ElUploadResponse, file : File, fileList: array\\<File\\>)=>void | - | - |\r\n| on-error | 图片上传失败时的钩子 | (err: Error, file: File, fileList: array\\<File\\>)=>void | - | - |\r\n| on-change | 图片状态改变时的钩子,添加图片、上传成功和上传失败时都会被调用 | (file : File, fileList: array\\<File\\>)=>void | - \r\n| onProgress | 图片上传时的钩子(同 elementUI) |(event: ProgressEvent, file: File, fileList: array\\<File\\>)=>void |-|\r\n\r\n\r\n### Slot\r\n| name | 说明 |\r\n| ------------ | :----------------------------------: |\r\n|trigger\t|触发图片选择框的内容插槽|\r\n|view\t|图片回显区域插槽|\r\n\r\n### Events\r\n| name | 说明 |\r\n| ------------ | :----------------------------------: |\r\n|delete\t|删除事件|\r\n\r\n\r\n### Methods\r\n| name | 说明 |\r\n| ------------ | :----------------------------------: |\r\n|startUpload\t| 触发图片上传事件 |\r\n\r\n\r\n\r\n### 类型定义\r\n```ts\r\ntype ElUploadResponse = {\r\n height: number,\r\n key: string,\r\n name: string,\r\n url: string,\r\n size: number,\r\n width: string\r\n};\r\n// 定义进度事件对象的接口\r\ninterface ProgressEvent {\r\n percent: number;\r\n loaded: number;\r\n total: number;\r\n}\r\n\r\n```"
},
{
"name": "ws-status-text",
"category": "PC端组件库",
"content": "## WsStatusText - 单元格状态文本组件\r\n\r\n单元格状态文本组件,常结合 `WsTable` 使用,展示状态。运行效果:左侧是小圆点,右侧为文本,圆点与文本水平居中对齐。 圆点与文本的颜色代表状态。\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WsStatusText`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WsStatusText} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsStatusText\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-status-text mode=\"fail\" text=\"失败\" />\r\n <ws-status-text mode=\"default\" text=\"默认\" />\r\n <ws-status-text mode=\"success\" text=\"成功\" />\r\n <ws-status-text mode=\"info\" text=\"警告\" />\r\n <ws-status-text mode=\"finish\" text=\"结束\" />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {}\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 列表状态展示\r\n通过 mode 属性设置状态类型,该属性有 `fail` 、`default`、`success`、`info`、`finish` 五种类型,分别对应 `红`、`蓝`、`绿`、`黄`、`灰` 颜色;text 属性设置状态文案\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-table\r\n :data=\"tableData\"\r\n :hidden-header=\"true\"\r\n :show-pagination=\"false\"\r\n >\r\n <el-table-column label=\"名称\" prop=\"name\" />\r\n <el-table-column label=\"任务状态\" prop=\"status\">\r\n <template v-slot=\"scope\">\r\n <ws-status-text :mode=\"getStatus(scope.row.status).status\" :text=\"getStatus(scope.row.status).text\" />\r\n </template>\r\n </el-table-column>\r\n </ws-table>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tableData: [\r\n {\r\n name: '双十一的小小礼物1',\r\n status: 1\r\n },\r\n {\r\n name: '双十一的小小礼物2',\r\n status: 2\r\n },\r\n {\r\n name: '双十一的小小礼物3',\r\n status: 3\r\n },\r\n {\r\n name: '双十一的小小礼物4',\r\n status: 4\r\n },\r\n {\r\n name: '双十一的小小礼物5',\r\n status: 5\r\n }\r\n ]\r\n };\r\n },\r\n methods: {\r\n getStatus(status) {\r\n const textMap = {\r\n 1: '进行中',\r\n 2: '已结束',\r\n 3: '创建失败',\r\n 4: '创建中',\r\n 5: '即将失效'\r\n }\r\n const statusMap = {\r\n 1: 'success',\r\n 2: 'finish',\r\n 3: 'fail',\r\n 4: 'default',\r\n 5: 'info'\r\n }\r\n return { status: statusMap[status], text: textMap[status] }\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ---- | ------------ | ------ | ------ | -------- |\r\n| mode | 状态类型 | string | fail/default/success/info/finish | default |\r\n| text | 状态对应文案 | string | — | 默认文案 |"
},
{
"name": "ws-filter-tag-group",
"category": "PC端组件库",
"content": "## WeShineFilterTagGroup - 标签组组件\r\n\r\n筛选内容后以标签组的形式展示。常用于筛选组织架构、群聊、客户标签等内容后的展示,需配合 `WsShineFilterTagItem` 组件一起使用。\r\n\r\n需注意与`WsTagShow`组件的区别,`WeShineFilterTagGroup`组件只能单行展示标签,超出一行的标签组件会进行折叠,通过组件内置的方法自行计算出有“n”个未展示的标签,然后在组件右侧自动显示“+n”的标签,无需再额外进行未展示标签的逻辑计算。+n的标签也不需要重复实现。\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineFilterTagGroup`、`WsShineFilterTagItem`组件, 并在页面中注册\r\n\r\n```js\r\n<script>\r\n import { WeShineFilterTagGroup, WsShineFilterTagItem } from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineFilterTagGroup, WsShineFilterTagItem\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <we-shine-filter-tag-group @changeClick=\"selected\">\r\n <we-shine-filter-tag-item\r\n v-for=\"(tag, i) of list\"\r\n :key=\"i\"\r\n :value=\"tag.name\"\r\n />\r\n </we-shine-filter-tag-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n list: [\r\n {'id': '123', 'name': '测试标签'}\r\n ]\r\n };\r\n },\r\n \r\n methods: {\r\n // 触发选择事件\r\n selected() {\r\n // 自定义打开选择对话框 \r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 标签组清空、标签删除\r\n\r\n- `WeShineFilterTagGroup` 标签组组件配置`allow-clear`属性,标签组会显示清除图标按钮。可通过`clear`事件监听清空标签组清空操作;\r\n- `WeShineFilterTagItem` 标签组件配置`closeable`属性,标签右侧会显示\"x\" 删除图标按钮。可通过`close`事件监听删除标签操作操作。\r\n\r\n::: demo\r\n\r\n```html\r\n<template>\r\n <we-shine-filter-tag-group\r\n :placeholder=\"placeholder\"\r\n @changeClick=\"selected\"\r\n @clear=\"clearAll\"\r\n >\r\n <we-shine-filter-tag-item\r\n v-for=\"(data, index) of displayOptionList\"\r\n :key=\"data.bigdataQueryThemeId\"\r\n :value=\"data.themeName\"\r\n closable\r\n @close=\"clear(index)\"\r\n />\r\n </we-shine-filter-tag-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n placeholder: '请选择',\r\n displayOptionList: [\r\n {\r\n 'id': '1653967078819924807',\r\n 'themeName': '话题名称010',\r\n 'categoryId': '0',\r\n 'bigdataQueryThemeId': '1#1653967078819924807'\r\n },\r\n {\r\n 'id': '1653967078819924808',\r\n 'themeName': '话题名称011',\r\n 'categoryId': '0',\r\n 'bigdataQueryThemeId': '1#1653967078819924808'\r\n }\r\n ]\r\n };\r\n },\r\n methods: {\r\n // 触发选择事件\r\n selected() {\r\n // 自定义打开选择对话框 \r\n },\r\n clearAll() {\r\n this.displayOptionList = [];\r\n },\r\n clear(index) {\r\n this.displayOptionList.splice(index, 1);\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n### WeShineFilterTagGroup Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-------------|---------------------------------------------------|---------|-------------|------|\r\n| placeholder | 无数据时占位文本 | string | - | 请选择 |\r\n| allow-clear | 是否支持清标签组清空操作,配置后鼠标悬浮到组件区域,会在组件右侧显示清除图标按钮,点击触发清空操作 | boolean | - | true |\r\n| theme | 主题色 | string | gray / blue | gray |\r\n| selectIcon | 标签组组件最右侧显示下拉箭头\"v\"图标 | boolean | - | true |\r\n\r\n### WeShineFilterTagGroup Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ------- |-------------| --------- |\r\n| changeClick | 标签组点击事件 | - |\r\n| clear | 清除图标按钮的点击事件 | - |\r\n\r\n### WeShineFilterTagItem Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|-------------------------------------------------------|---------|--------------------|-------|\r\n| icon-type | 标签类型的icon图标,作为svg-icon组件的icon-class属性进行展示,不传则不展示 | string | user/department/其它 | - |\r\n| value | 展示的标签文本,当icon-type为user或者department时,会使用open-data进行转义 | string | - | - |\r\n| max-width | 标签展示最大宽度, 当超过此宽度时,文本会溢出隐藏,并显示... | number | - | - |\r\n| closeable | 标签是否支持删除操作, 配置后会在标签文本右侧显示\"x\"删除图标按钮 | boolean | - | false |\r\n| corpid | 企业id, 若企业存在上下游关系,open-data-box渲染指定企业的员工或部门名称 | string | - | - |\r\n| theme | 主题色 |string| gray / blue | gray |\r\n\r\n### WeShineFilterTagItem Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ------- |-------------| --------- |\r\n| close | 删除图标按钮的点击事件 | - |"
},
{
"name": "FieldFactory",
"category": "PC端组件库",
"content": "## FieldFactory 自定义字段表单生成引擎\r\n\r\n`FieldFactory` 是一个高度灵活的自定义字段表单生成引擎,旨在通过配置化的方式快速构建复杂的表单组件。开发者只需提供组件的配置选项,即可动态生成多种常见的表单元素,如输入框、单选框、 日期选择器、附件组件等。每个组件都具备完整的功能,包括获取值、设置状态、校验等,简化了表单的开发流程。\r\n\r\n#### 主要特点:\r\n- **多组件类型支持**:支持多种表单组件类型,如 `formInput`(输入框)、`formRadio` (单选框)、`formDateTimePicker`(日期时间选择器)、`formCascade`(级联选择器)、`formUpload`(附件)、`formSelect`(选择器) 、`formSelectTag`(标签选择器),满足不同场景的表单需求。\r\n- **配置灵活**:通过简单的配置即可生成复杂的表单结构,支持字段分组、必填校验、自定义校验等功能,适应多样化的业务场景。\r\n- **多场景适配**:支持创建、编辑、详情查看等多种场景模式,组件的布局和交互方式会根据场景自动调整,提升用户体验。\r\n- **事件驱动**:通过 `change` 事件监听组件值的变化,集中处理表单数据的变动,便于统一管理。\r\n- **丰富的 API**:提供 `getValue`、`setState`、`validate` 等方法,方便开发者获取表单数据、动态修改组件状态以及进行表单校验。\r\n\r\n`FieldFactory` 适用于创建、编辑、详情展示等多种表单场景,帮助开发者快速构建高效、灵活的表单界面,极大地提升了表单开发的效率和可维护性。\r\n\r\n### 导入方式\r\n需从 `@wshoto/pc-base-ui` 中具名导入 `FieldFactory` 组件, 并在页面中注册\r\n\r\n```js\r\n<script>\r\n import { FieldFactory } from \"@wshoto/pc-base-ui\";\r\n\r\n export default {\r\n components: {\r\n FieldFactory\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 基础用法\r\n\r\n:::demo\r\n```html\r\n\r\n<template>\r\n <div style=\"display: flex;\">\r\n <div style=\"flex: 1;padding: 24px; border: 1px solid #e8e9ed;margin-right: 10px;\">\r\n <h4 class=\"title\">create/edit(创建/编辑场景)</h4>\r\n <field-factory\r\n ref=\"factory\"\r\n shape=\"create\"\r\n :options=\"options\"\r\n @change=\"change\"\r\n />\r\n </div>\r\n <div style=\"flex: 1;padding: 24px; border: 1px solid #e8e9ed;margin-right: 10px;\">\r\n <h4 >info(详情场景)</h4>\r\n <field-factory\r\n shape=\"info\"\r\n :options=\"options\"\r\n @change=\"change\"\r\n />\r\n </div>\r\n <div style=\"flex: 1;padding: 24px; border: 1px solid #e8e9ed;margin-right: 10px;\">\r\n <h4 >info-up-down(详情-上下布局)</h4>\r\n <field-factory\r\n shape=\"info-up-down\"\r\n :options=\"options\"\r\n @change=\"change\"\r\n />\r\n </div>\r\n <div style=\"flex: 1;padding: 24px; border: 1px solid #e8e9ed\">\r\n <h4 >collect_form_info(收集表定制场景)</h4>\r\n <field-factory\r\n shape=\"collect_form_info\"\r\n :options=\"options\"\r\n @change=\"change\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n shape: 'create',\r\n options: [\r\n {\r\n groupTitle: '基础信息',\r\n forms: [\r\n {\r\n type: 'formInput',\r\n props: {\r\n sort: 1,\r\n field: 'field-1',\r\n label: '单行文本',\r\n value: '输入的文本'\r\n }\r\n },\r\n {\r\n type: 'formInput',\r\n props: {\r\n sort: 2,\r\n field: 'field-2',\r\n label: '多行文本',\r\n value: '',\r\n type: 'textarea'\r\n }\r\n },\r\n {\r\n type: 'formInput',\r\n props: {\r\n sort: 3,\r\n field: 'field-3',\r\n label: '数字',\r\n value: 120,\r\n type: 'number',\r\n required: true\r\n }\r\n },\r\n {\r\n type: 'formRadio',\r\n props: {\r\n sort: 4,\r\n field: 'field-4',\r\n value: '男',\r\n label: '性别',\r\n options: [\r\n { label: '1', name: '男' },\r\n { label: '2', name: '女' }\r\n ]\r\n }\r\n },\r\n ]\r\n },\r\n {\r\n groupTitle: '更多信息',\r\n forms: [\r\n {\r\n type: 'formDateTimePicker',\r\n props: {\r\n sort: 5,\r\n field: 'field-5',\r\n label: '日期',\r\n value: '',\r\n placeholder: '请选择时间',\r\n required: true\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker',\r\n props: {\r\n sort: 6,\r\n field: 'field-6',\r\n label: '日期时间',\r\n value: '2022-02-25 08:00:00',\r\n type: 'datetime',\r\n placeholder: '请选择时间'\r\n }\r\n },\r\n {\r\n type: 'formSelect',\r\n props: {\r\n sort: 7,\r\n field: 'field-7',\r\n label: '单选',\r\n value: [{ id: '1', name: '黄金糕'}],\r\n options: [\r\n {\r\n id: '1',\r\n name: '黄金糕'\r\n },\r\n {\r\n id: '2',\r\n name: '双皮奶'\r\n },\r\n {\r\n id: '3',\r\n name: '蚵仔煎'\r\n }\r\n ]\r\n }\r\n },\r\n {\r\n type: 'formSelect',\r\n props: {\r\n sort: 8,\r\n field: 'field-8',\r\n label: '多选',\r\n value: [],\r\n multiple: true,\r\n options: [\r\n {\r\n id: '1',\r\n name: '黄金糕'\r\n },\r\n {\r\n id: '2',\r\n name: '双皮奶'\r\n },\r\n {\r\n id: '3',\r\n name: '蚵仔煎'\r\n }\r\n ]\r\n }\r\n },\r\n {\r\n type: 'formCascade',\r\n props: {\r\n sort: 9,\r\n field: 'field-9',\r\n label: '地区',\r\n value: [],\r\n area: true\r\n }\r\n },\r\n {\r\n type: 'formCascade',\r\n props: {\r\n sort: 10,\r\n field: 'field-10',\r\n label: '级联',\r\n value: [{ id: '3', name: '建国' }],\r\n options: [\r\n {\r\n id: '1',\r\n name: '研发中心',\r\n children: [\r\n {\r\n id: '2',\r\n name: '前端',\r\n children: [\r\n {\r\n id: '3',\r\n name: '建国'\r\n },\r\n {\r\n id: '4',\r\n name: '居易'\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n },\r\n {\r\n type: 'formSelectTag',\r\n props: {\r\n sort: 11,\r\n field: 'field-11',\r\n label: '选标签',\r\n value: []\r\n }\r\n },\r\n {\r\n type: 'formUpload',\r\n props: {\r\n sort: 12,\r\n field: 'field-12',\r\n label: '上传素材',\r\n value: []\r\n }\r\n },\r\n ]\r\n }\r\n ],\r\n };\r\n },\r\n methods: {\r\n change(params) {\r\n this.$message.info(JSON.stringify(params));\r\n },\r\n\r\n getFormData() {\r\n const formRef = this.$refs.factory;\r\n if (formRef && typeof formRef.getValue === 'function') {\r\n const result = formRef.getValue();\r\n this.$message.info(JSON.stringify(result));\r\n }\r\n },\r\n\r\n validateFrom() {\r\n const formRef = this.$refs.factory;\r\n if (formRef && typeof formRef.validate === 'function') {\r\n formRef.validate((state, payload) => {\r\n // do something\r\n if(state) {\r\n this.$message.success('检验通过');\r\n } else {\r\n this.$message.error('检验不通过');\r\n }\r\n })\r\n }\r\n },\r\n\r\n validateField() {\r\n const formRef = this.$refs.factory;\r\n if (formRef && typeof formRef.validateField === 'function') {\r\n formRef.validateField('field-5', (state) => {\r\n // do something\r\n if(state) {\r\n this.$message.success('检验通过');\r\n } else {\r\n this.$message.error('检验不通过');\r\n }\r\n })\r\n }\r\n },\r\n\r\n modifyValueByField() {\r\n const formRef = this.$refs.factory;\r\n if (formRef && typeof formRef.setState === 'function') {\r\n formRef.setState('field-2', '所有产研人都要追求极致的交付质量');\r\n }\r\n }\r\n }\r\n };\r\n</script>\r\n<style scoped>\r\n .group-content {\r\n display: flex;\r\n }\r\n .block {\r\n flex: 1\r\n }\r\n</style>\r\n```\r\n:::\r\n\r\n### 生成单个基础表单组件\r\n通过 `FieldFactory`,开发者可以轻松生成单个基础表单组件。只需在 `options` 中配置组件类型和相关属性,`FieldFactory` 会自动渲染对应的基础表单组件。适用于需要快速生成单个表单字段的场景。\r\n\r\n```html\r\n<field-factory shape=\"create\" :options=\"options\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n fieldType: 1, // 字段类型\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n required: true, // 必填\r\n }\r\n }\r\n ]\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 生成多个基础表单组件\r\n`FieldFactory` 还支持通过配置 `options` 一次性生成多个基础表单组件。每个组件的配置项独立,开发者可以灵活定义每个字段的类型、标签、默认值等。适用于需要构建复杂表单的场景,能够大幅提升表单开发的效率。\r\n\r\n```html\r\n<field-factory shape=\"create\" :options=\"options\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n fieldType: 1, // 字段类型\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n required: true, // 必填\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 将基础表单组件分组\r\n`options` 属性的类型是 `Array<FieldProp | FormNode>`。当 `options` 数组中的子项类型为 `FieldProp` 时,基础表单组件会按照分组形式展示,并使用 `groupTitle` 属性作为组名。\r\n\r\n```html\r\n<field-factory shape=\"create\" :options=\"options\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n groupTitle: '分组一', // 分组名称\r\n forms: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n },\r\n {\r\n groupTitle: '分组二', // 分组名称\r\n forms: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-3', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-4', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 组件展示场景\r\n`shape` 属性决定了组件在不同场景下的交互方式和布局形式。根据 `shape` 的不同取值,组件的布局和可编辑性会有所变化:\r\n\r\n- 当 `shape` 的值为 `create` 或 `edit` 时,组件采用**上下布局**,表单字段是**可编辑**的,适用于创建或编辑数据的场景。\r\n\r\n- 当 `shape` 的值为 `info` 时,组件采用**左右布局**,仅展示字段信息,表单字段是**不可编辑**的,适用于查看详情的场景。\r\n\r\n- 当 `shape` 的值为 `info-up-down` 时,组件采用**上下布局**,仅展示字段信息,占位文本不展示,表单字段是**不可编辑**的。\r\n\r\n- 当 `shape` 的值为 `collect_form_info` 时,组件采用**上下布局**,展示\"收集表\"定制的表单样式,表单字段是**不可编辑**的。此时需要传递 `sort` 属性,字段标签前带有顺序编号。标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。字段之间用一条灰色的横线分割。\r\n\r\n\r\n```html\r\n<!-- 新建场景 -->\r\n<field-factory shape=\"create\" :options=\"options\" />\r\n\r\n<!-- 编辑场景 -->\r\n<field-factory shape=\"edit\" :options=\"options\" />\r\n\r\n<!-- 详情展示场景 -->\r\n<field-factory shape=\"info\" :options=\"options\" />\r\n\r\n<!-- 详情展示场景 上下布局 -->\r\n<field-factory shape=\"info-up-down\" :options=\"options\" />\r\n\r\n<!-- 收集表定制场景 -->\r\n<field-factory shape=\"collect_form_info\" :options=\"options\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory } from '@wshoto/pc-base-ui';\r\n\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n sort: 1,\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '123456', // 输入框绑定值\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n sort: 2,\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n value: '2024-08-08'\r\n }\r\n }\r\n ]\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 监听基础表单组件值的变化\r\n可以通过 `FieldFactory` 的 `change` 事件监听每个基础表单组件的值变化,并使用同一个 change 函数集中处理。这样,在每次基础表单组件的值发生变化时,都会触发该 `change` 函数,并将相应的变化值作为参数传递给该函数。通过这种方式,可以集中处理所有基础表单组件值的变化。\r\n\r\n```html\r\n<field-factory shape=\"create\" :options=\"options\" @change=\"change\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory, FieIdComponentFactoryTypes } from '@wshoto/pc-base-ui';\r\n\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n }\r\n },\r\n methods: {\r\n change(data: FieIdComponentFactoryTypes.Params) {\r\n if (data.field === 'field-1') {\r\n console.log(`字段名为field-1的组件值变成了${data.value}`);\r\n }\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n\r\n\r\n### 给基础表单组件设置值\r\n可以使用 `FieldFactory` 的 `setState` 方法为基础表单组件设置值。\r\n`setState` 方法的类型是 `(field: string, value: any) => void`。其中,参数 `field` 是基础表单组件的 `field` 属性的值,参数 `value` 表示要设置的值。`value` 的类型应与基础表单组件的 `value` 属性的类型相匹配。\r\n\r\n```html\r\n<field-factory ref=\"fieldFactoryRef\" shape=\"create\" :options=\"options\" />\r\n\r\n<ws-button @click=\"setState\">setState</ws-button>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory, WsButton } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n WsButton\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n }\r\n },\r\n methods: {\r\n // 将 field 为 field-1 的基础表单组件的值设置为 \"所有产研人都要追求极致的交付质量\"\r\n setState() {\r\n const factoryRef = this.$refs.fieldFactoryRef as InstanceType<typeof FieldFactory> | undefined;\r\n if (factoryRef) {\r\n factoryRef.setState('field-1', '所有产研人都要追求极致的交付质量');\r\n }\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 校验基础表单组件的值是否合法\r\n`FieldFactory` 提供了两个方法来校验基础表单组件的值:\r\n\r\n1. 使用 `validate` 方法可以对所有基础字段的值进行校验。`validate` 方法的类型是 `(callback: (state: boolean, payload: Params[]) => void) => void`。其中,参数 `state` 表示校验结果,当 `state` 为 `true` 时表示校验通过,否则表示校验不通过。参数 `payload` 是所有校验不通过的基础表单组件值的集合。\r\n\r\n2. 使用 `validateField` 方法可以对单个基础字段的值进行校验。`validateField` 方法的类型是 `(field: string, callback: (state: boolean) => void) => void`。其中,参数 `field` 是基础表单组件的 `field` 属性的值,参数 `state` 表示校验结果,当 `state` 为 `true` 时表示校验通过,否则表示校验不通过。\r\n\r\n```html\r\n<field-factory ref=\"fieldFactoryRef\" shape=\"create\" :options=\"options\" />\r\n\r\n<ws-button @click=\"validate\">validate</ws-button>\r\n<ws-button @click=\"validateField\">validateField</ws-button>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory, WsButton } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n WsButton\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n required: true\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n }\r\n },\r\n methods: {\r\n // 对所有基础表单组件做值校验\r\n validate() {\r\n const factoryRef = this.$refs.fieldFactoryRef as InstanceType<typeof FieldFactory> | undefined;\r\n if (factoryRef) {\r\n factoryRef.validate((state, payload) => {\r\n if (state) {\r\n console.log('校验通过');\r\n // do something\r\n } else {\r\n console.log(`${payload.length}个字段校验不通过`);\r\n // do something\r\n }\r\n });\r\n }\r\n },\r\n\r\n // 对 field 为 field-1 的基础表单组件做值校验\r\n validateField() {\r\n const factoryRef = this.$refs.fieldFactoryRef as InstanceType<typeof FieldFactory> | undefined;\r\n if (factoryRef) {\r\n factoryRef.validateField('field-1', (state) => {\r\n if (state) {\r\n console.log('校验通过');\r\n // do something\r\n } else {\r\n console.log('校验不通过');\r\n // do something\r\n }\r\n });\r\n }\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n\r\n### 如何自定义基础表单组件的校验规则\r\n\r\n基础表单组件默认会根据 `required` 属性判断该字段是否为必填项。如果需要自定义规则校验,可以通过给基础表单组件配置 `validator` 属性。`validator` 属性的类型是 `(value: any) => (Error | undefined)`。值发生变化时,会触发 `validator` 函数。如果校验不通过,需要返回一个 `Error` 对象,可以设置 `Error` 对象的 `message` 属性来显示校验不通过的提示样式。如果校验通过,可以返回其他数据类型。以下是一个示例,展示如何使用 `validator` 属性进行自定义规则校验:\r\n\r\n```html\r\n<field-factory shape=\"create\" :options=\"options\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n validator: (val: string) => {\r\n const max = 5;\r\n if (val.length > max) {\r\n return new Error(`不允许超过${max}个字符`);\r\n }\r\n }\r\n }\r\n }\r\n ]\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n\r\n### 获取基础表单组件的值\r\n可以使用 `FieldFactory` 的 `getValue` 方法来获取所有基础表单组件的当前值。\r\n`getValue` 方法的类型是 `() => Params[]`,它会返回所有基础表单组件的值集合。\r\n\r\n```html\r\n<field-factory ref=\"fieldFactoryRef\" shape=\"create\" :options=\"options\" />\r\n\r\n<ws-button @click=\"getValue\">getValue</ws-button>\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory, WsButton } from '@wshoto/pc-base-ui';\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory,\r\n WsButton\r\n },\r\n data () {\r\n return {\r\n options: [\r\n {\r\n type: 'formInput', // 组件名称\r\n props: {\r\n field: 'field-1', // 字段唯一id\r\n label: '单行文本', // 标签文本\r\n value: '', // 输入框绑定值\r\n }\r\n },\r\n {\r\n type: 'formDateTimePicker', // 组件名称\r\n props: {\r\n field: 'field-2', // 字段唯一id\r\n label: '日期时间', // 标签文本\r\n }\r\n }\r\n ]\r\n }\r\n },\r\n methods: {\r\n // 获取基础表单组件的值\r\n getValue() {\r\n const factoryRef = this.$refs.fieldFactoryRef as InstanceType<typeof FieldFactory> | undefined;\r\n if (factoryRef) {\r\n const result = factoryRef.getValue();\r\n console.log(result);\r\n }\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n### 字段类型与基础表单组件的映射关系\r\n字段类型与基础表单组件的关系是一种映射关系,通过字段类型来确定需要使用哪种基础表单组件来展示对应的字段。不同的字段类型对应不同的基础表单组件,例如单行文本、多行文本、数字输入框等字段类型可以使用同一个基础表单组件来展示,即 formInput 组件。这种映射关系可以帮助开发者根据字段类型快速选择合适的基础表单组件,从而构建符合业务需求的表单界面。\r\n\r\n| 字段名 | 字段类型 | 对应的基础组件 | 运行效果描述 |\r\n|------------- |---------- |------------------ |----------------------|\r\n| 单行文本 | 1 | formInput | 该字段通过formInput组件实现单行文本输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项。输入框右侧会动态显示当前输入的字符数,并标注最大字符限制。默认最大可输入30个字符。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 多行文本 | 2 | formInput | 该字段通过formInput组件实现多行文本输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项。输入框右侧会动态显示当前输入的字符数,并标注最大字符限制。默认最大可输入500个字符。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 数字输入框 | 3 | formInput | 该字段通过formInput组件实现数字输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局。如果标签带有红色星号,表示这是一个必填项。输入框右侧还有一个“X”按钮,允许用户清除已输入的数字。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 下拉单选 | 4 | formSelect | 该字段通过formSelect组件实现下拉单选功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局。选择框右侧有一个向下的箭头图标,表示该框是一个可展开的下拉菜单。用户可以点击选择框来展开或收起下拉菜单。展开后,用户可以从列表中选择一个选项,选中的选项会显示在选择框内,替换之前的选项。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与输入值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 下拉多选 | 5 | formSelect | 该字段通过formSelect组件实现下拉多选功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局。选择框右侧有一个向下的箭头图标,表示该框是一个可展开的下拉菜单。用户可以点击选择框来展开或收起下拉菜单。展开后,用户可以从列表中选择一个或多个选项,选中的选项会显示在选择框内,并用逗号分隔。用户可以通过再次点击已选项来 取消选择,或点击未选项来新增选择。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 级联选择器 | 6 | formCascade | 该字段通过formCascade组件实现级联选择器功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局。选择框右侧有一个向下的箭头图标,表示该框是一个可展开的下拉菜单。用户可以点击选择框来展开或收起下拉菜单。展开后,用户可以从第一级开始选择,选择某个选项后会展开下一级的选项,直到用户选择到最终的具体选项。每个层级的选择会影响下一级的可选项,用户可以通过逐级选择来确定最终的选项。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 日期选择器 | 7 | formDateTimePicker | 该字段通过formDateTimePicker组件实现日期选择器功能,日期格式:YYYY-MM-DD。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局。如果标签名带有红色星号,表示这是一个必填项。输入框内显示当前选中的日期“YYYY-MM-DD”,左侧有一个日历图标,表示该输入框与日期选择器相关联。输入框右侧还有一个“X”按钮,允许用户清除已选的日期。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 日期时间选择器 | 8 | formDateTimePicker | 该字段通过formDateTimePicker组件实现日期选择器功能,日期格式:YYYY-MM-DD HH:mm。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局。如果标签名带有红色星号,表示这是一个必填项。输入框内显示当前选中的日期“YYYY-MM-DD HH:mm”,左侧有一个日历图标,表示该输入框与日期选择器相关联。输入框右侧还有一个“X”按钮,允许用户清除已选的日期。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 附件 | 10 | formUpload | 该字段通过formUpload组件实现附件功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与附件功能按钮的上下排列布局,如果标签带有红色星号,表示这是一个必填项。用户可以通过点击“+ 新建”按钮创建新的临时素材,或者通过点击“+ 从素材中心中选择”按钮从已有的素材库中选择素材。所创建或选择的素材以列表形式展示,每个已选素材的右侧有一个\"x\"按钮,允许用户移除当前素材。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 手机号 | 11 | formInput | 该字段通过formInput组件实现手机号输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项,输入框失焦时会校验输入的手机号是否合法。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 座机 | 12 | formInput | 该字段通过formInput组件实现座机输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项,输入框失焦时会校验输入的座机是否合法。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 邮箱 | 13 | formInput | 该字段通过formInput组件实现邮箱输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项,输入框失焦时会校验输入的邮箱是否合法。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 标签选择器 | 15 | formSelectTag | 该字段通过formSelectTag组件实现选择标签功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局,如果标签带有红色星号,表示这是一个必填项。用户可以点击选择框区域弹起\"标签选择对话框\"输入框,选中的标签会显示在选择框内,并用逗号分隔。右侧还有一个“X”按钮,允许用户清除已选择的标签。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 单选框 | 16 | formRadio | 该字段通过formRadio组件实现单选框功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项。用户可以点击其中一个选项的圆形按钮来进行选择。选中某个选项后,按钮会被填充为蓝色,其他选项会自动取消选中状态,确保在同一时间只能选择一个选项。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 地区选择器 | 17 | formCascade | 该字段通过formCascade组件实现地区选择器功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与选择框的上下排列布局。选择框右侧有一个向下的箭头图标,表示该框是一个可展开的下拉菜单。用户可以点击选择框来展开或收起下拉菜单。展开后,用户可以从第一级开始选择,选择某个省级行政区后会展开下一级的市级行政区,接着选择市级行政区后会展开区级行政区。每个层级的选择会影响下一级的可选项,用户可以通过逐级选择来确定最终的地区。。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 地理位置选择器 | 18 | formLocation | 该字段通过formLocation组件实现地理位置选择器功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项。在PC端,无法选择地理位置,用户会收到默认提示信息:“桌面端无法获取位置,请在移动端打开获取位置信息”。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 身份证号 | 20 | formInput | 该字段通过formInput组件实现身份证号输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项,输入框失焦时会校验输入的身份证号是否合法,默认最大可输入18个字符。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n| 银行卡号 | 21 | formInput | 该字段通过formInput组件实现银行卡号输入功能。具体运行效果依shape属性的不同而有所区别:在创建或编辑场景(shape为create或edit),组件展示为标签与输入框的上下排列布局,如果标签带有红色星号,表示这是一个必填项,输入框失焦时会校验输入的行卡号是否合法,默认最大可输入19个字符。在详情展示场景(shape为info),组件用于展示字段的已有值,此时标签与已有值并列排列。在上下布局展示场景(shape为info-up-down),组件同样用于展示字段的已有值,但是标签与已有值采用上下排列的方式呈现。在收集表定制场景(shape为collect_form_info),组件以预览模式展示。每个字段的标签前都带有顺序编号,标签下方展示占位文本,而实际输入的数据则显示在占位文本的下方。整体布局采用上下结构,使得用户能够快速理解并浏览布局。 |\r\n\r\n### 工具方法\r\n在业务中,通常我们需要先获取自定义字段的配置信息,然后将这些配置信息转换成自定义组件引擎所需的数据格式。\r\n\r\n转换方法 `transferField` 的类型是 `(shape: ShapeTypes, options: Array<FieldGroupNode | FieldNode>, values?: Values, propsHook?: (option: FieldNode) => Record<string, any>) => Array<FormNode | FieldProp>`。其中,参数 `shape` 表示使用场景,参数 `options` 是自定义字段的配置信息,参数 `values` 是每个字段对应的值。属性 `propsHook` 是构造基础表单组件 `props` 时的钩子函数,`propsHook` 的类型是:`(option: FieldNode) => Record<string, any>`, 参数 `option` 是字段属性信息,返回值为新增的属性对象。如果不需要修改属性,则返回空对象。\r\n\r\n```html\r\n<field-factory shape=\"create\" :options=\"options\" />\r\n\r\n<script lang=\"ts\">\r\n import Vue from 'vue';\r\n import { FieldFactory, FieldComponentFactoryUtils, FieIdComponentFactoryConstants, FieIdComponentFactoryTypes } from '@wshoto/pc-base-ui';\r\n\r\n export default Vue.extend({\r\n components: {\r\n FieldFactory\r\n },\r\n data () {\r\n return {\r\n options: [] as Array<FieIdComponentFactoryTypes.FormNode | FieIdComponentFactoryTypes.FieldProp>\r\n }\r\n },\r\n created () {\r\n Promise.all([this.getFieldSetting(), this.getFieldValue()]).then(([fieldSetting, fieldValues]) => {\r\n this.options = FieldComponentFactoryUtils.transferField(FieIdComponentFactoryConstants.ShapeTypes.CREATE, fieldSetting, fieldValues, (option) => {\r\n // 判断如果 fieldKey 等于 description, 修改基础表单组件的props\r\n if (option.fieldKey === 'description') {\r\n return {\r\n placeholder: '请输入描述'\r\n }\r\n }\r\n return {};\r\n })\r\n })\r\n },\r\n methods: {\r\n // 模拟获取自定义字段配置\r\n getFieldSetting(): Promise<Array<FieIdComponentFactoryTypes.FieldGroupNode | FieIdComponentFactoryTypes.FieldNode>> {\r\n return Promise.resolve([\r\n {\r\n sort: 1,\r\n groupId: '1687130022415984002',\r\n groupName: '更多信息',\r\n fieldId: '1687130022415912121',\r\n fieldName: 'group-1',\r\n readonlyFlag: 0,\r\n requiredFlag: 1,\r\n sortableFlag: 1,\r\n supportEditName: 1,\r\n systemFlag: 1,\r\n defaultFlag: 1,\r\n fields: [\r\n {\r\n sort: 1,\r\n fieldKey: 'description',\r\n fieldId: '1687130022164325762',\r\n fieldName: '描述',\r\n readonlyFlag: 0,\r\n requiredFlag: 1,\r\n sortableFlag: 1,\r\n systemFlag: 0,\r\n defaultFlag: 0,\r\n type: 2,\r\n params: []\r\n },\r\n {\r\n sort: 2,\r\n fieldKey: 'mf_customer_102',\r\n fieldId: '1687130022164325761',\r\n fieldName: '性别',\r\n readonlyFlag: 0,\r\n requiredFlag: 1,\r\n sortableFlag: 1,\r\n systemFlag: 0,\r\n defaultFlag: 0,\r\n type: 16,\r\n params: [\r\n { id: '1514699294390644737', name: '男' },\r\n { id: '1514699294407421953', name: '女' }\r\n ]\r\n }\r\n ]\r\n }\r\n ]);\r\n },\r\n\r\n // 模拟获取自定义字段的值\r\n getFieldValue(): Promise<FieIdComponentFactoryTypes.Values> {\r\n return Promise.resolve({\r\n description: '这里是一段描述',\r\n mf_customer_102: [{ id: '1514699294390644737', name: '男' }]\r\n })\r\n }\r\n }\r\n })\r\n</script>\r\n```\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n| options | 组件配置 | Array\\<FieldProp \\| FormNode\\> | - | [] |\r\n\r\n\r\n### Events\r\n| 名称 | 说明 | 回调参数 |\r\n|---------- |-------- |---------- |\r\n|change | 当基础组表单件值发生变化时触发 | params: Params |\r\n\r\n\r\n### Methods\r\n\r\n通过refs调用\r\n\r\n| 名称 | 说明 | 类型 |\r\n| ------- | ------------------ | --------- |\r\n| getValue | 通过ref调用,调用可获取所有基础表单组件的值 | () => Params[] |\r\n| setState | 通过ref调用,根据 `field` 属性设置对应基础表单组件的值 | (field: string, value: any) => void |\r\n| validate | 通过ref调用,用于校验所有基础表单组件的值是否合法 | (callback: ((state: boolean; payload: Params[]) => void)) => void |\r\n| validateField | 通过ref调用,根据 `field` 属性校验对应基础表单组件的值是否合法 | (field: string,callback: ((state: boolean) => void)) => void | \r\n\r\n\r\n\r\n### 内置的基础表单组件\r\n#### formInput 输入框\r\n##### Attributes\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | string | - | - |\r\n|type | 输入框类型 | string | `text` 单行文本;<br>`textarea` 多行文本;<br>`number` 数字输入框 | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|placeholder | 输入框占位文本 | string | - | 请输入 |\r\n|limit | 最大输入长度 | number | - | `type` 是 `text` 时,默认值是30;`type` 是 `textarea` 时,默认值是500;`type` 是 `number` 时,默认值是99999; |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: string) => (Error \\| undefined) | - | - |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n\r\n\r\n#### formRadio 单选框\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | string \\| Array\\<OptionNode\\> | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|options | 选项 | Array\\<RadioProp\\> | - | - |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: string) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请输入 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n\r\n\r\n#### formDateTimePicker 日期时间选择器\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | string | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: string) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请选择 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n|minDate | 时间最小值 | number | - | - |\r\n|maxDate | 时间最大值 | number | - | - |\r\n|type | 时间类型 | string | `date` 日期:YYYY-MM-DD;<br>`datetime` 日期时间: YYYY-MM-DD HH:mm:ss; | - |\r\n\r\n\r\n#### formCascade 级联选择器\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | string \\| Array\\<OptionNode\\> \\| AreaOption\\> | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: Array\\<string\\>) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请选择 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n|area | 是否是选择地理位置,如果值为true,开发者不用再传 `options` 属性,组件内部会创建城市列表数据 | boolean | - | false |\r\n\r\n#### formUpload 附件\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | Array\\<UploadFileNode\\> | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: Array\\<UploadFileNode\\>) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请输入 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n\r\n\r\n#### formSelect 选择器\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | Array\\<OptionNode\\> | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: Array\\<string\\> \\| string) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请选择 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n\r\n\r\n#### formSelectTag 标签选择器\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 绑定值 | Array\\<Tag\\> | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: Array\\<Tag\\>) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请选择 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n|isFilterAuto | 是否过滤自动标签 | boolean | - | false |\r\n|type | 选择的标签类型 | string | `customer` 客户标签;<br>`business` 业务标签;<br> `group` 客户群标签; | customer |\r\n|isFilterBusinessTag | 是否过滤业务标签 | boolean | - | false |\r\n|businessTagRange | 业务标签查询范围,1:我是管理员的规则组标签;2:我所在管理组的规则组标签;3:全部管理组的业务标签;4:带权限查询全部管理组标签; | number | 1\\|2\\|3\\|4 | 4 |\r\n|selectedNoAuthBusinessTagList | 已选的无权限业务标签集合 | Array\\<selectedNoAuthBusinessTagListTypes\\> | - | [] |\r\n|showBusinessTag | INFO模式是否展示业务标签 | boolean | - | false |\r\n|tips | 主要标签提示 | string | - | - |\r\n|sideTips | 副标签提示 | string | - | - |\r\n\r\n\r\n#### formLocation 附件\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n|field | 字段名 | string | - | - |\r\n|fieldType | 字段类型 | number | - | - |\r\n|label | 标签文本 | string | - | - |\r\n|value | 地理位置文本 | string | - | - |\r\n|required | 必填 | boolean | - | false |\r\n|disabled | 禁止输入 | boolean | - | false |\r\n|validator | 校验函数,返回Error代表校验不通过,反之代表校验通过。 | (value: string) => (Error \\| undefined) |\r\n|placeholder | 输入框占位文本 | string | - | 请选择 |\r\n|shape | 使用场景,不同场景对应组件不同的展示形态。 | string | `create` 创建;<br>`edit` 编辑;<br>`info` 详情(左右布局);<br>`info-up-down` 详情(上下布局);<br>`collect_form_info` 详情(收集表定制); | create |\r\n\r\n### 常量\r\n#### 导入方式\r\n可以从 `@wshoto/pc-base-ui` 库中导入 `FieIdComponentFactoryConstants`,这是一个包含组件相关常量的 TypeScript 命名空间。以下是示例用法:\r\n``` ts\r\nimport { FieIdComponentFactoryConstants } from '@wshoto/pc-base-ui';\r\n\r\nconst { ShapeTypes } = FieIdComponentFactoryConstants;\r\n```\r\n\r\n#### 内置的常量\r\n`@wshoto/pc-base-ui` 提供了一些常量,可以在代码中使用。以下是常量的一些内置类型:\r\n- `FieIdComponentFactoryConstants.ShapeTypes`: 包含了一些常见的场景类型,比如创建、编辑等。\r\n- `FieIdComponentFactoryConstants.FieIdTypes`: 包含了一些表单字段的类型,比如单行文本、日期等。\r\n- `FieIdComponentFactoryConstants.BaseComponentsType`: 包含了一些基础组件的类型,比如输入框、日期时间选择器等。\r\n- `FieIdComponentFactoryConstants.componentsMapping`: 包含了组件的映射关系,可以用于动态渲染组件。\r\n- `FieIdComponentFactoryConstants.MODULE_KEYS`: 包含了一些模块的键值对,用于标识不同的模块。\r\n- `FieIdComponentFactoryConstants.disabledMsg`: 包含了一些禁用状态的提示信息。\r\n- `FieIdComponentFactoryConstants.UploadStatusEnum`: 包含了一些上传状态的枚举值,比如上传中、上传成功等。\r\n\r\n```ts\r\n// 组件展示场景枚举\r\nenum ShapeTypes {\r\n CREATE = 'create', // 创建\r\n EDIT = 'edit', // 编辑\r\n INFO = 'info', // 信息 左右布局\r\n INFO_UP_DOWN = 'info-up-down', // 上下布局\r\n COLLECT_FORM_INFO = 'collect_form_info' // 收集表预览\r\n};\r\n\r\n// 字段类型枚举\r\nenum FieIdTypes {\r\n SINGLE_LINE_INPUT = 1, // 单行文本\r\n MULTI_LINE_INPUT = 2, // 多行文本\r\n NUMBER_INPUT = 3, // 数字输入框\r\n SINGLE_SELECT = 4, // 下拉单选\r\n MULTI_SELECT = 5, // 下拉多选\r\n CASCADE = 6, // 级联\r\n DATE = 7, // 日期\r\n DATE_TIME = 8, // 日期 + 时间\r\n TIME = 9, // 时间, 暂无\r\n UPLOAD_FILE = 10, // 附件\r\n MOBILE_PHONE = 11, // 手机号\r\n LANDLINE = 12, // 座机\r\n MAIL = 13, // 邮箱\r\n ASSOCIATION = 14, // 关联\r\n SELECT_TAG = 15, // 选择标签\r\n RADIO = 16, // 单选radio\r\n AREA = 17, // 地区\r\n LOCATION = 18, // 位置\r\n AT = 19, // at 富文本\r\n ID_NUMBER = 20, // 身份证号\r\n BANK_NUMBER= 21, // 银行卡号\r\n SINGLE_PICTURE = 22, // 单选图片\r\n MULTI_PICTURE = 23 // 多选图片\r\n};\r\n\r\n// 组表表单组件枚举\r\nenum BaseComponentsType {\r\n formInput = 'formInput',\r\n formRadio = 'formRadio',\r\n formDateTimePicker = 'formDateTimePicker',\r\n formCascade = 'formCascade',\r\n formUpload = 'formUpload',\r\n formSelect = 'formSelect',\r\n formSelectTag = 'formSelectTag',\r\n formPicture = 'formPicture',\r\n WsShineAt = 'WsShineAt',\r\n formLocation = 'formLocation',\r\n}\r\n\r\n// 字段类型与基础表单组件映射关系\r\nconst componentsMapping = {\r\n [FieIdTypes.SINGLE_LINE_INPUT]: BaseComponentsType.formInput,\r\n [FieIdTypes.MULTI_LINE_INPUT]: BaseComponentsType.formInput,\r\n [FieIdTypes.NUMBER_INPUT]: BaseComponentsType.formInput,\r\n [FieIdTypes.SINGLE_SELECT]: BaseComponentsType.formSelect,\r\n [FieIdTypes.MULTI_SELECT]: BaseComponentsType.formSelect,\r\n [FieIdTypes.CASCADE]: BaseComponentsType.formCascade,\r\n [FieIdTypes.DATE]: BaseComponentsType.formDateTimePicker,\r\n [FieIdTypes.DATE_TIME]: BaseComponentsType.formDateTimePicker,\r\n [FieIdTypes.TIME]: BaseComponentsType.formDateTimePicker,\r\n [FieIdTypes.UPLOAD_FILE]: BaseComponentsType.formUpload,\r\n [FieIdTypes.MOBILE_PHONE]: BaseComponentsType.formInput,\r\n [FieIdTypes.LANDLINE]: BaseComponentsType.formInput,\r\n [FieIdTypes.MAIL]: BaseComponentsType.formInput,\r\n [FieIdTypes.SELECT_TAG]: BaseComponentsType.formSelectTag,\r\n [FieIdTypes.RADIO]: BaseComponentsType.formRadio,\r\n [FieIdTypes.AREA]: BaseComponentsType.formCascade,\r\n [FieIdTypes.ID_NUMBER]: BaseComponentsType.formInput,\r\n [FieIdTypes.BANK_NUMBER]: BaseComponentsType.formInput,\r\n [FieIdTypes.SINGLE_PICTURE]: BaseComponentsType.formPicture,\r\n [FieIdTypes.MULTI_PICTURE]: BaseComponentsType.formPicture,\r\n [FieIdTypes.AT]: BaseComponentsType.WsShineAt,\r\n [FieIdTypes.LOCATION]: BaseComponentsType.formLocation\r\n};\r\n\r\n// 业务侧模块\r\nenum MODULE_KEYS {\r\n CLUE = 'clue', // 线索\r\n CUSTOMER = 'customer', // 客户\r\n COMPANY = 'company', // 企业\r\n FOLLOW = 'follow', // 跟进\r\n RETURNED = 'returned', // 回款\r\n ORDER = 'order', // 订单\r\n OPPORTUNITY = 'opportunity', // 商机\r\n GOODS = 'selfgoods' // 自定义商品\r\n}\r\n\r\n// 禁止编辑提示\r\nconst disabledMsg = '企业管理员已设置该数据不能编辑';\r\n\r\n// 附件组件上传标识枚举\r\nenum UploadStatusEnum {\r\n SUCCESS = 1, // 上传成功\r\n PENDING = 2, // 上传中\r\n FAILED = 3, // 上传失败\r\n};\r\n\r\n```\r\n\r\n\r\n\r\n### 类型定义\r\n#### 导入方式\r\n可以从 `@wshoto/pc-base-ui` 库中导入 `FieIdComponentFactoryTypes`,这是一个包含组件相关类型的 TypeScript 命名空间。以下是示例用法:\r\n\r\n```ts\r\nimport { FieIdComponentFactoryTypes } from '@wshoto/pc-base-ui';\r\n\r\ntype OptionNode = FieIdComponentFactoryTypes.OptionNode\r\n```\r\n\r\n内置的类型包括:\r\n- `FieIdComponentFactoryTypes.RadioProp`: 单选框组件的属性类型定义。\r\n- `FieIdComponentFactoryTypes.CascadeProp`: 级联选择组件的属性类型定义。\r\n- `FieIdComponentFactoryTypes.SelectProp`: 下拉选择框组件的属性类型定义。\r\n- `FieIdComponentFactoryTypes.FormProp`: 表单组件的属性类型定义。\r\n- `FieIdComponentFactoryTypes.FormNode`: 表单节点的类型定义。\r\n- `FieIdComponentFactoryTypes.FieldProp`: 表单字段组件的属性类型定义。\r\n- `FieIdComponentFactoryTypes.UploadFileNode`: 上传文件节点的类型定义。\r\n- `FieIdComponentFactoryTypes.Params`: 单个组件获取值的类型定义。\r\n- `FieIdComponentFactoryTypes.FieldNode`: 表单字段节点的类型定义。\r\n- `FieIdComponentFactoryTypes.FieldGroupNode`: 表单字段组节点的类型定义。\r\n- `FieIdComponentFactoryTypes.Values`: 回显表单值的类型定义。\r\n```ts\r\n\r\n// 选择器,级联选择器组件的options属性的数据类型\r\ntype OptionNode = {\r\n id: string; // 选项id\r\n name: string; // 选项名称\r\n children?: OptionNode[]; // 子集\r\n}\r\n\r\n// 单选框\r\ntype RadioProp = {\r\n label: string; // 选项label\r\n name: string; // 选项名称\r\n}\r\n\r\n// 地理位置\r\ntype AreaOption = {\r\n code: string; // 城市编码\r\n name: string; // 城市名称\r\n}\r\n\r\ninterface Tag {\r\n tagId: string; // 标签id\r\n tagName: string; // 标签名称\r\n order?: number; // 标签顺序\r\n singleType: 1 | 2 | 3; // 1 - 企业标签 2 - 业务标签 3 - 无权限的业务标签\r\n groupId?: string; // 标签组id\r\n}\r\n\r\ntype UploadFileNode = {\r\n id: number; // 素材id\r\n createTime: string; // 创建时间\r\n creator: string; // 创建人\r\n tenantId: string; // 租户id\r\n title: string; // 素材名称\r\n type: string; // 素材类型\r\n materialType: number; // 素材类型\r\n sendNum?: number; // 发送次数\r\n visitNum?: number; // 访问次数\r\n uuid?: string; // uuid\r\n keyId?: string; // keyId\r\n imageBase?: number; // 封面图id\r\n imageBaseUrl?: string; // 封面图url\r\n originalLink?: string; // 原始链接\r\n [prop: string]: any;\r\n}\r\n\r\n\r\ninterface selectedNoAuthBusinessTagListTypes {\r\n groupId: string; // 标签组id\r\n groupName: string; // 标签组名称\r\n tagName: string; // 标签名称\r\n tagId: string; // 标签id\r\n type: number; // 标签类型\r\n strategyId: number; // 业务标签组 ID\r\n manageGroupName: string; // 业务标签管理组名称\r\n}\r\n\r\n\r\n// 生成组件配置的类型\r\ntype FormNode = {\r\n type: string; // 字段类型对应的基础表单组件名称,例如:formInput\r\n props: {\r\n field: string; // 字段id\r\n label: string; // 字段的label\r\n value?: any; // 字段的值\r\n placeholder?: string; // 输入框的placeholder\r\n required?: boolean; // 是否必填\r\n disabled?: boolean; // 是否禁止修改\r\n maxlength?: string; // 最大长度\r\n multiple?: boolean; // 单选/多选字段,是否多选\r\n area?: boolean; // 级联字段是否选择地区\r\n options?: OptionNode[]; // 选项\r\n validator?: <T>(params: T) => (Error | undefined); // 单个字段的自定义校验\r\n }\r\n}\r\n\r\n// 生成组件配置的类型\r\ntype FieldProp = {\r\n groupTitle: string; // 分组名称\r\n forms: FormNode[]; // 字段集合\r\n}\r\n\r\n\r\n// 组件值发生变化时,触发的change事件携带的参数。若调用getValue, 返回 Params[]\r\ntype Params = {\r\n field: string; // 字段id\r\n fieldType?: number; // 字段类型\r\n label: string; // 字段label\r\n value: any; // 值\r\n required?: boolean; // 是否必填\r\n system: boolean; // 是否系统字段\r\n default: boolean; // 是否默认字段\r\n}\r\n\r\n\r\ntype FieldNode = {\r\n sort: number; // 顺序\r\n fieldKey: string; // 字段key\r\n fieldId: string; // 字段id\r\n fieldName: string; // 字段名称\r\n readonlyFlag: 0 | 1; // 是否只读\r\n requiredFlag: 0 | 1; // 是否必填\r\n sortableFlag: 0 | 1, // 是否允许排序\r\n systemFlag: 0 | 1; // 是否是系统字段\r\n defaultFlag: 0 | 1; // 是否是模块默认字段\r\n type: number; // 字段类型\r\n params: Array<CascadeProp>; // 字段选项参数\r\n fillHint?: string; // 填写提示\r\n verifyFlag?: 0 | 1; // 是否校验\r\n};\r\n\r\ntype FieldGroupNode = {\r\n sort: number; // 顺序\r\n groupId: string; // 分组id\r\n groupName: string; // 分组名称\r\n fieldId: string; // 字段id\r\n fieldName: string; // 字段名称\r\n readonlyFlag: 0 | 1; // 是否只读\r\n requiredFlag: 0 | 1; // 是否必填\r\n sortableFlag: 0 | 1; // 是否允许排序\r\n systemFlag: 0 | 1; // 是否是系统字段\r\n defaultFlag: 0 | 1; // 是否是默认字段\r\n fields: FieldNode[]; // 字段集合\r\n}\r\n\r\ntype Values = {\r\n [prop: string]: any;\r\n fieldMap?: {\r\n [prop: string]: any;\r\n }\r\n}\r\n\r\n```"
},
{
"name": "ws-tree",
"category": "PC端组件库",
"content": "## WeShineTree 树形组件\r\n\r\n- 树形组件,以 `vue-easy-tree` 作为基础的树形结构组件。展示清晰的层级结构,可展开或折叠。常用于企业通讯录的员工与部门展示、选择。\r\n- 支持多选、懒加载、节点禁用、虚拟滚动,支持节点图标的配置,提供了多种事件和钩子函数,适用于复杂的树形选择场景。\r\n- 与 [el-tree](/#/zh-CN/component/tree) 的区别主要在样式上,`we-shine-tree` 组件选中状态会有淡蓝色背景,且最右侧会有蓝色 `√` 图标,可多选属性下无 [el-checkbox](/#/zh-CN/component/checkbox) 的选择样式。\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入 `WeShineTree` 组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import {WeShineTree} from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WeShineTree\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n通过 `data` 属性直接传入树形结构的数据,控制组件展示的内容。它的主要功能是提供一个静态的数据源,用于展示树形结构的节点信息。若同时传入 `lazy` 为 `false` 则展示纯列表数据,此场景可用于数据回显,此时 `load` 不生效\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :data=\"data\" :lazy=\"false\" multiple />\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n data: [\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]\r\n };\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n### 加载节点\r\n通过 `load` 属性实现懒加载,即在用户展开某个节点时,动态加载该节点的子节点数据。通过返回一个 `Promise` 来异步加载数据,并在数据加载完成后将子节点渲染到树形结构中。适用于数据量较大或需要从服务器端动态获取数据的场景\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" />\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n### 单选与多选\r\n- 通过 `switch` 属性控制组件是否处于 `单选模式`,优先级高于 `multiple`。当 `switch` 为 `true` 时,用户每次只能选择一个节点,选择新的节点时会取消之前的选中状态\r\n- 通过 `multiple`属性控制组件是否允许 `多选`,只有在 `switch` 为 `false` 时生效。`multiple` 为 `true` 时,用户可以同时选中多个节点\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" multiple/>\r\n <br />\r\n <WeShineTree :load=\"load\" multiple switch />\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n\r\n\r\n### 选择类型\r\n通过 `choiceType` 属性控制在树形结构中可以选择的节点类型。`choiceType` 为 `user` 时只能选择当前 `DataNode` 内属性 `isUser` 为 `true` 的节点;为 `department` 时只能选择属性 `isUser` 为 `false` 的节点;为 `both` 时不限制选择的节点\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" multiple choiceType=\"user\"/>\r\n <br/>\r\n <WeShineTree :load=\"load\" multiple choiceType=\"department\"/>\r\n <br/>\r\n <WeShineTree :load=\"load\" multiple choiceType=\"both\"/>\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n\r\n\r\n### 默认选中\r\n通过 `defaultSelected` 预先设置默认选中的节点,这些节点会自动显示为选中状态,用户可以在此基础上进行进一步的选择或取消选择。常用于编辑场景或预选场景。选中后节点背景高亮,且最右侧会出现 `√` 效果\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" :defaultSelected=\"defaultSelected\" choiceType=\"both\"/>\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n defaultSelected: [\r\n {\r\n isUser: false,\r\n deptId: \"207\",\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: \"员工\",\r\n userId: \"laotian\",\r\n leaf: true\r\n }\r\n ]\r\n };\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n\r\n### 禁用\r\n通过 `disableList` 控制节点的禁用。禁用后节点在 UI 上会显示为灰色,并且无法点击或选中\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" :disableList=\"disableList\" choiceType=\"both\"/>\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n disableList: [\r\n {\r\n isUser: false,\r\n deptId: \"207\",\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: \"员工\",\r\n userId: \"laotian\",\r\n leaf: true\r\n }\r\n ]\r\n };\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n\r\n### 只读\r\n通过 `readonly` 控制组件是否处于只读模式。`readonly` 为 `true` 时,只能查看节点,而不能进行任何取消或选择操作\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" :defaultSelected=\"defaultSelected\" readonly/>\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n defaultSelected: [\r\n {\r\n isUser: false,\r\n deptId: \"207\",\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: \"员工\",\r\n userId: \"laotian\",\r\n leaf: true\r\n }\r\n ]\r\n };\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n\r\n### 自定义节点图标\r\n`options` 提供了四个可选的属性,分别为:`deptIcon`、`deptIconDisabled`、`userIcon`、`userIconDisabled`,分别用于自定义部门节点图标、部门节点禁用图标、用户节点图标、用户节点禁用图标。通过 `options` 属性,组件可以适应不同的 UI 风格和业务需求\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" :options=\"options\"/>\r\n</template>\r\n\r\n\r\n<script>\r\n const deptIcon = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'\r\n const userIcon = 'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg'\r\n export default {\r\n data() {\r\n return {\r\n options: {\r\n deptIcon: userIcon,\r\n deptIconDisabled: '',\r\n userIcon: deptIcon,\r\n userIconDisabled: ''\r\n }\r\n };\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n### 选择节点前的钩子函数\r\n校验当前选中的节点是否可以被选择,可以通过 `beforeChecked` 属性来配置,`beforeChecked` 属性的类型定义是:(data: DataNode) => (Promise\\<boolean\\> | boolean),当返回值是 `true` 时,表示当前节点可以选择,反之代表不可以选择。参数 `data` 是当前选择节点的信息\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" :beforeChecked=\"beforeChecked\"/>\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n },\r\n beforeChecked(data) {\r\n if (data.isUser) {\r\n this.$message('触发选择节点前的钩子函数,不可选中');\r\n return false;\r\n }\r\n return true;\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n\r\n### 高级使用\r\n- `expandOnClickNode` 属性为 `true` 时,允许用户通过点击节点文本来展开或收缩节点,从而提升用户体验\r\n- `showCheckedState` 属性为 `false` 时,选中节点背景高亮,但最右侧不会出现 `√` 效果,此状态下的单选、多选不会受影响\r\n- `loading` 属性为 `true` 时,表示组件在加载数据时会显示加载状态,提升用户体验,避免用户在数据加载过程中进行误操作\r\n- `emptyTreeTips` 当树形组件没有数据时,显示一段自定义的提示文案,告知用户当前没有可显示的数据,避免用户看到空白的组件\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <WeShineTree :load=\"load\" expandOnClickNode/>\r\n <br/>\r\n <WeShineTree :load=\"load\" :showCheckedState=\"false\" multiple/>\r\n <br/>\r\n <WeShineTree :load=\"load\" :loading=\"true\"/>\r\n .<br/>\r\n <WeShineTree :load=\"load1\" emptyTreeTips=\"避免用户看到空白的提示文案\" />\r\n</template>\r\n\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {};\r\n },\r\n methods: {\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n resolve([\r\n {\r\n isUser: false,\r\n deptId: '207',\r\n leaf: false\r\n },\r\n {\r\n isUser: true,\r\n deptId: '员工',\r\n userId: 'laotian',\r\n leaf: true\r\n }\r\n ]);\r\n });\r\n },\r\n load1() {\r\n return new Promise((resolve, reject) => {\r\n resolve([]);\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------- | ---------------------------- | ------------------------ | ------ | ------ |\r\n| load | 加载数据源函数,第一个参数是加载类型type,可以是 root/children, root表示是加载根节点的状态,children表示是是加载子节点的状态;第二个参数为data, 是当前点击的部门data, 该方法的返回值用于渲染视图,类型是 DataNode[]。 | (loadType: LOAD_TYPES, data: TreeNode) => Promise\\<DataNode[]\\> | - | - |\r\n| corpid | 企业id, 若企业存在上下游关系,open-data-box渲染指定企业的员工或部门名称 | string | - | - |\r\n| multiple | 是否多选,switch为false时生效 | boolean | - | false |\r\n| switch | 是否单选 | boolean | - | false |\r\n| choiceType | 选择节点类型,user:员工/department:部门/both:全部 | string | user/department/both | both |\r\n| defaultSelected | 默认选中节点 | DataNode[] | - | - |\r\n| disableList | 禁选节点集合 | DataNode[] | - | - |\r\n| readonly | 是否只读 | boolean | - | false |\r\n| lazy | 是否懒加载子节点,需与 load 方法结合使用 | boolean | - | true |\r\n| data | 展示的数据,用于需要主动更换数据的场景 | DataNode[] | - | - |\r\n| showCheckedState | 是否展示节点勾选状态| boolean | - | true |\r\n| emptyTreeTips | 无数据展示文案| string | - | 暂无数据 |\r\n| options | 用于配置图标icon,deptIcon:部门节点icon,deptIconDisabled:部门节点禁用时icon;userIcon:员工节点icon,userIconDisabled:员工节点禁用时icon | { deptIcon: string; deptIconDisabled: string; userIcon: string; userIconDisabled: string; } | - | - |\r\n| expandOnClickNode | 是否在点击节点的时候展开或者收缩节点, 默认值为 false,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。| boolean | - | false |\r\n| beforeChecked | 修改节点状态前置钩子,参数为当前节点data,返回值是Promise或者boolean,根据返回值决定节点是否会被勾选。| (data: DataNode) => Promise | - | - |\r\n| departmentPersonTotal | 是否展示部门总人数 | boolean | - | false |\r\n| height | 组件容器高度,不传则不开启虚拟滚动 | string | - | 100% |\r\n| loading | 是否显示组件加载状态 | boolean | - | false |\r\n\r\n### Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ------- | ------------------ | --------- |\r\n| check-change | 节点选中状态发生变化后触发,data:节点信息,state:更新后节点的勾选状态 | data: DataNode, state: boolean |\r\n| node-click | 节点被点击时触发 | data: DataNode |\r\n\r\n### Methods\r\n\r\n通过refs调用\r\n\r\n| 名称 | 说明 | 返回值 |\r\n| ------- | ------------------ | --------- |\r\n| getCheckedNodes | 获取所有已选节点 | DataNode[] |\r\n\r\n```js\r\n// 标签配置\r\nexport type TagConfig = {\r\n label: string; // 标签的文本\r\n tips?: string; // hover标签时的提示\r\n button?: string; // 结尾按钮的问题\r\n routerPath?: string; // 点击按钮跳转的路由\r\n message?: string; // 点击按钮弹出的提示\r\n}\r\n\r\n// 节点的标签类型,目前仅一种\r\nexport type TagType = 'normal';\r\n\r\n// 节点的标签\r\nexport type TagNode = {\r\n text: string, // 标签的文字\r\n type?: TagType, // 节点的标签类型,目前仅一种\r\n popover?: boolean, // hover标签是否需要展示文本\r\n popoverTips?: string, // hover标签时展示的文案\r\n handlerType?: number, // 交互类型,跳转路由或展示提示\r\n} & Pick<TagConfig, 'button' | 'routerPath' | 'message'>\r\n\r\nexport type NodeParent = {\r\n id?: number; // 节点的id\r\n count?: number | null, // 如果是部门节点,部门下有多少人\r\n name?: string; // 节点名称,showOriginName为true时,可使用name渲染名称\r\n leaf?: boolean; // 是否是叶子节点\r\n parentId?: number; // 节点的父部门id\r\n showOriginName?: boolean; // 组织架构树节点名称默认使用open-data-box渲染,如果传递showOriginName,可以搭配name直接使用html原生标签渲染\r\n customTags?: TagNode[]; // 节点右侧的标签集合\r\n hiddenTips?: boolean; // 是否隐藏节点展示主部门信息的icon\r\n nodeIconClass?: string; // 自定义iconClass 弃用\r\n nodeCustomIcon?: string; // 节点自定义图标 示例 require('./xx.svg')\r\n _id?: string | number; // 节点的id,兼容历史数据,弃用\r\n status?: 0 | 1 | 2 | 4 | 5 | 99; // 员工节点状态:0-无效,不在可见范围内,1-已激活,2-已禁用,4-未激活,5-退出企业,99-已离职\r\n accountStatus?: 1 | 2 | 3; // 账号状态:1-未开通, 2-已开通, 3-已过期\r\n orgPathIds?: Array<number>; // 节点的父部门id集合\r\n style?: number; // 样式主体,1-标品 2-爱尔,需要展示节点的部门\r\n _disable?: boolean // 内部使用,是否禁用\r\n _virtualNode?: boolean // 内部使用,是否是虚拟节点\r\n}\r\n\r\n// 员工节点类型\r\nexport type NodeUser = {\r\n isUser: true; // 是员工节点\r\n userId: string; // 员工id\r\n} & NodeParent;\r\n\r\n// 部门节点类型\r\nexport type NodeDep = {\r\n isUser: false; // 非员工节点,即部门节点\r\n deptId: number; // 部门id\r\n depId?: number; // 部门id,冗余字段\r\n children?: Array<NodeUser | NodeDep>;\r\n} & NodeParent\r\n\r\n// 节点类型\r\nexport type DataNode = NodeUser | NodeDep;\r\n```"
},
{
"name": "ws-tag-group",
"category": "PC端组件库",
"content": "## WsTagGroup - 标签组组件\r\n\r\n`WsTagGroup` 组件用于展示一组标签,并支持在空间不足时自动隐藏多余的标签,以“+n”的形式显示隐藏标签数量。常用于筛选组织架构、群聊、客户标签等内容后的展示,需配合 `WsTagItem` 标签组件一起使用。\r\n\r\n- 组件可以通过`lineClamp`属性设置最大显示行数,超出行数的标签将被隐藏。\r\n- 组件支持自定义隐藏标签数量的显示格式,通过`moreFormatter`属性实现。\r\n- 组件内部使用`ResizeObserver`监听尺寸变化,动态调整标签的显示和隐藏。\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入 `WsTagGroup`、`WsTagItem` 组件, 并在页面中注册\r\n\r\n```js\r\n<script>\r\n import { WsTagGroup, WsTagItem } from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsTagGroup, WsTagItem\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n`WsTagGroup` 组件默认展示所有标签\r\n\r\n:::demo\r\n```html\r\n<ws-tag-group>\r\n <ws-tag-item v-for=\"(tag, index) in new Array(30)\" :key='index'>标签{{index + 1}}</ws-tag-item>\r\n</ws-tag-group>\r\n```\r\n:::\r\n\r\n#### 限制显示行数\r\n通过 `lineClamp` 属性,可以限制标签组的最大显示行数。当空间不足时,会自动隐藏多余的标签,并以“+n”的形式显示隐藏的标签数量。\r\n\r\n:::demo\r\n```html\r\n<ws-tag-group :line-clamp=\"2\">\r\n <ws-tag-item v-for=\"(tag, index) in new Array(50)\" :key='index'>标签{{index + 1}}</ws-tag-item>\r\n</ws-tag-group>\r\n```\r\n:::\r\n\r\n\r\n#### 自定义隐藏标签显示格式\r\n通过 `moreFormatter` 属性,可以自定义隐藏标签数量的显示格式。\r\n\r\n:::demo\r\n```html\r\n<ws-tag-group :line-clamp='1' :more-formatter=\"(count) => `还有${count}个标签`\">\r\n <ws-tag-item v-for=\"(tag, index) in new Array(30)\" :key='index'>标签{{index + 1}}</ws-tag-item>\r\n</ws-tag-group>\r\n```\r\n:::\r\n\r\n也可使用 `more` 作用域插槽自定义展示格式。\r\n:::demo\r\n```html\r\n<ws-tag-group :line-clamp='1'>\r\n <ws-tag-item v-for=\"(tag, index) in new Array(30)\" :key='index'>标签{{index + 1}}</ws-tag-item>\r\n <template v-slot:more='scope'>\r\n <ws-tag-item>{{`还有${scope.count}个标签`}}</ws-tag-item>\r\n </template>\r\n</ws-tag-group>\r\n```\r\n:::\r\n\r\n\r\n#### 标签展开/收起\r\n\r\n可通过`showMoreChange`事件监听\"+n\"标签的显示/隐藏状态, 并根据此状态调整`line-clamp`属性值, 实现标签展开/收起状态切换\r\n:::demo\r\n```html\r\n<template>\r\n <div style=\"display: flex;\">\r\n <!-- 标签组组件 -->\r\n <ws-tag-group\r\n :line-clamp=\"isExpanded ? undefined : 1\"\r\n @showMoreChange=\"handleShowMoreChange\"\r\n style=\"flex: 1;\"\r\n >\r\n <ws-tag-item v-for=\"(tag, index) in tags\" :key=\"index\">标签{{ index + 1 }}</ws-tag-item>\r\n </ws-tag-group>\r\n\r\n <!-- 文本按钮组件 -->\r\n <ws-button v-show='hasHiddenTags || isExpanded' size='meduim' type=\"text\" @click=\"toggleExpand\" style='margin-top: 4px;'>\r\n {{ isExpanded ? '收起' : '展开' }}\r\n </ws-button>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isExpanded: false, // 控制标签组是否展开\r\n hasHiddenTags: false, // 是否有隐藏的标签\r\n tags: new Array(30), // 模拟标签数据\r\n };\r\n },\r\n methods: {\r\n // 切换展开/收起状态\r\n toggleExpand() {\r\n this.isExpanded = !this.isExpanded;\r\n },\r\n // 监听标签组的隐藏状态变化\r\n handleShowMoreChange(visible) {\r\n this.hasHiddenTags = visible;\r\n },\r\n },\r\n};\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### WsTagGroup Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-------------|-----------------------------------------------------------|----------------------------|-------------|------|\r\n| lineClamp | 限定最大展示的标签行数,超出范围的标签组件会进行折叠,并在此组件尾部展示\"+n”标签。 如不设置,不限定最大行数 | string/number | - | - |\r\n| moreFormatter | \"+n” 字符串格式化函数 | (value: number) =\\> string | - | - |\r\n\r\n\r\n\r\n### WsTagGroup slots\r\n\r\n| name | 说明 | 参数 |\r\n|------|----------|-------------|\r\n| default | 用于放置`WsTagItem`标签的默认插槽 |\r\n| more | \"+n” 标签 | count: 剩余数量 |\r\n\r\n\r\n### WsTagGroup Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n|-------|-------------|--------------------------------------------------|\r\n| click | 标签组点击事件 | - |\r\n| showMoreChange | \"+n” 标签显示事件 | visible: `true`表示显示\"+n” 标签, `false`表示没有显示\"+n” 标签 |\r\n\r\n\r\n### WsTagItem - 标签项组件\r\n\r\n`WsTagItem`组件用于展示单个标签,支持图标、关闭按钮等功能,和element-ui tag 组件类展示效果类似。\r\n\r\n`WsTagItem`组件可以单独使用,也可以嵌套在`WsTagGroup`中。\r\n\r\n#### 标签样式\r\n使用`scene`属性对应不同的使用场景,各场景展示样式不同。\r\n\r\n - default 默认场景,适合在内页表单项的展示(白底有边框)。\r\n - filter 筛选器场景,适合在表单筛选器里面展示(灰底无边框)。 \r\n - table 表格场景,适合在表格里面展示(灰底有边框)。\r\n\r\n:::demo\r\n```html\r\n<ws-tag-item>默认场景</ws-tag-item>\r\n<ws-tag-item scene='table'>表格场景</ws-tag-item>\r\n<ws-tag-item scene='filter'>筛选器场景</ws-tag-item>\r\n```\r\n:::\r\n\r\n#### 尺寸\r\n\r\n组件提供三种尺寸`medium`、`small`、`mini`,通过设置`size`属性来配置它们,可以在不同场景下选择合适的按钮尺寸。如不配置`size`,默认尺寸为`medium`。\r\n\r\n:::demo\r\n```html\r\n<ws-tag-item size=\"medium\">中等标签</ws-tag-item>\r\n<ws-tag-item size=\"small\">小型标签</ws-tag-item>\r\n<ws-tag-item size=\"mini\">超小标签</ws-tag-item>\r\n```\r\n:::\r\n\r\n#### 图标\r\n\r\n通过`icon`属性,可以为标签添加图标。组件内置的枚举字符串如下图所示。\r\n\r\nicon属性也可传入svg图标路径,如\r\n`<ws-tag-item :icon=\"require('./assets/xxx.svg')\">标签</ws-tag-item>`\r\n\r\n:::demo\r\n```html\r\n<ws-tag-item icon=\"user\">用户</ws-tag-item>\r\n<ws-tag-item icon=\"department\">部门</ws-tag-item>\r\n<ws-tag-item icon=\"label\">标签</ws-tag-item>\r\n<ws-tag-item icon=\"store\">门店</ws-tag-item>\r\n<ws-tag-item icon=\"qrcode\">活码</ws-tag-item>\r\n<ws-tag-item icon=\"group\">群聊</ws-tag-item>\r\n```\r\n:::\r\n\r\n#### 可关闭的标签\r\n\r\n通过`closeable`属性,可以为标签添加关闭按钮。\r\n:::demo\r\n```html\r\n<template>\r\n <ws-tag-item closeable @close=\"handleClose\">可关闭标签</ws-tag-item>\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleClose() {}\r\n }\r\n }\r\n </script>\r\n```\r\n:::\r\n\r\n\r\n\r\n#### WsTagItem Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------------------|-------|\r\n| scene | 标签使用场景,不同的场景对应不同的展示样式。 | string | default / filter / table | default |\r\n| icon | 标签类型的icon图标,显示在标签文本的左侧。可传入字符串 \"user\": 员工、\"department\": 部门、\"label\": 标签、\"store\": 门店、\"qrcode\": 活码、\"group\": 群聊,展示对应图片icon。也可传入svg图标路径,如require('/assets/xx.svg') | string | user/department/label/store/qrcode/group | - |\r\n| max-width | 标签最大宽度, 当超过此宽度时,文本会溢出隐藏,并显示... | number | - | - |\r\n| closeable | 标签是否支持删除操作, 配置后会在标签文本右侧显示\"x\"删除图标按钮 | boolean | - | false |\r\n| size | 尺寸, 一般使用场景为筛选器或表格里展示尺寸为mini,内页表单项多为small | string | medium / small / mini | medium |\r\n\r\n\r\n\r\n#### WsTagItem Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ------- |-------------| --------- |\r\n| close | 删除图标按钮的点击事件 | - |"
},
{
"name": "ws-filter-business-tags",
"category": "PC端组件库",
"content": "## WsFilterBusinessTags - 标签筛选器组件\r\n\r\n用于筛选标签,内部集成了 WsFilterTagGroup 和 TagSelectDialog。\r\n\r\n\r\n### 导入方式\r\n需从`@wshoto/pc-base-ui`中具名导入`WeShineFilterBusinessTags`组件, 并在页面中注册\r\n\r\n```js\r\n\r\n<script>\r\n import { WeShineFilterBusinessTags, TagSelectDialogTypes } from \"@wshoto/pc-base-ui\";\r\n \r\n export default {\r\n components: {\r\n WsFilterBusinessTags\r\n }\r\n }\r\n</script>\r\n\r\n```\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-filter-group :show-operation=\"false\">\r\n <ws-filter-item label=\"客户标签\">\r\n <we-shine-filter-business-tags\r\n dialog-title=\"选择标签\"\r\n ref=\"businessTags\"\r\n type=\"business\"\r\n isRadioGroup\r\n :radio=\"tagOptions.radio\"\r\n :limit=\"20\"\r\n :corpTagList.sync=\"tagOptions.corpTagList\"\r\n :businessTagList.sync=\"tagOptions.businessTagList\"\r\n :noAuthBusinessTagList.sync=\"tagOptions.noAuthBusinessTagList\"\r\n @change=\"tagSelectConfirm\"\r\n />\r\n </ws-filter-item>\r\n </ws-filter-group>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n tagOptions: {\r\n corpTagList: [],\r\n businessTagList: [],\r\n noAuthBusinessTagList: [],\r\n radio: 1 // 筛选条件类别 可选值包括 1:满足任意一个标签;2:同时满足所选标签;3:无标签; 4:满足所选标签“同组为或、异组为且”\r\n }\r\n };\r\n },\r\n methods: {\r\n tagSelectConfirm(data) {\r\n // 确认选中标签,data类型为TagSelectResult\r\n this.tagOptions.corpTagList = data.corpTagList;\r\n this.tagOptions.businessTagList = data.businessTagList;\r\n this.tagOptions.noAuthBusinessTagList = data.noAuthBusinessTagList;\r\n this.tagOptions.radio = data.radio;\r\n // todo 以tagOptions做为标签筛选条件, 请求列表接口\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------------------- |------------------------------------------------------------------------------------------------------------|------------------------|-----------------------------|--------|\r\n| corpTagList | 选择的企业标签列表,支持.sync | Tag[] | - | - |\r\n| businessTagList | 选择的业务标签列表,支持.sync | Tag[] | - | - |\r\n| noAuthBusinessTagList | 选择的没有权限的业务标签列表,支持.sync | Tag[] | - | - |\r\n| placeholder | 无选择数据时占位符文案 | String | - | 请选择 |\r\n| allowClear | 是否展示标签组清除按钮 | Boolean | true |\r\n| dialog-title | 选标签对话框标题 | String | - | 请选择添加人 |\r\n| isRadioGroup | 是否显示筛选条件 | Boolean | - | false |\r\n| radio | 筛选条件类别,可选值包括 1:满足任意一个标签;2:同时满足所选标签;3:无标签; 4:满足所选标签“同组为或、异组为且” | 1 \\| 2 \\| 3 \\| 4 | - | 1 |\r\n| limit | 标签最多选中数量限制 | Number | - | - |\r\n| type | 客户群标签(group), 客户标签(business), 客户标签包括企业标签corpTagList、业务标签businessTagList、未授权的业务标签noAuthBusinessTagList 三种类别 | String | group \\| business | - |\r\n| isClue | 线索标识 | Boolean | - | false |\r\n| isFilterAuto | 自动标签 | Boolean | - | false |\r\n\r\n\r\n### Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ------ |--------------| --------------- |\r\n| change | 选标签对话框点击确认时触发 | TagSelectResult |\r\n\r\n\r\n### 类型定义\r\n\r\n当使用TS时,需要先导入标签的类型定义\r\n\r\n```ts\r\nimport { TagSelectDialogTypes } from '@wshoto/pc-base-ui';\r\ntype Tag = TagSelectDialogTypes.Tag;\r\ntype TagSelectResult = TagSelectDialogTypes.TagSelectResult;\r\n```\r\n\r\n#### Tag 标签类型定义\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|---------|--------|-------|\r\n| tagId | string | 标签 ID |\r\n| tagName | string | 标签名称 |\r\n| order | number | 标签排序 |\r\n\r\n#### TagGroup 标签组类型定义\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|------------|--------|-------------------------------------|\r\n| tagId | string | 标签 ID |\r\n| tagName | string | 标签名称 |\r\n| order | number | 标签排序 |\r\n| tagGroupId | string | 标签组 ID |\r\n| strategyId | string | 业务标签组 ID(可选)如果为空则代表这个标签组不从属于某一个具体业务 |\r\n\r\n#### TagSelectResult 类型定义\r\n\r\n| 属性名 | 类型 | 描述 |\r\n|-----------------------|-----------------|---------------------------------------------------------------|\r\n| list | Tag[] | 选中 ID 列表 |\r\n| cropTagList | Tag[] | 选中企业标签列表 |\r\n| businessTagList | Tag[] | 选中业务标签列表 |\r\n| noAuthBusinessTagList | Tag[] | 选中无权限的业务标签列表 |\r\n| radio | 1 \\| 2 \\| 3\\| 4 | 选中 radio 类型; 1:满足任意一个标签;2:同时满足所选标签;3:无标签; 4:满足所选标签“同组为或、异组为且” |\r\n| tagGroups | TagGroup[] | 选中标签组 |"
},
{
"name": "ws-toast",
"category": "移动端组件库",
"content": "## WsToast - 轻提示组件\r\n\r\nWsToast 是一个用于展示消息提示的组件,在页面中间弹出黑色半透明提示,基于 `Vue`、`Vant` 组件进行封装。该组件支持多种消息类型(如文本、成功、失败、加载中等),并提供了丰富的自定义选项,如图标、位置、遮罩层等。\r\n\r\n- 支持多种消息类型:文本、成功、失败、加载中等。\r\n- 支持自定义显示时长、位置、图标、遮罩层、内容、样式等。\r\n- 支持点击关闭、自动关闭等功能。\r\n- 支持多实例提示,允许同时展示多个提示框。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsToast` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import Vue from 'vue';\r\n import { WsToast } from '@wshoto/h5-base-ui';\r\n\r\n Vue.use(Toast);\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\nWsToast 默认支持文本提示,调用时只需传入提示信息即可。\r\n\r\n```js\r\n this.$wstoast('这是一个提示信息');\r\n```\r\n\r\n#### 成功提示\r\n\r\n使用 `success` 方法展示成功提示。\r\n\r\n```js\r\n this.$wstoast.success('操作成功');\r\n```\r\n\r\n\r\n#### 失败提示\r\n\r\n使用 `fail` 方法展示失败提示。\r\n\r\n```js\r\n this.$wstoast.fail('操作失败');\r\n```\r\n\r\n#### 加载提示\r\n\r\n使用 `loading` 方法展示加载提示。\r\n\r\n```js\r\n this.$wstoast.loading('加载中...');\r\n```\r\n\r\n\r\n#### 自定义显示时长\r\n\r\n可以通过 `duration` 属性自定义消息的显示时长,单位为毫秒。默认显示时长为 2000 毫秒。\r\n\r\n```js\r\nthis.$wstoast({\r\n message: '自定义时长',\r\n duration: 5000 // 显示 5 秒\r\n});\r\n```\r\n\r\n#### 自定义位置\r\n\r\n可以通过 `position` 属性设置提示框的位置,支持 `top`、`middle` 和 `bottom` 三种位置。\r\n\r\n```js\r\nthis.$wstoast({\r\n message: '顶部消息',\r\n position: 'top'\r\n});\r\n\r\nthis.$wstoast({\r\n message: '底部消息',\r\n position: 'bottom'\r\n});\r\n```\r\n\r\n#### 自定义图标\r\n\r\n可以通过 `icon` 属性自定义消息的图标,支持传入图标名称或图片链接。。\r\n\r\n```js\r\nthis.$wstoast({\r\n message: '带图标的消息-图片名称',\r\n icon: 'success'\r\n});\r\n\r\nthis.$wstoast({\r\n message: '带图标的消息-图片链接',\r\n icon: require('../../assets/common/icon-tip.svg')\r\n});\r\n```\r\n\r\n#### 遮罩层与点击关闭\r\n\r\nWsToast 支持显示遮罩层,并可以通过点击遮罩层或消息本身来关闭提示。\r\n\r\n```js\r\nthis.$wstoast({\r\n message: '带遮罩层的消息',\r\n overlay: true,\r\n closeOnClick: true\r\n});\r\n```\r\n\r\n#### 多实例展示\r\n\r\n默认情况下,WsToast 只会展示一个消息。如果需要同时展示多个消息,可以通过 `allowMultiple` 方法开启多实例模式。\r\n\r\n```js\r\n this.$wstoast.allowMultiple(true);\r\n this.$wstoast('第一个提示');\r\n this.$wstoast.success('第二个提示');\r\n```\r\n\r\n\r\n#### 修改默认配置\r\n\r\n通过`setDefaultOptions`函数可以全局修改默认配置,通过`resetDefaultOptions`函数可以全局重置默认配置。\r\n\r\n```js\r\n// 将所有 Toast 的展示时长设置为 2000 毫秒\r\nthis.$wstoast.setDefaultOptions({ duration: 2000 });\r\n\r\n// 将所有 loading Toast 设置为背景不可点击\r\nthis.$wstoast.setDefaultOptions('loading', { forbidClick: true });\r\n\r\n// 重置所有 Toast 的默认配置\r\nthis.$wstoast.resetDefaultOptions();\r\n\r\n// 重置 loading Toast 的默认配置\r\nthis.$wstoast.resetDefaultOptions('loading');\r\n```\r\n\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------------|--------------------------------------------------------------------|------------------|-----------------------|---------|\r\n| message | 消息内容 | string/number | — | — |\r\n| type | 消息类型,支持 `text`、`loading`、`success`、`fail` 等 | string | text/loading/success/fail | text |\r\n| duration | 消息显示时长,单位为毫秒,设置为 0 时表示不会自动关闭 | number | — | 2000 |\r\n| position | 消息展示位置 | string | top/middle/bottom | middle |\r\n| icon | 自定义图标 | string | — | — |\r\n| overlay | 是否显示遮罩层 | boolean | — | false |\r\n| closeOnClick | 是否允许通过点击消息关闭 | boolean | — | false |\r\n| closeOnClickOverlay | 是否允许通过点击遮罩层关闭 | boolean | — | false |\r\n| iconPrefix | 图标类名前缀,同 Icon 组件的 class-prefix 属性 | string | — | — | \r\n| forbidClick | 是否禁止背景点击 | boolean | — | false |\r\n| className | 自定义类名 | any | — | null |\r\n| transition | 动画类名,等价于 transition 的name属性 | string | — | van-fade |\r\n| loadingType | 自定义加载图标类型,仅在 `type` 为 `loading` 时有效 | string | — | — |\r\n| getContainer | 指定挂载的节点 | string/HTMLElement | — | body |\r\n| onClose | 消息关闭时的回调函数 | () => void | — | — |\r\n| onOpened | 消息展示完成后的回调函数 | () => void | — | — |\r\n\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|--------|------------------|-------|\r\n| opened | 消息展示完成时触发 | — |\r\n| closed | 消息关闭时触发 | — |\r\n\r\n### Methods\r\n\r\n| 方法名 | 说明 | 参数 |\r\n|---------------|--------------------------|-------|\r\n| success | 显示成功提示 | message: string |\r\n| fail | 显示失败提示 | message: string |\r\n| loading | 显示加载提示 | message: string |\r\n| clear | 清除当前提示 | all: boolean |\r\n| setDefaultOptions| 设置默认配置 | type: string, options: ToastOptions |\r\n| resetDefaultOptions | 重置默认配置 | type: string |\r\n| allowMultiple | 允许同时展示多个提示框 | value: boolean |\r\n\r\n\r\n\r\n### 类型定义\r\n\r\n```ts\r\ninterface ToastOptions {\r\n message: string; // 提示信息内容\r\n type?: 'text' | 'loading' | 'success' | 'fail'; // 提示类型\r\n icon?: string; // 自定义图标\r\n position?: 'top' | 'middle' | 'bottom'; // 提示框位置\r\n duration?: number; // 提示框显示时长,单位为毫秒\r\n forbidClick?: boolean; // 是否禁止背景点击\r\n closeOnClick?: boolean; // 是否在点击提示框时关闭\r\n closeOnClickOverlay?: boolean; // 是否在点击遮罩层时关闭\r\n overlay?: boolean; // 是否显示遮罩层\r\n overlayStyle?: object; // 自定义遮罩层样式\r\n getContainer?: string; // 指定挂载的节点\r\n transition?: string; //动画类名,等价于 transition 的name属性 \r\n className?: any; //自定义类名\r\n iconPrefix?: string; //图标类名前缀,同 Icon 组件的 class-prefix 属性\r\n onClose?: () => void; // 关闭时的回调函数\r\n onOpened?: () => void; // 打开时的回调函数\r\n}\r\n```"
},
{
"name": "ws-dialog-h5",
"category": "移动端组件库",
"content": "## WsDialog - 自定义对话框组件\r\n\r\n`WsDialog` 是一个基于 `van-dialog` 封装的对话框组件,提供了更灵活的功能和样式定制。它支持自定义标题、内容、底部插槽,并且可以控制是否显示关闭按钮、遮罩层等。该组件适用于需要弹出对话框的场景,如确认框、信息提示框等。\r\n\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsDialog` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsDialog } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsDialog\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsDialog` 组件可以通过 `visible` 属性控制弹窗的显示与隐藏。可以通过 `title` 属性设置弹窗的标题,并通过插槽自定义内容。\r\n\r\n```html\r\n<template>\r\n <ws-dialog :visible.sync=\"isVisible\" title=\"对话框标题\">\r\n <p>这是对话框的内容</p>\r\n </ws-dialog>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isVisible: false\r\n };\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n#### 自定义关闭按钮\r\n\r\n通过 `showClose` 属性可以控制是否显示右上角的关闭按钮。\r\n\r\n```html\r\n<template>\r\n <ws-dialog :visible.sync=\"isVisible\" title=\"对话框标题\" :show-close=\"true\">\r\n <p>这是对话框的内容</p>\r\n </ws-dialog>\r\n</template>\r\n```\r\n\r\n\r\n#### 点击遮罩层关闭\r\n\r\n通过 `closeOnClickOverlay` 属性可以控制是否在点击遮罩层时关闭弹窗。\r\n\r\n```html\r\n<template>\r\n <ws-dialog :visible.sync=\"isVisible\" title=\"对话框标题\" :closeOnClickOverlay=\"true\">\r\n <p>点击遮罩层可以关闭对话框</p>\r\n </ws-dialog>\r\n</template>\r\n```\r\n\r\n\r\n#### 自定义挂载节点\r\n\r\n通过 `getContainer` 属性可以指定对话框挂载的 DOM 节点。\r\n\r\n```html\r\n<template>\r\n <ws-dialog :visible.sync=\"isVisible\" title=\"对话框标题\" getContainer=\"#custom-container\">\r\n <p>对话框挂载在自定义节点上</p>\r\n </ws-dialog>\r\n</template>\r\n```\r\n\r\n#### 自定义底部插槽\r\n\r\n你可以通过 `footer` 插槽自定义对话框底部的内容,例如添加确认和取消按钮。\r\n\r\n```html\r\n<template>\r\n <ws-dialog :visible.sync=\"isVisible\" title=\"对话框标题\">\r\n <p>这是对话框的内容</p>\r\n <template v-slot:footer>\r\n <ws-button @click=\"isVisible = false\">取消</ws-button>\r\n <ws-button @click=\"confirm\">确认</ws-button>\r\n </template>\r\n </ws-dialog>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isVisible: false\r\n };\r\n },\r\n methods: {\r\n confirm() {\r\n // 确认逻辑\r\n this.isVisible = false;\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-------------------|--------------------------------------------------------------------|---------|------|-------|\r\n| title | 对话框标题 | string | — | — |\r\n| visible | 是否显示对话框 | boolean | — | false |\r\n| showClose | 是否展示右上角的关闭按钮 | boolean | — | false |\r\n| overlay | 是否展示遮罩层 | boolean | — | true |\r\n| closeOnPopstate | 是否在页面回退时自动关闭 | boolean | — | true |\r\n| closeOnClickOverlay | 是否在点击遮罩层后关闭对话框 | boolean | — | false |\r\n| lazyRender | 是否在显示弹层时才渲染节点 | boolean | — | true |\r\n| lockScroll | 是否锁定背景滚动 | boolean | — | true |\r\n| getContainer | 指定挂载的节点,传入选择器字符串,如 `#app` | string | — | — |\r\n| customClass | 自定义的class | string | — | — |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|--------|------------------|----|\r\n| open | 打开对话框时触发 | — |\r\n| close | 关闭对话框时触发 | — | \r\n\r\n### Slots\r\n\r\n| name | 说明 |\r\n|--------|----------------------------|\r\n| title | 自定义对话框标题内容,位于对话框顶部 |\r\n| default | 对话框的主体内容,位于标题下方 |\r\n| footer | 自定义对话框底部内容,位于对话框底部 |"
},
{
"name": "ws-list",
"category": "移动端组件库",
"content": "## WsList - 列表组件\r\n\r\nWsList组件用于展示列表数据,支持下拉刷新和分页加载功能。基于`van-pull-refresh`和`van-list`组件封装,适用于需要动态加载数据的场景。\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/h5-base-ui`中具名导入`WsList`组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsList } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsList\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\nWsList组件默认支持分页加载功能。通过配置`getList`属性来获取数据。\r\n:::demo\r\n```html\r\n<template>\r\n <ws-list ref=\"pullRefreshList\" :getList=\"getList\">\r\n <template v-slot=\"{ item, index }\">\r\n <div>{{ item.name }}</div>\r\n </template>\r\n </ws-list>\r\n</template>\r\n\r\n<script>\r\nimport { request } from '@wshoto/lib-base'; \r\nexport default {\r\n data() {\r\n return {\r\n pageSize: 10\r\n };\r\n },\r\n created() {\r\n\r\n },\r\n methods: {\r\n search() {\r\n this.$refs.pullRefreshList.reset();\r\n },\r\n async getList(pageNum) {\r\n // 换成真实的API接口\r\n const data = await request({\r\n url: '/your-api-url',\r\n method: 'post',\r\n data: {\r\n currentIndex: pageNum,\r\n pageSize: this.pageSize\r\n }\r\n });\r\n return {\r\n list: data.list,\r\n total: data.total\r\n };\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------|---------------------------------------------------------------------------------------------------|----------|-----|--------------|\r\n| getList | 获取数据的方法, 接收一个参数(当前页码), 必须返回一个包含着list、total(总条数)的对象 , 注:没有使用request封装的请求需要处理异常情况,异常情况需要throw error | WsGetList | - | - |\r\n| pageSize | 每页显示的数据条数 | number | — | 10 |\r\n| pageMode | 分页模式 one单页模式:没有分页,一次加载全部数据,组件的高度由列表项内容确定; multi多页模式:分页加载,上拉加载更多数据, 组件的高度和列表项内容高度无关。默认为多页模式 | string | multi/one | multi |\r\n| hasRefresh | 是否启用下拉刷新功能 | boolean | — | false |\r\n| immediate | 是否立即调用获取数据函数 | boolean | — | true |\r\n| background | 暂无数据时的背景色 | string | — | — |\r\n| image | 暂无数据时显示的图片 | string | — | — |\r\n| title | 暂无数据时的标题 | string | — | — |\r\n| subTitle | 暂无数据时的副标题 | string | — | 暂无数据 |\r\n| buttonText | 暂无数据时按钮的文本 | string | — | — |\r\n\r\n### Methods\r\n\r\n| 方法名称 | 说明 | 参数 |示例|\r\n| -------- | ------------------ |---------------------------------------------------| ------------ |\r\n| reset | 重置方法, 筛选过滤条件后可调用此方法 | - | (this.$refs.pullRefreshList as InstanceType\\<typeof **WsPullRefreshList**\\>).reset(); |\r\n| update | 更新指定索引处的列表项 | item: any, index: number 其中item代表当前项, index代表当前项索引 | - |\r\n| delete | 删除指定索引处的列表项 | index: number |\r\n\r\n### Scope Slots\r\n|名称 | 说明 | 参数 |\r\n| -------- | ------------------ |------------------------------|\r\n| default | 列表项作用域插槽,用于自定义列表项内容 | {item: any, index: number} 其中item代表当前项, index代表当前项索引 |\r\n\r\n### Slots\r\n|名称 | 说明 | 默认值 |\r\n| -------- | ------------------ | ------------ |\r\n| empty | 暂无数据插槽 | ws-default-page组件 |\r\n| header | 列表头部插槽 |-|\r\n| finished| 加载完成后的提示文案 | 没有更多了 |\r\n\r\n### Events\r\n|事件 | 说明 |\r\n| -------- | ------------------ |\r\n| click | 暂无数据的按钮点击事件 |\r\n\r\n### 类型定义\r\n\r\n```ts\r\n// currentPage 为当前页码\r\nexport type WsGetList = (currentPage: number) => Promise<{\r\n list: Array<any>;\r\n total: number;\r\n}>;\r\n```\r\n\r\n::: tip\r\n\r\n### wsList使用常见问题\r\n\r\n#### 问题: 列表布局出现无限加载?\r\n#### 解决: 对ws-list容器设置 height: auto; overflow: visible;\r\n\r\n:::"
},
{
"name": "ws-search",
"category": "移动端组件库",
"content": "## WsSearch 搜索栏组件\r\n\r\n`WsSearch` 是一个基于 `van-search` 封装的搜索组件,支持自定义搜索输入框、右侧操作按钮、角色切换等功能。该组件适用于需要搜索功能的场景,并且可以根据不同的主题进行样式切换。\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsSearch } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsSearch', WsSearch);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo `WsSearch` 组件默认提供一个圆角搜索框,并支持输入搜索关键词。用户通过输入框输入内容、回车触发搜索事件。\r\n\r\n```html\r\n<template>\r\n <ws-search placeholder=\"请输入搜索关键词\" @onSearch=\"handleSearch\" />\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleSearch(value) {\r\n if (value) {\r\n this.$toast(`搜索关键词:${value}`);\r\n }\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 通过 `theme` 属性设置搜索组件的背景色。可选值为 `light` 、 `blue`, `light` 为白色背景,`blue` 为蓝色背景,默认为 `light`。\r\n\r\n```html\r\n<template>\r\n <ws-search placeholder=\"请输入搜索关键词\" theme='blue' @onSearch=\"handleSearch\" />\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleSearch(value) {\r\n if (value) {\r\n this.$toast(`搜索关键词:${value}`);\r\n }\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n\r\n\r\n### 角色切换\r\n\r\n:::demo 通过设置 `isTeam` 属性为 `true`,启用角色切换功能。常用于用户在不同的角色(团队/我的)之间切换。点击切换后触发 `roleChange` 事件,首个参数为对象类型,其中的`mode`值 为`1`时代表`团队`, 为`0`时代表`我的`; 通过设置 `initRoleTitle` 和 `switchRoleTitle` 文案,允许用户自定义切换展示的文案。当 `theme` 为 `blue` 时,切换的图标为白色;为 `light` 时,切换的图标为蓝色。\r\n\r\n```html\r\n<template>\r\n <ws-search\r\n is-team\r\n :init-role-id=\"1\"\r\n init-role-title=\"团队的数据\"\r\n switch-role-title=\"我的数据\"\r\n @roleChange=\"handleRoleChange\"\r\n />\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleRoleChange({ mode }) {\r\n console.log(\"角色切换:\", mode === 1 ? '团队' : '我的');\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 自定义右侧按钮\r\n\r\n:::demo 通过设置 `rightIcon` 或 `showAction` 为 `true` 时,在搜索框右侧仅且只能控制展示一个 `+` 按钮,点击后可触发 `rightAction` 事件。需要注意的是搜索框右侧一般只有一个 `+` 按钮,若有其他的样式,需要用插槽实现。若 `rightIcon` 和 `showAction` 都为 `false` 时,则不展示右侧操作区域。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <ws-search showAction rightIcon @rightAction=\"handleRightAction\" />\r\n </div>\r\n <div>\r\n <ws-search :showAction='false' :rightIcon='false' />\r\n </div>\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleRightAction() {\r\n console.log(\"右侧按钮点击\");\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 通过 `rightBtnText` 属性自定义搜索框右侧 `+` 按钮的右侧文本。\r\n\r\n```html\r\n<template>\r\n <ws-search rightIcon right-btn-text=\"这是按钮右侧\" @rightAction=\"handleRightAction\" />\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleRightAction() {\r\n console.log(\"右侧按钮点击\");\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 通过 `action` 插槽自定义搜索框右侧 `+` 按钮的左侧内容。\r\n\r\n```html\r\n<template>\r\n <ws-search rightIcon @rightAction=\"handleRightAction\">\r\n <div slot='action'>这是按钮左侧</div>\r\n </ws-search>\r\n</template>\r\n<script>\r\n export default {\r\n methods: {\r\n handleRightAction() {\r\n console.log(\"右侧按钮点击\");\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 自定义左侧内容\r\n\r\n:::demo 通过 `left` 插槽,自定义搜索框左侧内容。\r\n\r\n```html\r\n<template>\r\n <ws-search rightIcon @rightAction=\"handleRightAction\">\r\n <van-icon class=\"fs25\" slot='left' name=\"https://fastly.jsdelivr.net/npm/@vant/assets/icon-demo.png\" />\r\n </ws-search>\r\n</template>\r\n```\r\n\r\n:::\r\n\r\n\r\n\r\n### 自定义搜索框内左侧图标\r\n\r\n:::demo 通过插槽 `left-icon` 自定义搜索框内部左侧的图标。\r\n\r\n```html\r\n<template>\r\n <ws-search>\r\n <template #left-icon>\r\n <van-icon name=\"chat-o\" />\r\n </template>\r\n </ws-search>\r\n</template>\r\n```\r\n\r\n:::\r\n\r\n### 自定义搜索框内图标的左侧内容\r\n\r\n:::demo 通过插槽 `label` 自定义搜索框内图标的左侧内容,一般为文本。\r\n\r\n```html\r\n<template>\r\n <ws-search>\r\n <template #label>一般为文本</template>\r\n </ws-search>\r\n</template>\r\n```\r\n\r\n:::\r\n\r\n### 高级使用\r\n\r\n:::demo 通过设置 `maxlength` 限制搜索框内可输入文案的最大长度。\r\n\r\n```html\r\n<template>\r\n <ws-search :maxlength='maxlength' @onInput='onInput' />\r\n</template>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n maxlength: 5\r\n }\r\n },\r\n methods: {\r\n onInput(v) {\r\n if (v.length >= this.maxlength) {\r\n this.$toast('已达到最大可输入文案长度')\r\n }\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo `clear-trigger` 用于控制清除按钮的触发时机。为 `focus` 时输入框聚焦且不为空时展示清除按钮;为 `always` 时输入框不为空时展示清除按钮,默认为 `focus`。\r\n\r\n```html\r\n<template>\r\n <ws-search clear-trigger='always'></ws-search>\r\n</template>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 属性名 | 说明 | 类型 | 默认值 |\r\n| --------------- |-----------------------------------------------| ------------------ | ------------------ |\r\n| isTeam | 是否显示切换组件(团队/我的) | boolean | false |\r\n| initRoleId | 初始化角色 | number | - |\r\n| initRoleTitle | 主标题(有权限展示,例如超管,分管) | string | 团队 |\r\n| switchRoleTitle | 副标题 (取反) | string | 我的 |\r\n| placeholder | 占位提示文字 | string | 请输入搜索关键词 |\r\n| theme | 主题,可选项为 light 和 blue | string | light |\r\n| hairlineBottom | 是否显示下外边框 | boolean | true |\r\n| initData | 输入框显示文案 | string | - |\r\n| maxlength | 输入的最大字符数 | number \\| string | 32 |\r\n| showAction | 是否在搜索框右侧显示取消按钮/图标 | boolean | false |\r\n| rightIcon | 是否在搜索框右侧显示图标 | boolean | false |\r\n| rightBtnText | 右侧文案配置 | string | - |\r\n| clearTrigger | 显示清除图标的时机,always 输入框不为空时展示,focus 输入框聚焦且不为空时展示 | string | focus |\r\n| formatter | 输入内容格式化函数 | (value: string) => string | - |\r\n\r\n### Slots\r\n\r\n| 插槽名 | 说明 |\r\n| ------ | ------------------ |\r\n| label | 搜索框内图标左侧插槽 |\r\n| left | 搜索框左侧内容插槽 |\r\n| action | 搜索框右侧操作按钮 '+' 左侧插槽 |\r\n| leftIcon | 搜索框内左侧图标插槽 |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 回调参数 |\r\n|-------------| -------------------- |------------------------|\r\n| onSearch | 确定搜索时触发 | value: string (当前输入的值) |\r\n| onInput | 输入框内容变化时触发 | value: string (当前输入的值) |\r\n| onFocus | 输入框获得焦点时触发 | event: Event |\r\n| onBlur | 当右侧按钮或图标被点击时触发 | event: Event |\r\n| rightAction | 输入框失去焦点时触发 | event: Event |\r\n| roleChange | 点击切换图标触发 | { mode: 1 \\| 0 } |\r\n| onCancle | 当右侧按钮为“取消”时,点击取消按钮触发 | event: Event |\r\n\r\n### Methods\r\n\r\n| 方法名 | 说明 | 参数 |\r\n|------------------|----------------------------------------------------------------------|-------------------------------------|\r\n| clear | 清空搜索框内容 | — |\r\n| onInputClear | 清空输入框内容 | value?: string |"
},
{
"name": "ws-action-sheet",
"category": "移动端组件库",
"content": "## WsActionSheet - 动作表单组件\r\n\r\n`WsActionSheet` 是一个基于 `Vant` 的动作表单组件,通常用于展示一组操作选项,用户可以点击选项执行相应的操作,与`vant ActionSheet`区别如下:\r\n- `value`属性名改为`show`。\r\n- 增加`closeOnClickAction`属性,提供点击选项后自动关闭的功能。\r\n- `cancel`取消事件和`clickOverlay`点击遮罩关闭事件内置为`update:show`事件控制组件的关闭。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsActionSheet` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsActionSheet } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsActionSheet\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsActionSheet` 组件用于展示一组操作选项,用户可以点击选项执行相应的操作。组件支持自定义选项、取消按钮、点击选项后自动关闭等功能。\r\n\r\n```html\r\n<template>\r\n <ws-action-sheet\r\n :show.sync=\"showActionSheet\"\r\n :actions=\"actions\"\r\n cancel-text=\"取消\"\r\n close-on-click-action\r\n @selectClick=\"handleSelect\"\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n showActionSheet: false,\r\n actions: [\r\n { name: '选项一' },\r\n { name: '选项二' },\r\n { name: '选项三' }\r\n ]\r\n };\r\n },\r\n methods: {\r\n handleSelect(action, index) {\r\n console.log('选中:', action, index);\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|--------------------|---------------------------------------|----------|------|-------|\r\n| show | 是否显示动作表单, 支持.sync修饰符 | boolean | — | false |\r\n| actions | 动作选项列表,数组中的每个对象代表一个选项, Action参考下面类型定义 | Action[] | — | [] |\r\n| cancel-text | 取消按钮的文本 | string | — | 取消 |\r\n| close-on-click-action | 是否在点击选项后关闭动作表单 | boolean | — | false |\r\n| get-container | 指定渲染的容器,默认渲染到 `body`,可以传入选择器或 DOM 元素 | string | — | body |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|--------------|------------------------------|-----------------------------------------|\r\n| selectClick | 当某个选项被点击时触发 | `active: Action, index: number` |\r\n\r\n### Methods\r\n\r\n| 方法名 | 说明 | 参数 |\r\n|------------------|------------------|----|\r\n| closeActionSheet | 手动关闭动作表单 | — |\r\n\r\n### Slots\r\n\r\n`WsActionSheet` 组件没有自定义插槽。\r\n\r\n### 类型定义\r\n\r\n```ts\r\ninterface Action {\r\n name: string; // 标题\r\n subname?: string; // 二级标题\r\n color?: string; // 选项文字颜色\r\n className?: string; // 为对应列添加额外的 class\r\n loading?: boolean; // 是否为加载状态\r\n disabled?: boolean; // 是否为禁用状态\r\n}\r\n```"
},
{
"name": "ws-custom-panel",
"category": "移动端组件库",
"content": "## WsCustomPanel - 自定义面板组件\r\n\r\n`WsCustomPanel` 是一个基于 `van-action-sheet` 和 `van-nav-bar` 封装的自定义面板组件,支持自定义标题、左右按钮、以及面板内容。该组件适用于需要弹出面板并展示自定义内容的场景。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsCustomPanel` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsCustomPanel } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsCustomPanel\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsCustomPanel` 组件可以通过 `show` 属性控制面板的显示与隐藏,并通过 `title` 属性设置面板的标题。\r\n\r\n```html\r\n<template>\r\n <ws-custom-panel\r\n :show.sync=\"showPanel\"\r\n title=\"自定义面板\"\r\n >\r\n <div>这里是面板的内容</div>\r\n </ws-custom-panel>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n showPanel: true\r\n };\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n#### 自定义标题栏\r\n\r\n通过设置 `type` 属性为 `customTitle`自定义标题栏,并通过 `leftBtn` 和 `rightBtn` 属性设置自定义标题栏左右按钮的文本。\r\n\r\n```html\r\n<template>\r\n <ws-custom-panel\r\n :show.sync=\"showPanel\"\r\n type=\"customTitle\"\r\n title=\"自定义标题栏\"\r\n left-btn=\"返回\"\r\n right-btn=\"确认\"\r\n @clickLeft=\"handleLeftClick\"\r\n @clickRight=\"handleRightClick\"\r\n >\r\n <div>这里是面板的内容</div>\r\n </ws-custom-panel>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n showPanel: true\r\n };\r\n },\r\n methods: {\r\n handleLeftClick() {\r\n console.log('点击了左侧按钮');\r\n },\r\n handleRightClick() {\r\n console.log('点击了右侧按钮');\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n#### 自定义容器\r\n\r\n通过 `getContainer` 属性可以指定面板的挂载容器,支持传入字符串选择器或函数。\r\n\r\n```html\r\n<template>\r\n <ws-custom-panel\r\n :show.sync=\"showPanel\"\r\n title=\"自定义容器\"\r\n :get-container=\"getContainer\"\r\n >\r\n <div>这里是面板的内容</div>\r\n </ws-custom-panel>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n showPanel: true\r\n };\r\n },\r\n methods: {\r\n getContainer() {\r\n return document.querySelector('#custom-container');\r\n }\r\n }\r\n};\r\n</script>\r\n\r\n<div id=\"custom-container\"></div>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------------|---------------------------------------------------------------------|-------------------------------|------------------|--------|\r\n| title | 面板的标题 | string | — | '标题' |\r\n| show | 是否显示面板, 支持.sync修饰符 | boolean | — | false |\r\n| type | 面板类型,`customTitle` 表示自定义标题栏 | string | default/customTitle | default |\r\n| left-btn | 自定义标题栏左侧按钮的文本 | string | — | — |\r\n| right-btn | 自定义标题栏右侧按钮的文本 | string | — | — |\r\n| get-container | 指定面板的挂载容器,支持字符串选择器或返回 DOM 元素的函数 | string \\| (() => HTMLElement) | — | — |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|-----------------|----------------------------------|---------|\r\n| clickLeft | 当自定义标题栏左侧按钮被点击时触发 | — |\r\n| clickRight | 当自定义标题栏右侧按钮被点击时触发 | — |\r\n| clickOverlay | 当点击遮罩层时触发 | — |\r\n\r\n### Slots\r\n\r\n| name | 说明 |\r\n|---------|--------------------------|\r\n| default | 面板的主要内容插槽 |"
},
{
"name": "ws-confirm",
"category": "移动端组件库",
"content": "## WsConfirm - 确认对话框\r\n\r\nWsConfirm 是一个确认对话框组件,通常用于需要用户确认操作的场景。该组件支持自定义标题、内容、按钮文字、按钮颜色等,用户可以通过点击确认或取消按钮来执行相应的操作。WsConfirm 组件基于遮罩层和弹窗的形式展示,支持点击遮罩层关闭对话框。\r\n\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsConfirm` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import Vue from 'vue';\r\n import { WsConfirm } from \"@wshoto/h5-base-ui\";\r\n Vue.use(WsConfirm)\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\nWsConfirm 组件可以通过 `$confirm` 方法来调用,传入的参数可以是字符串(作为内容)或对象(包含更多配置项)。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <ws-button @click=\"showConfirm\">单按钮展示</ws-button>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n methods: {\r\n showConfirm() {\r\n this.$confirm({\r\n title: '我是标题',\r\n content: '我是内容',\r\n confirm: () => {\r\n },\r\n });\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n\r\n#### 双按钮展示\r\n\r\n通过设置`isCancel`展示左侧按钮,默认为`false`;`isConfirm`属性来控制右侧按钮,默认`true`; 点击确认或取消按钮后,会触发相应的回调函数。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <ws-button @click=\"showConfirm\">显示确认对话框</ws-button>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n methods: {\r\n showConfirm() {\r\n this.$confirm({\r\n title: '确认操作',\r\n content: '您确定要执行此操作吗?',\r\n isCancel: true,\r\n confirm: () => {\r\n console.log('确认操作');\r\n },\r\n cancel: () => {\r\n console.log('取消操作');\r\n }\r\n });\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n#### 弹窗类型\r\n\r\n`WsConfirm` 支持三种弹窗类型:`success`、`info` 和 `error`。可以通过 `$confirm.success`、`$confirm.info` 和 `$confirm.error` 方法调用。\r\n\r\n### 1. `success` - 成功类型\r\n\r\n- **图标**:显示一个表示成功的图标(通常是一个绿色的对勾)。\r\n- **适用场景**:用于提示用户操作成功,或者确认某个操作是安全的、可行的。\r\n\r\n### 2. `info` - 信息类型\r\n\r\n- **图标**:显示一个表示信息的图标(通常是一个黄色的圆圈内带有 \"i\" 的符号)。\r\n- **适用场景**:用于提示用户一些重要的信息或通知,通常不涉及危险或错误。\r\n\r\n### 3. `error` - 错误类型\r\n\r\n- **图标**:显示一个表示错误的图标(通常是一个红色的叉号)。\r\n- **适用场景**:用于提示用户操作失败、错误或危险的操作,提醒用户需要谨慎处理。\r\n\r\n```js\r\n// `success` - 成功类型\r\nthis.$confirm.success({\r\n title: '操作成功',\r\n content: '您的操作已成功完成。',\r\n confirm: () => {\r\n console.log('确认按钮点击');\r\n }\r\n});\r\n\r\n// `info` - 信息类型\r\nthis.$confirm.info({\r\n title: '提示信息',\r\n content: '请注意,系统将在今晚进行维护。',\r\n confirm: () => {\r\n console.log('确认按钮点击');\r\n }\r\n});\r\n\r\n// `error` - 错误类型\r\nthis.$confirm.error({\r\n title: '操作失败',\r\n content: '删除文件时发生错误,请稍后重试。',\r\n confirm: () => {\r\n console.log('确认按钮点击');\r\n }\r\n});\r\n```\r\n\r\n#### 自定义按钮文字和颜色\r\n\r\n可以通过 `cancelText` 和 `confirmText` 自定义按钮文字,通过 `cancelColor` 和 `confirmColor` 自定义按钮颜色。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <ws-button @click=\"showCustomConfirm\">自定义按钮文字和颜色</ws-button>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n methods: {\r\n showCustomConfirm() {\r\n this.$confirm({\r\n title: '自定义按钮',\r\n content: '您确定要继续吗?',\r\n cancelText: '放弃',\r\n confirmText: '继续',\r\n cancelColor: '#ff0000',\r\n confirmColor: '#00ff00',\r\n isCancel: true,\r\n confirm: () => {\r\n console.log('继续操作');\r\n },\r\n cancel: () => {\r\n console.log('放弃操作');\r\n }\r\n });\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n#### 点击遮罩层关闭\r\n\r\n可以通过 `closeOnClickOverlay` 属性控制是否允许点击遮罩层关闭对话框。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <ws-button @click=\"showOverlayConfirm\">点击遮罩层关闭</ws-button>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n methods: {\r\n showOverlayConfirm() {\r\n this.$confirm({\r\n title: '点击遮罩层关闭',\r\n content: '点击遮罩层可以关闭对话框',\r\n closeOnClickOverlay: true,\r\n confirm: () => {\r\n console.log('确认操作');\r\n }\r\n });\r\n }\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n\r\n#### confirm直接传入字符串展示\r\n\r\n当传入内容超过两行为内容样式;不超过则展示为标题样式,当包含H5标签且包含用户生成内容时,需注意防范xss攻击。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <ws-button @click=\"titleVisitable()\">展示为标题-不超过两行内容</ws-button>\r\n <ws-button @click=\"contentVisitable()\">展示为内容-超过两行内容</ws-button>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n methods: {\r\n titleVisitable(){\r\n this.$confirm('当前内容不超过两行时');\r\n },\r\n contentVisitable() {\r\n this.$confirm('我是超过两行行文案<span style=\"color: red; font-size:12px\">超多内容超多内容超多内容超多内容超多内容超多内容超多内容超多内容超多内容</span>');\r\n },\r\n }\r\n};\r\n</script>\r\n```\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-------------------|--------------------------------------------------------------------|---------|-------------------------|---------|\r\n| type | 对话框类型,可显示不同的图标 | string | success/info/error | — |\r\n| isOverlay | 是否显示遮罩层 | boolean | — | true |\r\n| closeOnClickOverlay | 是否允许点击遮罩层关闭对话框 | boolean | — | true |\r\n| cancelText | 取消按钮的文字 | string | — | 取消 |\r\n| confirmText | 确认按钮的文字 | string | — | 确认 |\r\n| isCancel | 是否显示取消按钮 | boolean | — | false |\r\n| isConfirm | 是否显示确认按钮 | boolean | — | true |\r\n| cancelColor | 取消按钮的文字颜色 | string | — | #999 |\r\n| confirmColor | 确认按钮的文字颜色 | string | — | #2b60dd |\r\n| titleAlign | 标题的对齐方式 | string | left/center/right | center |\r\n| contentAlign | 内容的对齐方式 | string | left/center/right | center |\r\n| title | 对话框的标题 | string | — | null |\r\n| content | 对话框的内容 | string | — | null |\r\n\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n|----------------|------------------|----------|\r\n| confirm | 点击确认按钮时触发 | — |\r\n| cancel | 点击取消按钮时触发 | — |\r\n| clickOverlay | 点击遮罩层时触发 | — |\r\n\r\n### Methods\r\n\r\nWsConfirm 组件通过 `$confirm` 方法调用,支持以下方法:\r\n\r\n| 方法名 | 说明 | 参数 |\r\n|--------|--------------|----------|\r\n| info | 显示信息类型的对话框 | options |\r\n| success| 显示成功类型的对话框 | options |\r\n| error | 显示错误类型的对话框 | options |\r\n\r\n### Slots\r\n\r\nWsConfirm 组件不支持插槽。"
},
{
"name": "ws-button-h5",
"category": "移动端组件库",
"content": "## WsButton 组件\r\n\r\n业务中常用的操作按钮。按钮样式符合微盛UI规范,页面应该仅使用WsButton,不要使用ElButton\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsButton } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsButton', WsButton);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 由`type`属性指定 `WsButton` 的样式类型,用于控制按钮的颜色、边框、背景样式,默认值为 `default`。\r\n```html\r\n<template>\r\n <ws-button>默认</ws-button>\r\n <ws-button type=\"primary\">primary</ws-button>\r\n <ws-button type=\"border\">border</ws-button>\r\n <ws-button type='borderBG'>borderBG</ws-button>\r\n <ws-button type='info'>info</ws-button>\r\n <ws-button type='text'>文本按钮</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### 尺寸\r\n\r\n:::demo 由 `size` 属性指定 `WsButton` 的尺寸,用于按钮的大小,默认值为`normal`。\r\n```html\r\n<template>\r\n <ws-button type='primary' size='normal'>normal</ws-button>\r\n <ws-button type='primary' size='medium'>medium</ws-button>\r\n <ws-button type='primary' size='small'>small</ws-button>\r\n <ws-button circle size='normal'>normal</ws-button>\r\n <ws-button circle type='primary' size='medium'>medium</ws-button>\r\n <ws-button circle type='primary' size='small'>small</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### 块级\r\n\r\n:::demo `block` 属性为 `true` 时将按钮设置为块级元素,使其占据父容器的整个宽度,默认为 `false`。\r\n```html\r\n<template>\r\n <ws-button block>块级按钮</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### 圆角\r\n:::demo `circle` 属性为 `true` 时将按钮的形状从长方形变成椭圆形,默认为 `false`。\r\n```html\r\n<template>\r\n <ws-button circle>默认</ws-button>\r\n <ws-button circle type='primary'>primary</ws-button>\r\n <ws-button circle type='border'>border</ws-button>\r\n <ws-button circle type='borderBG'>borderBG</ws-button>\r\n <ws-button circle type='info'>info</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### 加载状态\r\n:::demo `loading` 属性为 `true` 时按钮处于加载状态,此时点击按钮无事件抛出。常用于异步操作或耗时操作的场景,默认为 `false`。\r\n```html\r\n<template>\r\n <ws-button type='primary' :loading='loading'>主要按钮</ws-button>\r\n</template>\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### 禁用状态\r\n:::demo `disabled` 属性为 `true` 时按钮处于禁用状态,默认为 `false`,常用于限制用户提交表单场景。若此时点击可触发 `disabledClick` 事件,此场景常用于提示按钮被禁用的原因。\r\n```html\r\n<template>\r\n <ws-button disabled>默认</ws-button>\r\n <ws-button type='primary' disabled>primary</ws-button>\r\n <ws-button type='border' disabled>border</ws-button>\r\n <ws-button type='info' disabled>info</ws-button>\r\n <ws-button type='text' disabled>文本按钮</ws-button>\r\n <ws-button type='text' disabled @disabledClick=\"disabledClick\">按钮禁用事件</ws-button>\r\n</template>\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n }\r\n },\r\n methods: {\r\n disabledClick() {\r\n this.$toast('禁用的原因')\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### 边框\r\n:::demo `hairline` 属性为 `false` 时按钮边框为粗边框,用于控制按钮的边框效果,默认为 `true`。\r\n```html\r\n<template>\r\n <ws-button color='#2B60DD' :hairline='false'>#2B60DD</ws-button>\r\n <ws-button color='#E32323' :hairline='false'>#E32323</ws-button>\r\n <ws-button color='#07c160' :hairline='false'>#07c160</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### 自定义\r\n:::demo 由 `color` 属性指定 `WsButton` 的文案颜色,不会影响背景色。\r\n```html\r\n<template>\r\n <ws-button color='#2B60DD' :hairline='false'>#2B60DD</ws-button>\r\n <ws-button color='#E32323' :hairline='false'>#E32323</ws-button>\r\n <ws-button color='#07c160' :hairline='false'>#07c160</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### 红点\r\n:::demo `dot` 为 `true` 时按钮右上角会出现红点,常用于提醒用户有未读消息、通知或其他需要关注的内容,默认为 `false`。\r\n```html\r\n<template>\r\n <ws-button color='#07c160' :hairline='false' dot>#07c160</ws-button>\r\n</template>\r\n```\r\n:::\r\n\r\n### Props\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------- | -------------- | ------- | ----------------------------------------- | ------- |\r\n| type | 类型 | string | default/primary/border/borderBG/info/text | default |\r\n| size | 尺寸 | string | normal/small | normal |\r\n| color | 按钮颜色设置 | string | - | - |\r\n| block | 是否为块级元素 | boolean | - | false |\r\n| hairline | 是否为细边框 | boolean | - | true |\r\n| circle | 是否圆角按钮 | boolean | - | false |\r\n| loading | 是否加载中状态 | boolean | - | false |\r\n| disabled | 是否禁用状态 | boolean | - | false |\r\n| dot | 红点配置 | boolean | - | false |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ------------------ | ------------ |\r\n| click | 主按钮点击触发事件 | event: Event |\r\n| disabledClick | 主按钮禁用状态下的点击触发事件 | event: Event |"
},
{
"name": "ws-button-bar",
"category": "移动端组件库",
"content": "## WsButtonBar 组件\r\n\r\n基于 `WsButton` 封装,支持单按钮、双按钮、多按钮、带图标按钮多种布局。常用于页面中有多个主要操作和次要操作的场景。\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsButtonBar } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsButtonBar', WsButtonBar);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 类型 default: # 页面仅有1个操作时使用。\r\n```html\r\n<template>\r\n <ws-button-bar background='#fff' @click='mainHandleClick' :hairline='true' />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型 doubleEqual: # 页面有2个主要操作,按钮层级需要做区别时使用,此时两个按钮大小一致。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n type='doubleEqual'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n :mainLoading='loading'\r\n @click='mainHandleClick'\r\n @secondaryClick='secondaryHandleClick'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n },\r\n secondaryHandleClick() {\r\n this.$toast('我是次按钮');\r\n },\r\n againHandleClick() {\r\n this.$toast('我是文本按钮');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型 doubleMain: # 页面有2个操作,按钮主要层级需要做明显区别时使用,此时主按钮宽度比次按钮长。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleMain'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n mainDisabled\r\n @click='mainHandleClick'\r\n @secondaryClick='secondaryHandleClick'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n },\r\n secondaryHandleClick() {\r\n this.$toast('我是次按钮');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型 doubleEqualText: # 页面2个主要操作需要强调,并且需要带取消操作时使用。若取消操作不是纯文本,需使用插槽 `left` 展示内容。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleEqualText'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n againText='取消'\r\n @click='mainHandleClick'\r\n @secondaryClick='secondaryHandleClick'\r\n @textClick='againHandleClick'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n },\r\n secondaryHandleClick() {\r\n this.$toast('我是次按钮');\r\n },\r\n againHandleClick() {\r\n this.$toast('我是取消按钮');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型 defaultIcon: # 单按钮+icon样式(含 `left` 插槽使用)\r\n```html\r\n<template>\r\n <ws-button-bar type='defaultIcon' mainText='主要按钮' @click='mainHandleClick'>\r\n <div slot='left' style='display: flex'>\r\n <div class='slot-left' v-for='i in 3' :key='i'>\r\n <!-- <svg-icon class='fs15' :src=\"require('../assets/searchIcon.svg')\" /> -->\r\n <img src=\"~examples/assets/h5/searchIcon.svg\" alt=\"\">\r\n <span class='fs11' style='color: #545454'>文案</span>\r\n </div>\r\n </div>\r\n </ws-button-bar>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型 doubleEqualIcon: # 双按钮+icon样式(含 `left` 插槽使用)\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleEqualIcon'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n @click='mainHandleClick'\r\n @secondaryClick='secondaryHandleClick'\r\n >\r\n <div slot='left' style='display: flex'>\r\n <div class='slot-left'>\r\n <!-- <svg-icon class='fs15' :src=\"require('../assets/searchIcon.svg')\" style='font-size: 15px' /> -->\r\n <img src=\"~examples/assets/h5/searchIcon.svg\" alt=\"\">\r\n <span class='fs11' style='color: #545454'>文案</span>\r\n </div>\r\n </div>\r\n </ws-button-bar>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n },\r\n secondaryHandleClick() {\r\n this.$toast('我是次按钮');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### 按钮文案\r\n\r\n:::demo 通过 `mainText` 属性设置主要按钮文案;通过 `secondaryText` 属性设置次要按钮文案;通过 `againText` 属性设置取消按钮文案。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleEqualText'\r\n mainText='主按钮'\r\n secondaryText='次按钮'\r\n againText='取消按钮'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {}\r\n },\r\n methods: {}\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### 文案、背景色\r\n\r\n:::demo `mainColor` 控制主要按钮文本颜色;`secondaryColor` 控制次按钮文本颜色(仅在双按钮布局中有效); `background` 控制按钮栏背景颜色\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleMain'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n mainDisabled\r\n mainColor='#2B60DD'\r\n secondaryColor='#E32323'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {}\r\n },\r\n methods: {}\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### 加载状态\r\n\r\n:::demo `mainLoading` 、`secondaryLoading` 属性为 `true` 时按钮处于加载状态,此时点击按钮无事件抛出。常用于异步操作或耗时操作的场景,默认为 `false`。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleEqual'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n :mainLoading='loading'\r\n :secondaryLoading='secondaryLoading'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true,\r\n secondaryLoading: true\r\n }\r\n },\r\n methods: {}\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 禁用状态\r\n\r\n:::demo `mainDisabled` 、`secondaryDisabled` 属性为 `true` 时按钮处于禁用状态。其中点击主按钮可触发 `disabledClick` 事件,此场景常用于提示按钮被禁用的原因。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n background='#fff'\r\n type='doubleEqual'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n :mainDisabled='mainDisabled'\r\n :secondaryDisabled='secondaryDisabled'\r\n @disabledClick='disabledClick'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n mainDisabled: true,\r\n secondaryDisabled: true\r\n }\r\n },\r\n methods: {\r\n disabledClick() {\r\n this.$toast('禁用原因');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### 边框\r\n\r\n:::demo `hairline` 属性为 `true` 时组件上方出现 `1px` 的边框,默认为 `false`。\r\n```html\r\n<template>\r\n <ws-button-bar\r\n hairline\r\n background='#fff'\r\n type='doubleEqual'\r\n mainText='主要按钮'\r\n secondaryText='次要按钮'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n mainDisabled: true,\r\n secondaryDisabled: true\r\n }\r\n },\r\n methods: {\r\n disabledClick() {\r\n this.$toast('禁用原因');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 |\r\n| ----------------- | ------------------------------------------------------------------------------------------------------------------ | ------- | --------- |\r\n| background | 背景颜色 | string | #F2F4F8 |\r\n| type | 按钮类型,可选项为 default、doubleEqual、doubleMain、defaultIcon、doubleEqualIcon 和 doubleEqualText。 | string | default |\r\n| mainText | 主按钮文本 | string | 确定 |\r\n| secondaryText | 次按钮文本 | string | 取消 |\r\n| againText | 次次按钮文本 | string | 取消 |\r\n| mainColor | 主按钮颜色 | string | - |\r\n| secondaryColor | 次按钮颜色 | string | - |\r\n| mainLoading | 主按钮是否显示为加载状态 | boolean | false |\r\n| secondaryLoading | 次按钮是否显示为加载状态 | boolean | false |\r\n| mainDisabled | 主按钮是否禁用 | boolean | false |\r\n| secondaryDisabled | 次按钮是否禁用 | boolean | false |\r\n| hairline | 配置按钮上边框 | boolean | false |\r\n\r\n#### type 可选值\r\n\r\n- default:页面仅有一个操作时使用。\r\n- doubleEqual:页面有两个主要操作,按钮层级需要做区别时使用。\r\n- doubleMain:页面有两个操作,按钮主要层级需要做明显区别时使用。\r\n- defaultIcon:单按钮 + icon 样式。\r\n- doubleEqualIcon:双按钮 + icon 样式。\r\n- doubleEqualText:页面两个主要操作需要强调,并且需要带取消操作时使用。\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ---- | ------------------ |\r\n| left | 自定义左侧操作区域 |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------------- | -------------------- | ------------ |\r\n| click | 主按钮点击触发事件 | event: Event |\r\n| secondaryClick | 次按钮点击触发事件 | event: Event |\r\n| textClick | 取消按钮点击触发事件 | event: Event |\r\n| disabledClick | 主按钮禁用状态下点击触发事件 | event: Event |"
},
{
"name": "ws-fix-bottom-layout",
"category": "移动端组件库",
"content": "## WsFixBottomLayout - 底部固定布局组件\r\n\r\n`WsFixBottomLayout` 是一个用于在页面底部固定显示内容的布局组件,通常用于在移动端页面中固定显示底部操作栏。组件内部处理了软键盘弹起时的布局调整,确保底部固定区域不会被遮挡。\r\n\r\n- 组件支持 Android 和 iOS 两种平台的软键盘弹起处理,确保输入框聚焦时页面布局不会错乱。\r\n- 组件通过监听软键盘的弹起和收起,动态显示或隐藏底部的悬浮按钮。\r\n- 组件提供了一个插槽用于放置底部固定的内容,并自动计算底部区域的高度,确保页面内容不会被遮挡。 \r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsFixBottomLayout` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsFixBottomLayout } from '@wshoto/h5-base-ui';\r\n\r\n export default {\r\n components: {\r\n WsFixBottomLayout\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用 \r\n\r\nWsFixBottomLayout 组件用于在页面底部固定显示内容。通过 `bottom` 插槽可以自定义底部固定区域的内容。\r\n常用场景:长表单页,底部`WSButtonBar`固定在屏幕底部,内容区域可滚动;底部固定区域所有脱离文档流布局均不适用于本组件,使用`WsFooter`。\r\n\r\n```html\r\n<template>\r\n <ws-fix-bottom-layout> \r\n <div>页面内容</div>\r\n <template v-slot:bottom>\r\n <ws-button-bar />\r\n </template>\r\n </ws-fix-bottom-layout>\r\n</template>\r\n```\r\n\r\n#### 软键盘弹起处理\r\n\r\n在 Android 和 iOS 设备上,软键盘弹起时,组件会自动隐藏底部固定区域,确保输入框不会被遮挡。软键盘收起后,底部固定区域会重新显示。\r\n\r\n```html\r\n<template>\r\n <ws-fix-bottom-layout>\r\n <template v-slot:bottom>\r\n <div>底部固定内容</div>\r\n </template>\r\n <input type=\"text\" placeholder=\"点击输入\" />\r\n </ws-fix-bottom-layout>\r\n</template>\r\n```\r\n\r\n#### 自定义底部背景色\r\n\r\n可以通过 `bottomBackgroundColor` 属性自定义底部固定区域的背景色。\r\n\r\n```html\r\n<template>\r\n <ws-fix-bottom-layout bottomBackgroundColor=\"#ffffff\">\r\n <div>页面内容</div>\r\n <template v-slot:bottom>\r\n <div>底部固定内容</div>\r\n </template>\r\n </ws-fix-bottom-layout>\r\n</template>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------------------|--------------------------------|---------|------|-------|\r\n| bottomBackgroundColor | 底部固定区域的背景色 | string | — | #f2f4f8 |\r\n| fixedInput | 是否强制显示底部固定区域,即使软键盘弹起时也显示 | boolean | — | false |\r\n\r\n### Events\r\n\r\n无额外事件。\r\n\r\n### Methods\r\n\r\n无额外方法。\r\n\r\n### Slots\r\n\r\n| name | 说明 |\r\n|-------|----------------------------------------------------------------------|\r\n| bottom | 底部固定区域的插槽,通常用于放置底部操作按钮或其他固定内容。 |\r\n| default | 页面内容插槽,页面的主要内容会放置在此插槽中,底部区域会根据内容高度自动调整。 |"
},
{
"name": "ws-dep-selector",
"category": "移动端组件库",
"content": "## WsSelector 选人页面组件\r\n\"选人页面组件\"是一个移动端页面级组件,用于选择企业员工和部门。该组件支持配置数据权限、单选/多选、可选节点等功能。在使用前,请确保在发起页路由信息的 `meta` 中将 `keepAlive` 设置为 `auto`。然后,通过 `pageStack` 跳转至选人页面,并监听 `pageResult` 事件以获取已选节点信息。\r\n\r\n\r\n### 基本用法\r\n```html\r\n<ws-button @click=\"select\">选择员工</ws-button>\r\n\r\n<script lang=\"ts\">\r\nimport Vue from 'vue';\r\nimport { WsDeptSelectorTypes } from '@wshoto/h5-base-ui';\r\n\r\nexport default Vue.extend({\r\n data () {\r\n return {\r\n selectUserRequestType: 'SELECT_USER',\r\n // 已选员工节点集合\r\n userList: [] as WsDeptSelectorTypes.UserNodeResult[],\r\n // 已选部门节点集合\r\n deptList: [] as WsDeptSelectorTypes.DepNodeResult[],\r\n // 组织架构树\r\n fullList: [] as WsDeptSelectorTypes.DataNode[]\r\n };\r\n },\r\n created () {\r\n // 监听 pageResult 事件,获取已选节点信息\r\n this.$on('pageResult', (requestType, pageResult: WsDeptSelectorTypes.SelectorResult) => {\r\n if (requestType === this.selectUserRequestType) {\r\n const { fullList = [], checkedStaffList = [], checkedDepsList = [] } = pageResult;\r\n // 已选的员工节点集合\r\n this.userList = checkedStaffList;\r\n // 已选的部门节点集合\r\n this.deptList = checkedDepsList;\r\n // 已经加载过的组织架构树,可在下次重新选择时传给选人页面,选人页面可以复用组织架构树\r\n this.fullList = fullList;\r\n }\r\n });\r\n },\r\n methods: {\r\n select() {\r\n // 选人页面路由信息\r\n const router = { name: 'WsSelector' };\r\n\r\n // 携带的参数,用于配置选人页面功能\r\n const payload = {\r\n // 默认选中的员工id集合\r\n initStaffList: this.userList.map(item => ({ userId: item.userId })),\r\n // 默认选中的部门id集合\r\n initDepList: this.deptList.map(item => ({ depId: item.depId })),\r\n // 复用组织架构树,避免每次进入选人页面后加载组织架构树\r\n fullList: this.fullList\r\n };\r\n\r\n // 通过 $pageStack 跳转至选人页面,并在 created 生命周期中监听事件获取已选节点信息\r\n this.$pageStack.requestPageResult(this.selectUserRequestType, router, payload);\r\n }\r\n }\r\n});\r\n</script>\r\n```\r\n\r\n### 配置数据源是否带有权限\r\n可以通过传递 `authorityType` 参数来设置数据源是否带有权限。当 `authorityType` 的取值为1时,表示数据源带有权限;取值为2时,表示数据源不带权限。默认情况下,`authorityType` 的取值为1,即数据源带有权限。\r\n\r\n\r\n### 单选/多选\r\n可以通过传递 `model` 参数来设置选择节点类型。当 `model` 的取值为1时,表示单选;取值为2时,表示多选。默认情况下,`model` 的取值为2,即支持多选。\r\n\r\n\r\n### 配置可选择的节点类型\r\n可以通过传递 `choiceType` 参数来设置选择节点类型。当 `choiceType` 的取值为1时,表示仅可以选择员工节点;取值为2时,表示仅可以选择部门节点;取值为3时,表示可以选择员工和部门节点。默认情况下,`choiceType` 的取值为3,即可以选择员工和部门节点。\r\n\r\n\r\n### 配置员工标签功能\r\n筛选具有指定的员工标签的员工集合,可以通过 `tagSelect` 参数进行配置。当 `tagSelect` 的值为 true 时表示开启该功能,默认值为 false,即默认不开启。\r\n`initUserTagList` 属性表示默认选中的 员工标签,需和 `tagSelect` 属性配合使用; `userTagLimit` 属性表示 员工标签 最大的选择数量。\r\n\r\n```html\r\n<ws-button @click=\"select\">选择员工</ws-button>\r\n\r\n<script lang=\"ts\">\r\nimport Vue from 'vue';\r\nimport { WsDeptSelectorTypes } from '@wshoto/h5-base-ui';\r\n\r\nexport default Vue.extend({\r\n data () {\r\n return {\r\n selectUserRequestType: 'SELECT_USER',\r\n // 已选员工节点集合\r\n userList: [] as WsDeptSelectorTypes.UserNodeResult[],\r\n // 已选部门节点集合\r\n deptList: [] as WsDeptSelectorTypes.DepNodeResult[],\r\n // 已选员工标签集合\r\n userTagList: [] as WsDeptSelectorTypes.UserTagItem[],\r\n // 组织架构树\r\n fullList: [] as WsDeptSelectorTypes.DataNode[]\r\n }\r\n },\r\n created () {\r\n // 监听 pageResult 事件,获取已选节点信息\r\n this.$on('pageResult', (requestType, pageResult: WsDeptSelectorTypes.SelectorResult) => {\r\n if (requestType === this.selectUserRequestType) {\r\n const { fullList = [], checkedStaffList = [], checkedDepsList = [], checkedUserTagList = [] } = pageResult;\r\n // 已选的员工节点集合\r\n this.userList = checkedStaffList;\r\n // 已选的部门节点集合\r\n this.deptList = checkedDepsList;\r\n // 已选的员工标签\r\n this.initUserTagList = checkedUserTagList;\r\n // 已经加载过的组织架构树,可在下次重新选择时传给选人页面,选人页面可以复用组织架构树\r\n this.fullList = fullList;\r\n }\r\n });\r\n },\r\n methods: {\r\n select() {\r\n // 选人页面路由信息\r\n const router = { name: 'WsSelector' };\r\n\r\n // 携带的参数,用于配置选人页面功能\r\n const payload = {\r\n // 默认选中的员工id集合\r\n initStaffList: this.userList.map(item => ({ userId: item.userId })),\r\n // 默认选中的部门id集合\r\n initDepList: this.deptList.map(item => ({ depId: item.depId })),\r\n // 默认选中的员工标签\r\n initUserTagList: this.userTagList.map(item => { return { ...item, dataType: 'userTag' }; }),\r\n // 复用组织架构树,避免每次进入选人页面后加载组织架构树\r\n fullList: this.fullList,\r\n // 开启选择员工标签功能\r\n tagSelect: true\r\n };\r\n\r\n // 通过 $pageStack 跳转至选人页面,并在 created 生命周期中监听事件获取已选节点信息\r\n this.$pageStack.requestPageResult(this.selectUserRequestType, router, payload);\r\n } \r\n }\r\n})\r\n</script>\r\n```\r\n\r\n### 参数说明\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------------- | ---------------- | -------------- | ------------- | --------------- |\r\n| initStaffList | 已选的员工id集合 | string[] | - | [] |\r\n| initDepList | 已选的部门id集合 | number[] | - | [] |\r\n| initUserTagList | 已选的员工标签 | UserTagItem[] | - | [] |\r\n| fullList | 组织架构树 | DataNode[] | - | [] |\r\n| disableList | 禁用的节点集合 | DisabledNode[] | - | [] |\r\n| authorityType | 数据源是否带权限。1:数据源带权限;2:数据源不带权限; | number | 1 \\| 2 | 1 |\r\n| model | 1:单选;2:多选 | number | 1 \\| 2 | 2 |\r\n| choiceType | 选择节点类型。1:员工;2:部门;3:员工和部门; | number | 1 \\| 2 \\| 3 | 3 |\r\n| tagSelect | 是否开启员工标签 | boolean | - | false |\r\n| userTagLimit | 员工标签最大选择数量 | number | - | 5 |\r\n| pageTitle | 页面title | string | - | 选择添加人 |\r\n| readOnly | 所有节点是否禁止选择 | boolean | - | false |\r\n| disableTipsText | 点击禁选员工提示文案 | string | - | 使用员工中已包含该员工 |\r\n| checkedPanelTitle | 已选文案 | string | - | 已选 |\r\n| selectLimit | 员工最大选择数(已选员工和已选部门下员工的总和,员工不去重) | number | - | - |\r\n| limitTips | 选择数量超过最大数量限制的提示 | string | - | 超过上限了 |\r\n| shape | 用于指定业务场景下展示指定状态的员工: select:创建任务时选择员工或部门,禁止选择成员状态是已禁用,退出企业或已离职的节点,禁止选择账号状态是未开通或已过期的节点;filter:列表筛选条件场景,列表筛选时选择员工/部门,支持选择“已禁用,退出企业,未开通,已过期”节点,若存在已离职员工吗,则展示”已离职员工“分组;filter-none-auth-node:列表筛选条件场景(未开通/已过期成员置灰不能选)禁止账号状态为未开通和已过期,目前主要应用于客户/客户群列表数据和统计的筛选场景。 | string | select \\| filter \\| filter-none-auth-node | select |\r\n| limit | 用于限制选择人数场景,为提高查询性能,在某些业务场景禁止选择人数超过1000。当该属性为true时,选择人数超200时,点击对话框确定按钮关闭对话框,并toast提示:“已选成员数超过200,查询时间可能比较长,可适当减少成员数”;当选择的成员数量超过1000人,点击对话框确定按钮不关闭对话框,并toast提示:“每次查询最多只能选择1000个成员”; | boolean | - | false |\r\n| openScene | 用于展示不同开通场景下选人组件员工节点的提示,normal: 通用功能开通权限; session : 会话存档开通权限 | string | normal \\| session | normal |\r\n\r\n\r\n### 类型定义\r\n导入方式\r\n可以从 @wshoto/h5-base-ui 库中导入 WsDeptSelectorTypes,这是一个包含组件相关类型的 TypeScript 命名空间。以下是示例用法:\r\n\r\n```typescript\r\nimport { WsDeptSelectorTypes } from '@wshoto/h5-base-ui';\r\n\r\ntype SelectorResult = WsDeptSelectorTypes.SelectorResult;\r\n```\r\n\r\n内置的类型定义包括:\r\n- `WsDeptSelectorTypes.SelectorResult`: 选择结果类型定义。\r\n- `WsDeptSelectorTypes.UserNodeResult`: 选择的员工节点类型定义。\r\n- `WsDeptSelectorTypes.DepNodeResult`: 选择的部门节点类型定义。\r\n- `WsDeptSelectorTypes.UserTagItem`: 选择的员工标签节点类型定义。\r\n- `WsDeptSelectorTypes.NodeUser`: 组织架构树中的员工节点类型定义。\r\n- `WsDeptSelectorTypes.NodeDep`: 组织架构树中的部门节点类型定义。\r\n- `WsDeptSelectorTypes.DataNode`: 组织架构树中的节点类型定义。\r\n- `WsDeptSelectorTypes.DisabledUser`: 单选框组件的属性类型定义。\r\n- `WsDeptSelectorTypes.DisabledDep`: 单选框组件的属性类型定义。\r\n- `WsDeptSelectorTypes.DisabledNode`: 单选框组件的属性类型定义。\r\n\r\n```typescript\r\n// 已选成员节点类型\r\ntype UserNodeResult = {\r\n userId: string; // 员工id\r\n name?: string; // // 员工id,冗余字段\r\n};\r\n\r\n// 已选部门节点类型\r\ntype DepNodeResult = {\r\n depId: number; // 部门id\r\n name?: string; // 部门id,冗余字段\r\n count?: number; // 部门下有多少员工\r\n};\r\n\r\n// 员工标签类型\r\ntype UserTagItem = {\r\n tagId: string, // 标签Id\r\n tagName: string, // 标签名称\r\n createSource?: TagCreateSourceEnum, // 标签来源\r\n tagStatus?: TagStatusEnum, // 标签状态\r\n readOnly?: 1 | 0, // 是否只读\r\n exceptionCause?: string // 是否只读\r\n}\r\n\r\n// 页面页面返回结果类型\r\ntype SelectorResult = {\r\n checkedStaffList: Array<UserNodeResult>; // 已选员工集合\r\n checkedDepsList: Array<DepNodeResult>; // 已选部门集合\r\n checkedUserTagList: Array<UserTagItem>; // 已选员工标签集合\r\n fullList: Array<DataNode>; // 组织架构树\r\n};\r\n\r\n// 禁用员工类型\r\ntype DisabledUser = { userId: string; };\r\n// 禁用部门类型\r\ntype DisabledDep = { depId: number; count?: number; }\r\n// 禁用节点类型\r\ntype DisabledNode = DisabledUser | DisabledDep;\r\n\r\ntype NodeParent = {\r\n id?: number; // 节点的id\r\n count?: number | null, // 如果是部门节点,部门下有多少人\r\n name?: string; // 节点名称,showOriginName为true时,可使用name渲染名称\r\n leaf?: boolean; // 是否是叶子节点\r\n parentId?: number; // 节点的父部门id\r\n showOriginName?: boolean; // 组织架构树节点名称默认使用open-data-box渲染,如果传递showOriginName,可以搭配name直接使用html原生标签渲染\r\n customTags?: TagNode[]; // 节点右侧的标签集合\r\n hiddenTips?: boolean; // 是否隐藏节点展示主部门信息的icon\r\n status?: 0 | 1 | 2 | 4 | 5 | 99; // 员工节点状态:0-无效,不在可见范围内,1-已激活,2-已禁用,4-未激活,5-退出企业,99-已离职\r\n accountStatus?: 1 | 2 | 3; // 账号状态:1-未开通, 2-已开通, 3-已过期\r\n openAccountStatus?: 1 | 2 | 3; // 原accountStatus\r\n sessionUsesStatus?: 0 | 1 | 2; // 会话存档使用权限状态 0未开通 1开通 2已过期\r\n commonUsesStatus?: 0 | 1 | 2; // 通用功能使用权限状态 0未开通 1开通 2已过期\r\n}\r\n\r\n// 员工节点\r\ntype NodeUser = {\r\n isUser: true; // 是员工节点\r\n userId: string; // 员工id\r\n} & NodeParent;\r\n\r\n// 部门节点\r\ntype NodeDep = {\r\n isUser: false; // 非员工节点,即部门节点\r\n deptId: number; // 部门id\r\n depId?: number; // 部门id,冗余字段\r\n children?: Array<NodeUser | NodeDep>;\r\n} & NodeParent\r\n\r\n// 树节点\r\ntype DataNode = NodeUser | NodeDep;\r\n\r\n// 标签来源\r\nenum TagCreateSourceEnum {\r\n QW_SYNC = 'QW_SYNC', // 企业微信同步\r\n OPEN_API = 'OPEN_API', // 本应用API创建\r\n PC_BACKEND = 'PC_BACKEND', // PC端后台创建\r\n AI_BOUND = 'AI_BOUND' // 智能外呼创建\r\n}\r\n\r\n// 标签标签\r\nexport enum TagStatusEnum {\r\n NORMAL = 1, // 正常\r\n EXCEPTION = 2 // 异常\r\n}\r\n```\r\n\r\n### 注意事项\r\n::: tip\r\n在已经加载过组织架构树并希望复用的情况下,可以将返回的 `fullList` 存储在本地。然后,在调用选人页面时,将存储的 `fullList` 传递给选人页面,以便实现数据的复用。这样可以避免每次进入选人页面都重新加载组织架构树,提高效率和用户体验。\r\n:::"
},
{
"name": "ws-field-factory-h5",
"category": "移动端组件库",
"content": "## FieldFactory 自定义字段组件\r\n\r\n\r\n### 引入\r\n\r\n```js\r\nimport { FieldFactory } from '@wshoto/h5-base-ui';\r\n\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo FieldFactory提供了5种使用场景,创建,编辑,详情,收集表编辑(定制),收集表预览(定制)\r\n```html\r\n<template>\r\n <field-factory ref=\"factory\" shape=\"create\" :options=\"options\" />\r\n</template>\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n loading: true,\r\n options: [\r\n {\r\n groupTitle: '个人信息',\r\n forms: [\r\n {\r\n type: 'formInput',\r\n props: {\r\n sort: 1,\r\n field: 'field-1',\r\n fieldType: 1,\r\n label: '单行文本',\r\n value: '范德萨范德',\r\n required: true,\r\n validator: (val) => {\r\n const max = 5;\r\n if (val.length > max) {\r\n return new Error(`不允许超过${max}个字符`);\r\n }\r\n }\r\n }\r\n },\r\n {\r\n type: 'formSelect',\r\n props: {\r\n sort: 4,\r\n field: 'field-2',\r\n fieldType: 1,\r\n label: '下拉多选',\r\n value: [],\r\n multiple: true,\r\n actions: [{ name: '选我选我' }, { name: '删除选择' }],\r\n options: [\r\n { id: '1', name: '建国' },\r\n { id: '2', name: '呼兰' },\r\n { id: '3', name: '呼兰' },\r\n { id: '4', name: '呼兰' },\r\n { id: '5', name: '呼兰' },\r\n { id: '6', name: '呼兰' },\r\n { id: '7', name: '呼兰' },\r\n { id: '8', name: '呼兰' }\r\n ],\r\n required: true\r\n }\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n::: tip\r\n 目前支持子组件类型有:单行文本,多行文本,数据输入框,单选,多选,级联,地区选择,日期,附件,标签,定位,at人\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------- |-------------- |---------- |-------------------------------- |-------- |\r\n| shape | 不同场景的展示形态:提供了5种使用场景,创建,编辑,详情,收集表编辑(定制),收集表预览(定制) | string | create/edit/info/info-up-down/collect_form_info | — |\r\n| options | 字段配置 | Array\\<FieldProp \\| FormNode\\> | - | — |\r\n\r\n\r\n### Event\r\n| 事件名称 | 说明 | 回调参数 |\r\n|---------- |-------- |---------- |\r\n|change | 字段值发生变化时触发 |{ field: string; label: string; value: any; } |\r\n\r\n\r\n### Methods\r\n\r\n通过refs调用\r\n\r\n| 名称 | 说明 | 类型 | 返回值 |\r\n| ------- | ------------------ | --------- | --------- |\r\n| getValue | 获取所有字段的值 | () => Params[] | Params[] |\r\n| setState | 根据field设置该字段的值 | (field: string, value: any) => void | - |\r\n| validate | 验证所有字段的值是否合法 | (callback: (state: boolean; payload: Params[]) => void) => void | - |\r\n| validateField | 根据field验证该字段的值是否合法 | (field: string,callback: (state: boolean) => void) => void | - |\r\n\r\n### OptionNode\r\n```\r\n// 选项类型\r\ntype OptionNode = {\r\n id: string; // 选项id\r\n name: string; // 选项名称\r\n children?: OptionNode[]; // 子集\r\n}\r\n```\r\n\r\n### FormNode\r\n```\r\ntype FormNode = {\r\n type: string; // 字段类型对应的基础组件名称,例如:formInput\r\n props: {\r\n field: string; // 字段id\r\n label: string; // 字段的label\r\n value?: any; // 字段的值\r\n placeholder?: string; // 输入框的placeholder\r\n required?: boolean; // 是否必填\r\n disabled?: boolean; // 是否禁止修改\r\n maxlength?: string; // 最大长度\r\n multiple?: boolean; // 单选/多选字段,是否多选\r\n area?: boolean; // 级联字段是否选择地区\r\n options?: OptionNode[]; //\r\n validator?: <T>(params: T) => (Error | undefined); // 单个字段的自定义校验\r\n }\r\n}\r\n```\r\n### FieldProp\r\n\r\n```\r\ntype FieldProp = {\r\n groupTitle: string;\r\n forms: FormNode[]\r\n}\r\n```\r\n### Params\r\n\r\n```\r\ntype Params = {\r\n field: string; // 字段id\r\n fieldType?: number; // 字段类型\r\n label: string; // 字段label\r\n value: any; // 值\r\n required?: boolean; // 是否必填\r\n system: boolean; // 是否系统字段\r\n default: boolean; // 是否默认字段\r\n}\r\n```"
},
{
"name": "ws-bottom-tab",
"category": "移动端组件库",
"content": "## 标签Tab\r\n### 简介\r\n用于页面底部的标签切换,可自定义样式\r\n\r\n### 引入\r\n\r\n```jsx\r\nimport { WeShineBottomTab, WeShineBottomTabItem } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineBottomTab', WeShineBottomTab);\r\nVue.component('WeShineBottomTabItem', WeShineBottomTabItem);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 基础用法\r\n\r\n```html\r\n<template>\r\n <we-shine-bottom-tab v-model='active'>\r\n <we-shine-bottom-tab-item icon=\"icon-lib-equalratio\">首页</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item icon=\"icon-lib-original\">查看</we-shine-bottom-tab-item>\r\n </we-shine-bottom-tab>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n active: 0,\r\n firstIcon: require('../../assets/h5/tab-icon-home-normal.png'),\r\n firstActiveIcon: require('../../assets/h5/tab-icon-home.png'),\r\n secondIcon: require('../../assets/h5/tab-icon-mine-normal.png'),\r\n secondActiveIcon: require('../../assets/h5/tab-icon-mine.png')\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 通过名称匹配\r\n:::demo 在标签指定 name 属性的情况下,v-model 的值为当前标签的 name。\r\n\r\n```html\r\n<template>\r\n <we-shine-bottom-tab radius v-model=\"activeTwo\">\r\n <we-shine-bottom-tab-item name=\"home\" icon=\"icon-lib-equalratio\">首页</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"mine\" icon=\"icon-lib-helpcenter\">帮助中心</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"customer\" icon=\"icon-lib-qrcode\">二维码</we-shine-bottom-tab-item>\r\n </we-shine-bottom-tab>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n active: 'mine',\r\n firstIcon: require('../../assets/h5/tab-icon-home-normal.png'),\r\n firstActiveIcon: require('../../assets/h5/tab-icon-home.png'),\r\n secondIcon: require('../../assets/h5/tab-icon-mine-normal.png'),\r\n secondActiveIcon: require('../../assets/h5/tab-icon-mine.png'),\r\n thirdIcon: require('../../assets/h5/tab-icon-customer-normal.png'),\r\n thirdActiveIcon: require('../../assets/h5/tab-icon-customer.png')\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 徽标提示\r\n::: demo 设置 dot 属性后,会在图标右上角展示一个小红点;设置 badge 属性后,会在图标右上角展示相应的徽标。\r\n```html\r\n<template>\r\n <we-shine-bottom-tab v-model=\"activeThree\">\r\n <we-shine-bottom-tab-item name=\"home\" icon=\"icon-lib-equalratio\" badge=\"99\">首页</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"mine\" icon=\"icon-lib-helpcenter\" dot>帮助中心</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"customer\" icon=\"icon-lib-qrcode\" badge=\"5\">二维码</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"marketing\" icon=\"icon-lib-location\">定位</we-shine-bottom-tab-item>\r\n </we-shine-bottom-tab>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n active: 'home',\r\n firstIcon: require('../../assets/h5/tab-icon-home-normal.png'),\r\n firstActiveIcon: require('../../assets/h5/tab-icon-home.png'),\r\n secondIcon: require('../../assets/h5/tab-icon-mine-normal.png'),\r\n secondActiveIcon: require('../../assets/h5/tab-icon-mine.png'),\r\n thirdIcon: require('../../assets/h5/tab-icon-customer-normal.png'),\r\n thirdActiveIcon: require('../../assets/h5/tab-icon-customer.png'),\r\n fourIcon: require('../../assets/h5/tab-icon-marketing-normal.png'),\r\n fourActiveIcon: require('../../assets/h5/tab-icon-marketing.png')\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 自定义图标 \r\n::: demo 通过 icon 插槽自定义图标,可以通过 slot-scope 判断标签是否选中。\r\n```html\r\n<template>\r\n <we-shine-bottom-tab v-model=\"activeFour\">\r\n <we-shine-bottom-tab-item name=\"home\" dodge=\"88\">\r\n <span>首页</span>\r\n <template #icon=\"props\">\r\n <img :src=\"props.active ? firstActiveIcon : firstIcon\" />\r\n </template>\r\n </we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"mine\" dot>\r\n <span>我的</span>\r\n <template #icon=\"props\">\r\n <img :src=\"props.active ? secondActiveIcon : secondIcon\" />\r\n </template>\r\n </we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"customer\">\r\n <span>客户</span>\r\n <template #icon=\"props\">\r\n <img :src=\"props.active ? thirdActiveIcon : thirdIcon\" />\r\n </template>\r\n </we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item name=\"marketing\">\r\n <span>营销台</span>\r\n <template #icon=\"props\">\r\n <img :src=\"props.active ? fourActiveIcon : fourIcon\" />\r\n </template>\r\n </we-shine-bottom-tab-item>\r\n </we-shine-bottom-tab>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n active: 'home',\r\n firstIcon: require('../../assets/h5/tab-icon-home-normal.png'),\r\n firstActiveIcon: require('../../assets/h5/tab-icon-home.png'),\r\n secondIcon: require('../../assets/h5/tab-icon-mine-normal.png'),\r\n secondActiveIcon: require('../../assets/h5/tab-icon-mine.png'),\r\n thirdIcon: require('../../assets/h5/tab-icon-customer-normal.png'),\r\n thirdActiveIcon: require('../../assets/h5/tab-icon-customer.png'),\r\n fourIcon: require('../../assets/h5/tab-icon-marketing-normal.png'),\r\n fourActiveIcon: require('../../assets/h5/tab-icon-marketing.png')\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 监听切换事件\r\n:::demo 通过监听 change 事件,可以获取到当前选中的标签。\r\n```html\r\n<template>\r\n <we-shine-bottom-tab v-model='activeFive' @change=\"onChange\">\r\n <we-shine-bottom-tab-item>\r\n <span>首页</span>\r\n <template #icon=\"props\">\r\n <img :src=\"props.active ? firstActiveIcon : firstIcon\" />\r\n </template>\r\n </we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item :icon=\"secondIcon\" :active-icon=\"secondActiveIcon\">\r\n <span>我的</span>\r\n <template #icon=\"props\">\r\n <img :src=\"props.active ? secondActiveIcon : secondIcon\" />\r\n </template>\r\n </we-shine-bottom-tab-item>\r\n </we-shine-bottom-tab>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n active: 'home',\r\n firstIcon: require('../../assets/h5/tab-icon-home-normal.png'),\r\n firstActiveIcon: require('../../assets/h5/tab-icon-home.png'),\r\n secondIcon: require('../../assets/h5/tab-icon-mine-normal.png'),\r\n secondActiveIcon: require('../../assets/h5/tab-icon-mine.png')\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 路由模式 \r\n:::demo 标签栏支持路由模式,用于搭配 vue-router 使用。路由模式下会匹配页面路径和标签的 to 属性,并自动选中对应的标签。\r\n```html\r\n<template>\r\n <we-shine-bottom-tab route>\r\n <we-shine-bottom-tab-item replace to=\"/home\" icon=\"icon-lib-equalratio\">首页</we-shine-bottom-tab-item>\r\n <we-shine-bottom-tab-item replace to=\"/mine\" icon=\"icon-lib-helpcenter\" dot>我的</we-shine-bottom-tab-item>\r\n </we-shine-bottom-tab>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n active: 'home',\r\n firstIcon: require('../../assets/h5/tab-icon-home-normal.png'),\r\n firstActiveIcon: require('../../assets/h5/tab-icon-home.png'),\r\n secondIcon: require('../../assets/h5/tab-icon-mine-normal.png'),\r\n secondActiveIcon: require('../../assets/h5/tab-icon-mine.png')\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 接受参数\r\n\r\n#### WeShineBottomTab Props\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------------------| --------------------------- |----------------------|----------|---------|\r\n| v-model | 当前选中标签的名称或索引值 | _`number/string`_ | - | `0` |\r\n| radius | 是否圆角 | _`boolean`_ | - | `false` |\r\n| route | 是否路由跳转 | _`boolean`_ | - | `false` |\r\n| safe-area-inset-bottom | 是否适配底部安全区域 | _`boolean`_ | - | `false` |\r\n| fixed | 是否固定在底部 | _`boolean`_ | - | `true` |\r\n| zIndex | z-index 层级 | _`number/string`_ | - | `1` |\r\n| placeholder | 是否需要占位 | _`boolean`_ | - | `false` |\r\n| beforeChange | 切换标签前的回调函数,返回 false 可阻止切换,支持返回 Promise | _`(name) => boolean\\|Promise`_ | - | `-` |\r\n\r\n#### WeShineBottomTab Events\r\n| 方法名 | 说明 | 参数 | \r\n|--------| --- | --- |\r\n| change | 切换标签时触发 | active: 当前选中标签的名称或索引值 |\r\n\r\n\r\n#### WeShineBottomTabItem Props\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|--------------| --------------------------- |-------------------|----------|------------|\r\n| name | 标签名称,作为匹配的标识符 | _`number/string`_ | - | `当前标签的索引值` |\r\n| icon | 图标名称 | _`string`_ | - | `-` |\r\n| activeIcon | 选中时的图片链接 | _`string`_ | - | `-` |\r\n| dot | 是否展示小红点 | _`boolean`_ | - | `false` |\r\n| badge | 图标右上角徽标的内容 | _`string/number`_ | - | `-` |\r\n| url | 点击后跳转的链接地址 | _`string`_ | - | `-` |\r\n| to | 点击后跳转的目标路由对象,同 vue-router 的 to 属性 | _`string \\ | object`_ | - | `-` |\r\n| replace | 是否在跳转时替换当前页面历史 | _`boolean`_ | - | `false` |\r\n\r\n#### WeShineBottomTabItem Slots\r\n| 名称 | 说明 | 参数 | \r\n|------| --- | --- |\r\n| icon | 自定义图标 | active: 是否为选中标签 |"
},
{
"name": "ws-cascade",
"category": "移动端组件库",
"content": "## WeShineCascade 级联选择器组件\r\n\r\n级联选择器组件\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineCascade } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineCascade', WeShineCascade);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo WeShineCascade 多选。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"options1.show = true\" >open WeShineCascade 多选</ws-button>\r\n <we-shine-cascade :show.sync=\"options1.show\" v-model=\"options1.selectedIds\" :options=\"mockData\" multiple title=\"级联选择器\" @confirm=\"confirm1\" />\r\n <div class=\"selected-nodes\">\r\n <span class=\"node\" v-for=\"(node, index) of options1.selectedNodes\" :key=\"index\">{{node.name}}</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nconst mock = [\r\n{\r\n id: '1',\r\n name: '湖北省',\r\n children: [\r\n {\r\n id: '12',\r\n name: '武汉市',\r\n children: [\r\n {\r\n id: '121',\r\n name: '洪山区',\r\n children: [\r\n {\r\n id: '1211',\r\n name: '关山'\r\n },\r\n {\r\n id: '1212',\r\n name: '光谷'\r\n }\r\n ]\r\n },\r\n {\r\n id: '122',\r\n name: '武昌区'\r\n }\r\n ]\r\n },\r\n {\r\n id: '13',\r\n name: '荆州市'\r\n },\r\n {\r\n id: '14',\r\n name: '宜昌'\r\n },\r\n {\r\n id: '15',\r\n name: '宜昌1'\r\n },\r\n {\r\n id: '16',\r\n name: '宜昌2'\r\n },\r\n {\r\n id: '17',\r\n name: '宜昌3'\r\n },\r\n {\r\n id: '18',\r\n name: '宜昌4'\r\n },\r\n {\r\n id: '19',\r\n name: '宜昌5'\r\n },\r\n {\r\n id: '111',\r\n name: '宜昌6'\r\n },\r\n {\r\n id: '112',\r\n name: '宜昌7'\r\n }\r\n ]\r\n},\r\n{\r\n id: '2',\r\n name: '湖南省',\r\n children: [\r\n {\r\n id: '21',\r\n name: '长沙市'\r\n }\r\n ]\r\n}\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineCascade',\r\n mockData: mock,\r\n options1: {\r\n show: false,\r\n selectedIds: [],\r\n selectedNodes: []\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm1(payload) {\r\n this.options1.selectedNodes = payload;\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo WeShineCascade 单选。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"options2.show = true\" >open WeShineCascade 单选</ws-button>\r\n <we-shine-cascade :show.sync=\"options2.show\" v-model=\"options2.selectedIds\" :options=\"mockData\" title=\"级联选择器\" @confirm=\"confirm2\" />\r\n <div class=\"selected-nodes\">\r\n <span class=\"node\" v-for=\"(node, index) of options2.selectedNodes\" :key=\"index\">{{node.name}}</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nconst mock = [\r\n{\r\n id: '1',\r\n name: '湖北省',\r\n children: [\r\n {\r\n id: '12',\r\n name: '武汉市',\r\n children: [\r\n {\r\n id: '121',\r\n name: '洪山区',\r\n children: [\r\n {\r\n id: '1211',\r\n name: '关山'\r\n },\r\n {\r\n id: '1212',\r\n name: '光谷'\r\n }\r\n ]\r\n },\r\n {\r\n id: '122',\r\n name: '武昌区'\r\n }\r\n ]\r\n },\r\n {\r\n id: '13',\r\n name: '荆州市'\r\n },\r\n {\r\n id: '14',\r\n name: '宜昌'\r\n },\r\n {\r\n id: '15',\r\n name: '宜昌1'\r\n },\r\n {\r\n id: '16',\r\n name: '宜昌2'\r\n },\r\n {\r\n id: '17',\r\n name: '宜昌3'\r\n },\r\n {\r\n id: '18',\r\n name: '宜昌4'\r\n },\r\n {\r\n id: '19',\r\n name: '宜昌5'\r\n },\r\n {\r\n id: '111',\r\n name: '宜昌6'\r\n },\r\n {\r\n id: '112',\r\n name: '宜昌7'\r\n }\r\n ]\r\n},\r\n{\r\n id: '2',\r\n name: '湖南省',\r\n children: [\r\n {\r\n id: '21',\r\n name: '长沙市'\r\n }\r\n ]\r\n}\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineCascade',\r\n mockData: mock,\r\n options2: {\r\n show: false,\r\n selectedIds: [],\r\n selectedNodes: []\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm2(payload) {\r\n this.options2.selectedNodes = payload;\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo WeShineCascade 节点含说明文字。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"options3.show = true\" >open WeShineCascade 节点含说明文字</ws-button>\r\n <we-shine-cascade :show.sync=\"options3.show\" v-model=\"options3.selectedIds\" :options=\"options3.mockData\" multiple title=\"级联选择器\" @confirm=\"confirm3\" />\r\n <div class=\"selected-nodes\">\r\n <span class=\"node\" v-for=\"(node, index) of options3.selectedNodes\" :key=\"index\">{{node.name}}</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nconst mock = [\r\n{\r\n id: '1',\r\n name: '湖北省',\r\n children: [\r\n {\r\n id: '12',\r\n name: '武汉市',\r\n children: [\r\n {\r\n id: '121',\r\n name: '洪山区',\r\n children: [\r\n {\r\n id: '1211',\r\n name: '关山'\r\n },\r\n {\r\n id: '1212',\r\n name: '光谷'\r\n }\r\n ]\r\n },\r\n {\r\n id: '122',\r\n name: '武昌区'\r\n }\r\n ]\r\n },\r\n {\r\n id: '13',\r\n name: '荆州市'\r\n },\r\n {\r\n id: '14',\r\n name: '宜昌'\r\n },\r\n {\r\n id: '15',\r\n name: '宜昌1'\r\n },\r\n {\r\n id: '16',\r\n name: '宜昌2'\r\n },\r\n {\r\n id: '17',\r\n name: '宜昌3'\r\n },\r\n {\r\n id: '18',\r\n name: '宜昌4'\r\n },\r\n {\r\n id: '19',\r\n name: '宜昌5'\r\n },\r\n {\r\n id: '111',\r\n name: '宜昌6'\r\n },\r\n {\r\n id: '112',\r\n name: '宜昌7'\r\n }\r\n ]\r\n},\r\n{\r\n id: '2',\r\n name: '湖南省',\r\n children: [\r\n {\r\n id: '21',\r\n name: '长沙市'\r\n }\r\n ]\r\n}\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineCascade',\r\n mockData: mock,\r\n options3: {\r\n show: false,\r\n selectedIds: [],\r\n selectedNodes: [],\r\n mockData: mock.map(node => ({ ...node, desc: '这里是说明文字' }))\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm3(payload) {\r\n this.options3.selectedNodes = payload;\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo WeShineCascade 已选 禁用节点。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"options4.show = true\" >open WeShineCascade 已选 禁用节点</ws-button>\r\n <we-shine-cascade\r\n multiple\r\n title=\"级联选择器\"\r\n v-model=\"options4.selectedIds\"\r\n :show.sync=\"options4.show\"\r\n :options=\"options4.mockData\"\r\n :disabledIds=\"options4.disabledIds\"\r\n @confirm=\"confirm4\"\r\n />\r\n <div class=\"selected-nodes\">\r\n <span class=\"node\" v-for=\"(node, index) of options4.selectedNodes\" :key=\"index\">{{node.name}}</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nconst mock = [\r\n{\r\n id: '1',\r\n name: '湖北省',\r\n children: [\r\n {\r\n id: '12',\r\n name: '武汉市',\r\n children: [\r\n {\r\n id: '121',\r\n name: '洪山区',\r\n children: [\r\n {\r\n id: '1211',\r\n name: '关山'\r\n },\r\n {\r\n id: '1212',\r\n name: '光谷'\r\n }\r\n ]\r\n },\r\n {\r\n id: '122',\r\n name: '武昌区'\r\n }\r\n ]\r\n },\r\n {\r\n id: '13',\r\n name: '荆州市'\r\n },\r\n {\r\n id: '14',\r\n name: '宜昌'\r\n },\r\n {\r\n id: '15',\r\n name: '宜昌1'\r\n },\r\n {\r\n id: '16',\r\n name: '宜昌2'\r\n },\r\n {\r\n id: '17',\r\n name: '宜昌3'\r\n },\r\n {\r\n id: '18',\r\n name: '宜昌4'\r\n },\r\n {\r\n id: '19',\r\n name: '宜昌5'\r\n },\r\n {\r\n id: '111',\r\n name: '宜昌6'\r\n },\r\n {\r\n id: '112',\r\n name: '宜昌7'\r\n }\r\n ]\r\n},\r\n{\r\n id: '2',\r\n name: '湖南省',\r\n children: [\r\n {\r\n id: '21',\r\n name: '长沙市'\r\n }\r\n ]\r\n}\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineCascade',\r\n mockData: mock,\r\n options4: {\r\n show: false,\r\n selectedIds: ['10'],\r\n disabledIds: ['10', '20'],\r\n selectedNodes: [{ id: '10', name: '宜昌' }],\r\n mockData: [\r\n {\r\n id: '1',\r\n name: '荆州市',\r\n children: [\r\n {\r\n id: '2',\r\n name: '沙市1'\r\n },\r\n {\r\n id: '3',\r\n name: '沙市2'\r\n },\r\n {\r\n id: '4',\r\n name: '沙市3'\r\n }\r\n ]\r\n },\r\n {\r\n id: '10',\r\n name: '宜昌'\r\n },\r\n {\r\n id: '20',\r\n name: '武汉'\r\n }\r\n ]\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm4(payload) {\r\n this.options4.selectedNodes = payload;\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo WeShineCascade 确认前钩子函数校验。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"options5.show = true\" >open WeShineCascade 确认前钩子函数校验</ws-button>\r\n <we-shine-cascade\r\n multiple\r\n title=\"级联选择器\"\r\n v-model=\"options5.selectedIds\"\r\n :options=\"mockData\"\r\n :show.sync=\"options5.show\"\r\n :beforeConfirm=\"beforeConfirm5\"\r\n />\r\n <div class=\"selected-nodes\">\r\n <span class=\"node\" v-for=\"(node, index) of options5.selectedNodes\" :key=\"index\">{{node.name}}</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nconst mock = [\r\n{\r\n id: '1',\r\n name: '湖北省',\r\n children: [\r\n {\r\n id: '12',\r\n name: '武汉市',\r\n children: [\r\n {\r\n id: '121',\r\n name: '洪山区',\r\n children: [\r\n {\r\n id: '1211',\r\n name: '关山'\r\n },\r\n {\r\n id: '1212',\r\n name: '光谷'\r\n }\r\n ]\r\n },\r\n {\r\n id: '122',\r\n name: '武昌区'\r\n }\r\n ]\r\n },\r\n {\r\n id: '13',\r\n name: '荆州市'\r\n },\r\n {\r\n id: '14',\r\n name: '宜昌'\r\n },\r\n {\r\n id: '15',\r\n name: '宜昌1'\r\n },\r\n {\r\n id: '16',\r\n name: '宜昌2'\r\n },\r\n {\r\n id: '17',\r\n name: '宜昌3'\r\n },\r\n {\r\n id: '18',\r\n name: '宜昌4'\r\n },\r\n {\r\n id: '19',\r\n name: '宜昌5'\r\n },\r\n {\r\n id: '111',\r\n name: '宜昌6'\r\n },\r\n {\r\n id: '112',\r\n name: '宜昌7'\r\n }\r\n ]\r\n},\r\n{\r\n id: '2',\r\n name: '湖南省',\r\n children: [\r\n {\r\n id: '21',\r\n name: '长沙市'\r\n }\r\n ]\r\n}\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineCascade',\r\n mockData: mock,\r\n options5: {\r\n show: false,\r\n selectedIds: [],\r\n selectedNodes: []\r\n }\r\n };\r\n },\r\n methods: {\r\n beforeConfirm5(payload) {\r\n return new Promise((resolve, reject) => {\r\n setTimeout(() => {\r\n if (payload.length > 3) {\r\n this.$confirm && this.$confirm('确认前钩子函数校验, 关闭失败');\r\n resolve(false);\r\n }\r\n this.$toast('关闭成功');\r\n resolve(true);\r\n }, 1000);\r\n });\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------- | --------------------------- | -------------------------------------------------------- | ------ | ------ |\r\n| show | 弹起选择器, 支持.sync修饰符 | boolean | - | - |\r\n| v-model | 选中的节点id集合 | string[] | - | - |\r\n| options | 级联数据项 | CascadeNode[] | - | - |\r\n| multiple | 多选 | boolean | - | false |\r\n| title | 弹窗title | string | - | 请选择 |\r\n| disabledIds | 禁用的节点id集合 | CascadeNode[] | - | - |\r\n| beforeChecked | 勾选节点前钩子 | (data: CascadeNode) => Promise<**boolean**> \\| boolean | - | - |\r\n| beforeConfirm | 确认前钩子 | (data: CascadeNode[]) => Promise<**boolean**> \\| boolean | - | - |\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| --------- | -------------- | ----------------- |\r\n| nodeClick | 点击节点 | data: CascadeNode | - | - |\r\n| confirm | 点击确定时触发 | CascadeNode[] |\r\n\r\n\r\n### CascadeNode Attributes\r\n\r\n| 参数名 | 说明 | 类型 |\r\n| --------- | -------------- | ----------------- |\r\n| id | 节点id(唯一) | string |\r\n| name | 节点名称 | string |\r\n| desc | 节点描述文案 | string |\r\n| checked | 节点是否是勾选状态 | boolean |\r\n| half | 节点是否是半选状态 | boolean |\r\n| disabled | 节点是否是禁止状态 | boolean |\r\n| children | 子节点集合 | CascadeNode |"
},
{
"name": "ws-circle-graph",
"category": "移动端组件库",
"content": "## WeShineCircleGraph 环形图组件\r\n\r\n环形图组件,基于F2二次封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineCircleGraph } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineCircleGraph', WeShineCircleGraph);\r\n```\r\n\r\n### 其他\r\n\r\n:::demo 环形图,7条。\r\n\r\n```html\r\n<template>\r\n <we-shine-circle-graph :params=\"params7\" :default-selected=\"false\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params7: [],\r\n };\r\n },\r\n created() {\r\n this.params7 = this.createSecondChartData(7);\r\n },\r\n methods: {\r\n /**\r\n * 创建横向图,环形图数据\r\n * @param count\r\n */\r\n createSecondChartData(count = 8) {\r\n return Array.from({ length: count }, (val, index) => {\r\n const xName = '分类' + (index + 1);\r\n const count = Math.floor(Math.random() * 100);\r\n return { xName, count };\r\n });\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 环形图,12条。\r\n\r\n```html\r\n<template>\r\n <we-shine-polyline-graph :params=\"params5\" :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params8: []\r\n };\r\n },\r\n created() {\r\n this.params8 = this.createSecondChartData(12);\r\n },\r\n methods: {\r\n /**\r\n * 创建横向图,环形图数据\r\n * @param count\r\n */\r\n createSecondChartData(count = 8) {\r\n return Array.from({ length: count }, (val, index) => {\r\n const xName = '分类' + (index + 1);\r\n const count = Math.floor(Math.random() * 100);\r\n return { xName, count };\r\n });\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------------- | ------------------------------ | ------------------- | ------ | ------ |\r\n| params | 展示的数据 | CircleChartDataType[] | - |\r\n| defaultSelected | 是否默认选中 | boolean | - | true |\r\n| defaultText | 圆环内label默认不选中文字label | string | - | 总数 |\r\n\r\n\r\n### CircleChartDataType Attributes\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|--|--------|-----|-----|\r\n| xName | 分类名称 | string | - | - |\r\n| count | 分类值 | number | - | 0 |"
},
{
"name": "ws-custom-time-panel",
"category": "移动端组件库",
"content": "## WeShineCustomTimePanel 组件\r\n\r\n自定义时间面板\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineCustomTimePanel } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineCustomTimePanel', WeShineCustomTimePanel);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-time-panel\">\r\n <Nav :title=\"title\" />\r\n <div class=\"ws-doc-demo-block\">\r\n <h2 class=\"ws-doc-demo-block__title\">时间选择器</h2>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"visible = true\">时间选择器</ws-button>\r\n </div>\r\n <div class=\"demo-button-row\">开始时间:{{ timeQuantum.startTime || '-' }}</div>\r\n <div class=\"demo-button-row\">结束时间:{{ timeQuantum.endTime || '-' }}</div>\r\n </div>\r\n <we-shine-custom-time-panel :visible=\"visible\" @cancel=\"cancel\" @confirm=\"confirm\"></we-shine-custom-time-panel>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n visible: false,\r\n title: 'WeShineCustomTimePanel',\r\n timeQuantum: {}\r\n };\r\n },\r\n methods: {\r\n cancel() {\r\n this.visible = false;\r\n },\r\n confirm(timeQuantum) {\r\n this.timeQuantum = timeQuantum;\r\n this.cancel();\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------- | ---------------- | ------- | ------ | ------ |\r\n| visible | 是否显示动作面板 | boolean | - | false |\r\n| title | 标题 | string | - | - |\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数及操作 |\r\n| -------- | ------------ | ------------------------------------------------------------------- |\r\n| cancel | 取消操作 | 需将传参置为false |\r\n| confirm | 点击确认操作 | 返回对象{ startTime: '12:00', endTime:'17:45' } 需将传参置为false |\r\n\r\n注: 点击遮罩层默认不会关闭动作面板"
},
{
"name": "ws-date-panel",
"category": "移动端组件库",
"content": "## WeShineDatePanel 组件\r\n\r\n日期面板\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineDatePanel } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineDatePanel', WeShineDatePanel);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"checkIndex(1)\">选择日期</ws-button>\r\n </div>\r\n <we-shine-date-panel :visible=\"options1.visible\" @cancel=\"cancel\" @confirm=\"confirm\"></we-shine-date-panel>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineDatePanel',\r\n tabIndex: -1,\r\n options1: {\r\n visible: false\r\n },\r\n };\r\n },\r\n methods: {\r\n checkIndex(num) {\r\n this.tabIndex = num;\r\n this['options' + this.tabIndex].visible = true;\r\n },\r\n cancel() {\r\n this['options' + this.tabIndex].visible = false;\r\n },\r\n confirm(date) {\r\n this.cancel();\r\n this.$toast(`选中时间${date}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 自定义日期区间。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"checkIndex(2)\">自定义日期区间</ws-button>\r\n </div>\r\n <we-shine-date-panel\r\n :visible=\"options2.visible\"\r\n :min-date=\"options2.minDate\"\r\n :max-date=\"options2.maxDate\"\r\n @cancel=\"cancel\"\r\n @confirm=\"confirm\"\r\n ></we-shine-date-panel>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineDatePanel',\r\n tabIndex: -1,\r\n options2: {\r\n visible: false,\r\n minDate: new Date('2021-1-1'),\r\n maxDate: new Date('2022-4-1')\r\n },\r\n };\r\n },\r\n methods: {\r\n checkIndex(num) {\r\n this.tabIndex = num;\r\n this['options' + this.tabIndex].visible = true;\r\n },\r\n cancel() {\r\n this['options' + this.tabIndex].visible = false;\r\n },\r\n confirm(date) {\r\n this.cancel();\r\n this.$toast(`选中时间${date}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 选择单个日期。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"checkIndex(3)\">选择单个日期</ws-button>\r\n </div>\r\n <we-shine-date-panel\r\n :visible=\"options3.visible\"\r\n :range=\"options3.range\"\r\n :dateType=\"options3.dateType\"\r\n @cancel=\"cancel\"\r\n @confirm=\"confirm\"\r\n ></we-shine-date-panel>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineDatePanel',\r\n tabIndex: -1,\r\n options3: {\r\n visible: false,\r\n range: [],\r\n dateType: 'datehour'\r\n },\r\n };\r\n },\r\n methods: {\r\n checkIndex(num) {\r\n this.tabIndex = num;\r\n this['options' + this.tabIndex].visible = true;\r\n },\r\n cancel() {\r\n this['options' + this.tabIndex].visible = false;\r\n },\r\n confirm(date) {\r\n this.cancel();\r\n this.$toast(`选中时间${date}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | ---------------- | ------------------------------------ | ------ | ----------------------------------------------------------------------------------------- |\r\n| visible | 是否显示动作面板 | Boolean | - | false |\r\n| title | 标题 | String | - | 选择日期 |\r\n| minDate | 最小时间 | Date | - | 一年前 |\r\n| maxDate | 最大时间 | Date | - | 一年后 |\r\n| currentDate | 当前日期 | Date | - | 当前时间 |\r\n| dateType | 时间类型 | String | - | time |\r\n| range | 选择日期范围 | Array<{ name: String, num: Number }> | - | [ { name: '近7天', num: 7 }, { name: '近14天', num: 14 }, { name: '近30天', num: 30 } ] |\r\n| isNeedUnit | 是否需要配置单位 | Boolean | - | true |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数及操作 |\r\n| -------- | ------------ | ---------------------------------------------------------- |\r\n| cancel | 取消操作 | 需将传参置为false |\r\n| confirm | 点击确认操作 | 返回选中时间 Date类型,需自己处理使用 需将传参置为false |\r\n\r\n注: 点击遮罩层默认不会关闭动作面板"
},
{
"name": "ws-date-range-bar",
"category": "移动端组件库",
"content": "## WeShineDateRangeBar 组件\r\n\r\n选择日期范围组件,含固定日期范围(今天/7天/30天)可配置切换团队/我的\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineDateRangeBar } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineDateRangeBar', WeShineDateRangeBar);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n :activeType.sync=\"options1.active\"\r\n isTeam\r\n allowSameDay\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options1: {\r\n active: 'today'\r\n },\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 自定义类型。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n :activeType.sync=\"options2.active\"\r\n isTeam\r\n allowSameDay\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options2: {\r\n active: 'seven'\r\n },\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 默认时间。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n ref=\"WeShineDateRangeBar3\"\r\n :activeType.sync=\"options3.active\"\r\n isTeam\r\n allowSameDay\r\n :minDate=\"options3.minDate\"\r\n :maxDate=\"options3.maxDate\"\r\n :defaultDate=\"options3.defaultDate\"\r\n @open=\"open3\"\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options3: {\r\n active: 'customize',\r\n minDate: new Date('2022/1/1'),\r\n maxDate: new Date('2022/12/31'),\r\n defaultDate: [new Date('2022/1/28'), new Date('2022/2/7')]\r\n },\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n open3() {\r\n (this.$refs.WeShineDateRangeBar3).scrollToDate(new Date('2022/5/15'));\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 滚动到指定日期,5月。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n ref=\"WeShineDateRangeBar1\"\r\n :activeType.sync=\"options7.active\"\r\n isTeam\r\n allowSameDay\r\n :minDate=\"options7.minDate\"\r\n :maxDate=\"options7.maxDate\"\r\n @open=\"open\"\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options7: {\r\n active: 'customize',\r\n minDate: new Date('2022/1/1'),\r\n maxDate: new Date('2022/12/31')\r\n },\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n open() {\r\n (this.$refs.WeShineDateRangeBar1).scrollToDate(new Date('2022/5/15'));\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 重置日期。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button\r\n block\r\n @click=\"reset\"\r\n >重置日期</ws-button>\r\n <WeShineDateRangeBar\r\n ref=\"WeShineDateRangeBar2\"\r\n :activeType.sync=\"options8.active\"\r\n isTeam\r\n allowSameDay\r\n :minDate=\"options8.minDate\"\r\n :maxDate=\"options8.maxDate\"\r\n :defaultDate=\"options8.defaultDate\"\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options8: {\r\n active: 'customize',\r\n minDate: new Date('2022/1/1'),\r\n maxDate: new Date('2022/12/31'),\r\n defaultDate: [new Date('2022/1/28'), new Date('2022/2/7')]\r\n }\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n reset() {\r\n (this.$refs.WeShineDateRangeBar2).reset([new Date('2022/1/1'), new Date('2022/1/2')]);\r\n }\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 自定义角色。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n :activeType.sync=\"options4.active\"\r\n isTeam\r\n allowSameDay\r\n :initRoleId=\"options4.roleId\"\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options4: {\r\n active: 'today',\r\n roleId: 0\r\n },\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 自定义角色名称。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n :activeType.sync=\"options5.active\"\r\n isTeam\r\n allowSameDay\r\n :initRoleTitle=\"options5.initRoleTitle\"\r\n @onRoleChange=\"onRoleChange\"\r\n @rangeChange=\"rangeChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options5: {\r\n active: 'today',\r\n initRoleTitle: '超管'\r\n },\r\n };\r\n },\r\n methods: {\r\n onRoleChange(payload) {\r\n console.log(payload);\r\n },\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 无角色组件。\r\n\r\n```html\r\n<template>\r\n <WeShineDateRangeBar\r\n :activeType.sync=\"options6.active\"\r\n :title=\"options6.title\"\r\n @rangeChange=\"rangeChange\"\r\n @monthShow=\"monthShow\"\r\n @confirm=\"confirm\"\r\n />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n options6: {\r\n active: 'today',\r\n title: '自定义日期组件标题'\r\n },\r\n };\r\n },\r\n methods: {\r\n rangeChange(range) {\r\n console.log('rangeChange', range);\r\n },\r\n monthShow(payload) {\r\n console.log('monthShow', payload);\r\n },\r\n confirm(date) {\r\n console.log('confirm', date);\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ---------- | ----------------------------- | ------- | ---------------------------- | ------ |\r\n| activeType | 当前范围类型, 支持.sync修饰符 | string | today/seven/thirty/customize | - |\r\n| isTeam | 是否显示团队组件 | boolean | - | false |\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| ----------- | ------------ | ------------------------------------------------------------------------------- |\r\n| rangeChange | 选择时间区间 | { beginTime: Date; endTime: Date; name: string; type: string; index?: number } |\r\n\r\n注意:\r\n\r\n- 团队组件配置参照 [WsTeamSwitch](https://fe.wshoto.com/components/#/h5/component/WsTeamSwitch) 组件;\r\n- 日期弹窗组件配置参见 [WsCalendar](https://fe.wshoto.com/components/#/h5/component/WsCalendar) 组件;\r\n- 日期组件`confirm`会触发 `rangeChange` 事件;\r\n- 日期组件的 `defaultDate` 参数只会在 `activeType` 是 `customize` 时生效;"
},
{
"name": "ws-filter-result",
"category": "移动端组件库",
"content": "## WeShineFilterResult 筛选结果组件\r\n\r\n用于列表展示筛选结果\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsShineFilterResult } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsShineFilterResult', WsShineFilterResult);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <div>\r\n <we-shine-filter-result\r\n background=\"#fff\"\r\n :totalCount=\"120\"\r\n left-icon\r\n :filter-list=\"list\"\r\n @leftIconClick=\"handleLeftIconClick\"\r\n @screen=\"screen\"/>\r\n <div style=\"margin-top: .2rem\">\r\n <ws-button @click=\"add\">添加筛选项</ws-button>\r\n <ws-button @click=\"remove\">移除筛选项</ws-button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsSearchWithFilter',\r\n list: []\r\n };\r\n },\r\n methods: {\r\n screen() {\r\n this.$toast('触发筛选事件');\r\n },\r\n handleLeftIconClick() {\r\n this.$toast('触发页面右侧事件');\r\n },\r\n add() {\r\n const arr = ['06.17-06.20', '已选员工(3)', '已选标签(3)', '已选类型(3)'];\r\n this.list.push(arr[this.list.length % 4]);\r\n },\r\n remove() {\r\n this.list.splice(0, 1);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------ | --------------------------------- | -------------- | ------ | --------- |\r\n| background | 背景色 | string | | '#F2F4F8' |\r\n| showTotal | 是否显示筛选区域 | boolean | - | true |\r\n| totalCount | 结果总个数 | number | - | 0 |\r\n| leftIcon | 左侧iconClass名称,默认是tip icon | Boolean\\string | - | |\r\n| filterList | 筛选右侧显示内容 | string[] | - | [] |\r\n| filterNumMax | 筛选右侧最多显示几个详细内容 | number | - | 2 |\r\n\r\n**变更:filterCount 已被废弃,请使用 filterList、leftIcon 添加传boolean值时默认icon为提示图标**\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| ------------------- | ----------------- | -------- |\r\n| screen | 筛选右侧点击事件 | - |\r\n| leftIconClick | leftficon点击事件 | - |"
},
{
"name": "ws-form",
"category": "移动端组件库",
"content": "## WsForm 表单组件\r\n\r\n表单组件\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport {\r\n WeShineForm,\r\n WsFormItem,\r\n WsFormText,\r\n WsFormInput,\r\n WsFormSelect,\r\n WsFormSwitch,\r\n WsFormCheckbox,\r\n WsFormTextarea,\r\n WsFormUpload } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineForm', WeShineForm);\r\nVue.component('WsFormItem', WsFormItem);\r\nVue.component('WsFormText', WsFormText);\r\nVue.component('WsFormInput', WsFormInput);\r\nVue.component('WsFormSelect', WsFormSelect);\r\nVue.component('WsFormSwitch', WsFormSwitch);\r\nVue.component('WsFormCheckbox', WsFormCheckbox);\r\nVue.component('WsFormTextarea', WsFormTextarea);\r\nVue.component('WsFormUpload', WsFormUpload);\r\n```\r\n\r\n### 基本用法 Text\r\n\r\n:::demo 表单校验规则 与 清除验证\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Text\r\n <ws-button size=\"small\" @click=\"resetValidateForm\" style=\"float: right\">清除</ws-button>\r\n <ws-button size=\"small\" @click=\"validateForm\" style=\"float: right;margin-right: .1rem\">验证</ws-button>\r\n </div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-text\r\n direction=\"column\"\r\n title=\"测试\"\r\n :tipClick=\"tipClick\"\r\n msg=\"请输入\"\r\n value=\"值\">\r\n </ws-form-text>\r\n <ws-form-text\r\n direction=\"row\"\r\n title=\"测试\"\r\n :tipClick=\"tipClick\"\r\n :validate=\"validate\"\r\n value=\"值\">\r\n </ws-form-text>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n };\r\n },\r\n methods: {\r\n tipClick() {\r\n this.$confirm && this.$confirm({\r\n title: 'icon说明',\r\n content:\r\n '<p>icon 事件被触发</p>'\r\n });\r\n },\r\n validate(v) {\r\n if (!v) {\r\n return new Error('请选择');\r\n }\r\n if (v > 99) {\r\n return new Error('不能超过99');\r\n }\r\n return true;\r\n },\r\n validateForm() {\r\n (this.$refs.form).validate();\r\n },\r\n resetValidateForm() {\r\n (this.$refs.form).resetValidate();\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 基本用法 Input\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Input</div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-input\r\n title=\"测试\"\r\n hasSuffix\r\n show-word-limit\r\n :validate=\"validate\"\r\n :formatter=\"(v)=>v.replace(/q/g, '9')\"\r\n maxlength=\"100\"\r\n v-model=\"value\">\r\n <div slot=\"suffix\">元</div>\r\n </ws-form-input>\r\n <ws-form-input\r\n required\r\n direction=\"row\"\r\n title=\"测试\"\r\n :validate=\"validate\"\r\n clearable\r\n info=\"提示文字\"\r\n v-model=\"value\">\r\n <div slot=\"suffix\">元</div>\r\n </ws-form-input>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n value: '',\r\n };\r\n },\r\n methods: {\r\n validate(v) {\r\n if (!v) {\r\n return new Error('请选择');\r\n }\r\n if (v > 99) {\r\n return new Error('不能超过99');\r\n }\r\n return true;\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 基本用法 Select\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Select</div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-select\r\n required\r\n direction=\"row\"\r\n title=\"测试\"\r\n v-model=\"select\"\r\n msg=\"请选择\"\r\n @click=\"selectClick\">\r\n <img\r\n src=\"~examples/assets/h5/new.svg\"\r\n class=\"add-circle-border\"\r\n slot=\"titleIcon\"\r\n @click=\"tipClick\"\r\n style=\"margin-left: .1rem;\" />\r\n <div>默认插槽展示: {{select}}</div>\r\n </ws-form-select>\r\n <ws-form-select\r\n required\r\n title=\"测试\"\r\n msg=\"请选择\"\r\n v-model=\"select\"\r\n @click=\"selectClick\">\r\n <div slot=\"prefix\"><van-icon name=\"shopping-cart-o\" /></div>\r\n </ws-form-select>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n select: '',\r\n };\r\n },\r\n methods: {\r\n tipClick() {\r\n this.$confirm && this.$confirm({\r\n title: 'icon说明',\r\n content:\r\n '<p>icon 事件被触发</p>'\r\n });\r\n },\r\n selectClick() {\r\n const v = Math.random() * 10;\r\n this.$toast('随机修改值: ' + v);\r\n this.select = v + '';\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 基本用法 Switch\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Switch</div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-switch\r\n title=\"测试\"\r\n direction=\"row\"\r\n v-model=\"switchValue\">\r\n </ws-form-switch>\r\n <ws-form-switch\r\n v-show=\"switchValue\"\r\n title=\"测试\"\r\n disabled\r\n v-model=\"switchValue\">\r\n <div>禁用状态禁用状态禁用状态禁用状态禁用状态禁用状态</div>\r\n </ws-form-switch>\r\n <ws-form-input\r\n v-show=\"switchValue\"\r\n hasSuffix\r\n show-word-limit\r\n :validate=\"validate01\"\r\n :formatter=\"(v)=>v.replace(/q/g, '9')\"\r\n maxlength=\"100\"\r\n v-model=\"value1\">\r\n <div slot=\"suffix\">元</div>\r\n </ws-form-input>\r\n <ws-form-select\r\n v-show=\"switchValue\"\r\n required\r\n v-model=\"select\"\r\n @click=\"selectClick\">\r\n <div>默认插槽展示: {{select}}</div>\r\n </ws-form-select>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n select: '',\r\n switchValue: false,\r\n value1: '',\r\n };\r\n },\r\n methods: {\r\n tipClick() {\r\n this.$confirm && this.$confirm({\r\n title: 'icon说明',\r\n content:\r\n '<p>icon 事件被触发</p>'\r\n });\r\n },\r\n validate01(v) {\r\n return this.switchValue ? this.validate(v) : true;\r\n },\r\n selectClick() {\r\n const v = Math.random() * 10;\r\n this.$toast('随机修改值: ' + v);\r\n this.select = v + '';\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 基本用法 Checkbox\r\n\r\n:::demo 表单校验规则 与 清除验证\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Checkbox\r\n <ws-button size=\"small\" @click=\"resetValidateCheckbox\" style=\"float: right\">清除</ws-button>\r\n <ws-button size=\"small\" @click=\"validateCheckbox\" style=\"float: right;margin-right: .1rem\">验证</ws-button>\r\n </div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-checkbox\r\n required\r\n direction=\"row\"\r\n title=\"测试单选\"\r\n ref=\"radio\"\r\n msg=\"请选择\"\r\n v-model=\"radio\">\r\n <template slot=\"radio\">\r\n <van-radio name=\"1\">男</van-radio>\r\n <van-radio name=\"2\">女</van-radio>\r\n </template>\r\n </ws-form-checkbox>\r\n <ws-form-checkbox\r\n required\r\n title=\"测试复选\"\r\n ref=\"checkbox\"\r\n msg=\"请选择\"\r\n v-model=\"checkbox\">\r\n <template slot=\"checkbox\">\r\n <van-checkbox name=\"1\">西瓜</van-checkbox>\r\n <van-checkbox name=\"2\">菠萝</van-checkbox>\r\n </template>\r\n </ws-form-checkbox>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n radio: '',\r\n checkbox: [],\r\n };\r\n },\r\n methods: {\r\n validateCheckbox() {\r\n (this.$refs.radio).validateField();\r\n (this.$refs.checkbox).validateField();\r\n },\r\n resetValidateCheckbox() {\r\n (this.$refs.radio).resetValidate();\r\n (this.$refs.checkbox).resetValidate();\r\n },\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 基本用法 Textarea\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Textarea</div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-textarea\r\n required\r\n title=\"测试\"\r\n msg=\"请输入\"\r\n maxlength=\"1000\"\r\n show-word-limit\r\n v-model=\"textarea\">\r\n <div slot=\"footer\">\r\n <ws-button circle type='borderBG'>@成员</ws-button>\r\n </div>\r\n </ws-form-textarea>\r\n <ws-form-textarea\r\n required\r\n scene=\"edit\"\r\n title=\"测试\"\r\n msg=\"请输入\"\r\n maxlength=\"1000\"\r\n show-word-limit\r\n v-model=\"textarea\">\r\n <div slot=\"footer\">\r\n <ws-button circle type='borderBG'>@成员</ws-button>\r\n </div>\r\n </ws-form-textarea>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n textarea: '',\r\n };\r\n },\r\n methods: {\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 基本用法 Upload\r\n\r\n:::demo\r\n\r\n```html\r\n<template>\r\n <we-shine-form class=\"form-demo\" ref=\"form\" :is-passed.sync=\"pass\">\r\n <div class=\"ws-form-title\">基本用法 Upload</div>\r\n <div class=\"ws-form-group\">\r\n <ws-form-upload\r\n title=\"测试上传\"\r\n required\r\n :maxNum=\"4\"\r\n msg=\"请上传\"\r\n v-model=\"upload\">\r\n </ws-form-upload>\r\n <ws-form-upload\r\n :maxNum=\"2\"\r\n title=\"测试上传\"\r\n v-model=\"upload01\">\r\n </ws-form-upload>\r\n </div>\r\n </we-shine-form>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n upload: [],\r\n upload01: []\r\n };\r\n },\r\n methods: {\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### WeShineForm Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------- | ---------------- | ------- | ------ | ------ |\r\n| isPassed | 表单验证是否通过 | Boolean | - | false |\r\n\r\n### WeShineForm Methods\r\n\r\n| 方法名称 | 说明 | 回调参数 |\r\n| ------------- | ---------------------- | -------- |\r\n| validate | 验证整个表单 | - |\r\n| resetValidate | 重置验证错误信息 | - |\r\n| scrollToError | 滑动到验证错误的表单项 | - |\r\n\r\n### 内置 class\r\n\r\n| class名 | 说明 |\r\n| ------------- | -------------------- |\r\n| ws-form-title | 表单组的标题的类名 |\r\n| ws-form-group | 包裹一组表单项的卡片 |\r\n\r\n<!-- ## WsFormItem 组件\r\n\r\n#### 表单项基类,所有的表单项都继承于它。当没有配置好的表单项时,请直接使用它 -->\r\n\r\n### WsFormItem Attributes\r\n\r\n表单项基类,所有的表单项都继承于它。当没有配置好的表单项时,请直接使用它\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------- | ------------------------------------------------------- | -------- | --------------- | -------- |\r\n| direction | 布局方式,分为上下和左右布局(默认上下布局) | string | 'column'、'row' | 'column' |\r\n| title | 标题 | string | - | '' |\r\n| v-model | 绑定表单项的值 | any | - | - |\r\n| required | 是否必填 | boolean | - | false |\r\n| validate | 自定义校验方法,返回Error或true | function | - | - |\r\n| disabled | 禁用状态 | boolean | - | false |\r\n| msg | 校验提示语,存在validate参数时,优先级没有返回的Error高 | boolean | - | false |\r\n| tipClick | 标题上的提示icon | function | - | - |\r\n| info | 校验信息上的提示语,UI规范上不能与tipClick同时出现 | string | - | - |\r\n\r\n### WsFormItem Slots\r\n\r\n| 插槽名 | 说明 |\r\n| ---------- | ------------------------------------------------- |\r\n| default | 默认插槽, 表单内容区域 |\r\n| titleIcon | 标题旁的icon, 优先级比tipClick高,且不会同时存在 |\r\n| titleRight | 标题右侧插槽 |\r\n| info | 与info参数一致 |\r\n\r\n### WsFormItem Methods\r\n\r\n| 方法名称 | 说明 | 回调参数 |\r\n| ------------- | -------------------------- | -------- |\r\n| validateField | 验证单个表单项 | - |\r\n| resetValidate | 重置单个表单项验证错误信息 | - |\r\n\r\n<!-- ## ws-form-text 组件\r\n\r\n#### 单纯的文本展示,一般用于固定的文本展示 -->\r\n\r\n### WsFormText Attributes\r\n\r\n请查看 WsFormItem Attributes\r\n\r\n<!-- ## ws-form-input 组件 -->\r\n\r\n### WsFormInput Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------- | --------------------------------------------------------------------------------------- | -------- | ------ | -------- |\r\n| placeholder | 输入框占位文本 | string | - | 请输入 |\r\n| showWordLimit | 是否显示输入字数统计 | Boolean | - | '' |\r\n| maxlength | 原生属性,最大输入长度 | number | - | - |\r\n| hasSuffix | 是否需要右侧箭头 | boolean | - | true |\r\n| formatter | 格式化函数,将表单项的值转换后进行校验 | function | - | - |\r\n| formatTrigger | 格式化函数触发的时机,可选值为 onBlur | string | - | onChange |\r\n| clearable | 是否启用清除图标,点击清除图标后会清空输入框 | boolean | - | false |\r\n| clearTrigger | 显示清除图标的时机,always 表示输入框不为空时展示, focus 表示输入框聚焦且不为空时展示 | string | - | focus |\r\n**showWordLimit 属性只支持上下布局,且需配置maxlength属性**\r\n\r\n### WsFormInput Slots\r\n\r\n| 插槽名 | 说明 |\r\n| ------ | ------------------------- |\r\n| suffix | 后置插槽, 会覆盖右侧箭头 |\r\n| prefix | 前置插槽 |\r\n\r\n<!-- ## ws-form-select 组件 -->\r\n\r\n### WsFormSelect Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | ---------------- | ------- | ------ | ------ |\r\n| placeholder | 占位文本 | string | - | 请选择 |\r\n| hasSuffix | 是否需要右侧箭头 | boolean | - | true |\r\n\r\n### WsFormSelect Slots\r\n\r\n| 插槽名 | 说明 |\r\n| ------- | --------------------------- |\r\n| default | 默认插槽, 会覆盖选中后的值 |\r\n| suffix | 后置插槽, 会覆盖右侧箭头 |\r\n| prefix | 前置插槽 |\r\n\r\n### WsFormSelect Events\r\n\r\n| 事件名 | 说明 |\r\n| ------ | ------------ |\r\n| click | 点击后的事件 |\r\n\r\n<!-- ## ws-form-switch 组件 -->\r\n\r\n### WsFormSwitch Attributes\r\n\r\n请查看 WsFormItem Attributes\r\n\r\n### WsFormSwitch Slots\r\n\r\n| 插槽名 | 说明 |\r\n| ------- | --------------------------------- |\r\n| default | 默认插槽, 上下布局时可添加副标题 |\r\n\r\n<!-- ## ws-form-checkbox 组件 -->\r\n\r\n### WsFormCheckbox Attributes\r\n\r\n请查看 WsFormItem Attributes\r\n\r\n### WsFormCheckbox Slots\r\n\r\n| 插槽名 | 说明 |\r\n| -------- | ---------------------------- |\r\n| radio | 单选插槽, 包裹 van-radio |\r\n| checkbox | 复选插槽, 包裹 van-checkbox |\r\n\r\n<!-- ## ws-form-textarea 组件 -->\r\n\r\n### WsFormTextarea Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------- | -------------------------------------- | -------- | ------------- | -------- |\r\n| scene | 场景交互形态 | string | 'add'、'edit' | add |\r\n| placeholder | 占位符 | string | - | 请输入 |\r\n| showWordLimit | 是否显示输入字数统计 | Boolean | - | '' |\r\n| maxlength | 原生属性,最大输入长度 | number | - | - |\r\n| formatter | 格式化函数,将表单项的值转换后进行校验 | function | - | - |\r\n| formatTrigger | 格式化函数触发的时机,可选值为 onBlur | string | - | onChange |\r\n**textarea组件只支持上下布局,showWordLimit 属性需要配置 maxlength**\r\n\r\n### WsFormTextarea Slots\r\n\r\n| 插槽名 | 说明 |\r\n| ------- | ----------------------------------------- |\r\n| default | edit场景下的默认插槽, 展示选择的文本插槽 |\r\n| suffix | edit场景下的后置插槽, 会覆盖右侧箭头 |\r\n\r\n<!-- ## ws-form-upload 组件 -->\r\n\r\n### WsFormUpload Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------- | ------------------------ | ------ | ------ | ------ |\r\n| columnNum | 一列数量,会自动计算宽度 | number | - | 4 |\r\n\r\ntips:\r\n\r\n- upload组件根据UI规范只支持上下布局\r\n- upload组件的validate校验已内置一种通用的校验规则,一般不需要定义,特殊场景可覆盖\r\n- 其他上传参数可参考 WeShineUploader 组件"
},
{
"name": "ws-horizontal-pillar-graph",
"category": "移动端组件库",
"content": "## WeShineHorizontalPillarGraph 水平柱形图组件\r\n\r\n水平柱形图组件,基于F2二次封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineHorizontalPillarGraph } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineHorizontalPillarGraph', WeShineHorizontalPillarGraph);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <we-shine-horizontal-pillar-graph :params=\"params8\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n params8: [],\r\n };\r\n },\r\n created() {\r\n this.params8 = this.createSecondChartData(12);\r\n },\r\n methods: {\r\n /**\r\n * 创建横向图,环形图数据\r\n * @param count\r\n */\r\n createSecondChartData(count = 8) {\r\n return Array.from({ length: count }, (val, index) => {\r\n const xName = '分类' + (index + 1);\r\n const count = Math.floor(Math.random() * 100);\r\n return { xName, count };\r\n });\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------ | ---------- | ------------------- | ------ | ------ |\r\n| params | 展示的数据 | BaseChartDataType[] | - |\r\n\r\n### BaseChartDataType Attributes\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|------|--------|-----|-----|\r\n| xName | 分类名称 | string | - | - |\r\n| count | 分类值 | number | - | 0 |"
},
{
"name": "ws-interval-graph",
"category": "移动端组件库",
"content": "<template>\r\n <div>\r\n <Nav :title=\"title\" />\r\n <div class=\"graph-factory\">\r\n <div class=\"graph-section\">\r\n <span class=\"desc\">柱状图, 1组数据,7条 </span>\r\n <we-shine-interval-graph\r\n :params=\"params1\"\r\n :x-formatter=\"formatter\" />\r\n </div>\r\n\r\n <div class=\"graph-section\">\r\n <span class=\"desc\">柱状图, 1组数据,30条,滚动条 </span>\r\n <we-shine-interval-graph\r\n :params=\"params2\"\r\n :x-formatter=\"formatter\" />\r\n </div>\r\n\r\n <div class=\"graph-section\">\r\n <span class=\"desc\">柱状图,1组数据,1条 </span>\r\n <we-shine-interval-graph\r\n :params=\"params3\"\r\n :x-formatter=\"formatter\" />\r\n </div>\r\n\r\n <div class=\"graph-section\">\r\n <span class=\"desc\">柱状图,3组数据,1条 </span>\r\n <we-shine-interval-graph\r\n :params=\"params4\"\r\n :x-formatter=\"formatter\" />\r\n </div>\r\n\r\n <div class=\"graph-section\">\r\n <span class=\"desc\">柱状图,3组数据,7条 </span>\r\n <we-shine-interval-graph\r\n :params=\"params5\"\r\n :x-formatter=\"formatter\" />\r\n </div>\r\n\r\n <div class=\"graph-section\">\r\n <span class=\"desc\">柱状图,3组数据,30条 </span>\r\n <we-shine-interval-graph\r\n :params=\"params6\"\r\n :x-formatter=\"formatter\" />\r\n </div>\r\n </div>\r\n \r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport Vue from 'vue';\r\nimport dayjs from 'dayjs';\r\n\r\nexport default Vue.extend({\r\n name: 'componentsWeShineIntervalGraph',\r\n data() {\r\n return {\r\n title: 'WeShineIntervalGraph',\r\n params1: [],\r\n params2: [],\r\n params3: [],\r\n params4: [],\r\n params5: [],\r\n params6: []\r\n };\r\n },\r\n created() {\r\n this.params1 = this.createChartData(['已分配线索'], 7);\r\n this.params2 = this.createChartData(['已分配线索'], 30);\r\n this.params3 = this.createChartData(['已分配线索'], 1);\r\n this.params4 = this.createChartData(['北京', '上海', '武汉'], 1);\r\n this.params5 = this.createChartData(['北京', '上海', '武汉'], 7);\r\n this.params6 = this.createChartData(['北京', '上海', '武汉'], 30);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n});\r\n</script>\r\n\r\n<style scoped lang='less'>\r\n.graph-factory {\r\n padding: 0.24rem 0;\r\n background: #fff;\r\n\r\n .graph-section {\r\n margin-top: 0.24rem;\r\n\r\n /deep/ .horizontal-pillar-graph {\r\n margin-top: 0.48rem;\r\n }\r\n\r\n /deep/ .progress-line-graph {\r\n margin-top: 1rem;\r\n }\r\n\r\n &.horizontal {\r\n .desc {\r\n margin-bottom: 2rem;\r\n }\r\n }\r\n\r\n .desc {\r\n margin: 0.24rem;\r\n padding: 0.24rem;\r\n }\r\n }\r\n}\r\n.wrap-circle, .wrap-line, .wrap-horizontal {\r\n margin-top: 0.96rem;\r\n}\r\n</style>"
},
{
"name": "ws-multiple-select",
"category": "移动端组件库",
"content": "## 选择类通用组件\r\n\r\n对移动端全局选择类组件交互逻辑统一,并进行组件封装,优化体验,提高业务开发效率。\r\n\r\n:::demo\r\n```html\r\n<template>\r\n <WeShineMultipleSelect\r\n rowKey=\"chatId\" :limit=\"20\" multiple unit=\"个群聊\"\r\n :getData=\"getData\"\r\n :filterList=\"filterList\"\r\n @filterReset=\"filterReset\"\r\n @filterDone=\"filterDone\"\r\n @confirm=\"confirm\">\r\n <WeShineTypeSelectItem slot-scope=\"slotProps\" :item-data=\"slotProps.item\" :status.sync=\"slotProps.item.status\">\r\n <div>{{slotProps.item.chatName || slotProps.item.name || '未命名群聊'}}</div>\r\n <div slot=\"img\" class=\"img-box\"></div>\r\n <div slot=\"desc\">群主· <open-data :openid=\"slotProps.item.owner\" type=\"userName\"/></div>\r\n </WeShineTypeSelectItem>\r\n </WeShineMultipleSelect>\r\n</template>\r\n```\r\n:::\r\n\r\n```js\r\n<script>\r\nimport { WeShineMultipleSelect, WeShineTypeSelectItem } from '@wshoto/h5-base-ui';\r\nexport default Vue.extend({\r\n name: 'componentWeShineMultipleSelect',\r\n components: {\r\n WeShineMultipleSelect,\r\n WeShineTypeSelectItem\r\n },\r\n data() {\r\n return {\r\n searchOption: {\r\n ownerList: [],\r\n ownerDeptIdList: [],\r\n labelType: 1,\r\n tagIdList: []\r\n },\r\n creatPerson: {\r\n userList: [],\r\n depList: []\r\n },\r\n groupTagInfo: {\r\n groupTagList: [], radio: 1\r\n }\r\n };\r\n },\r\n computed: {\r\n // 群主label\r\n creatPersonLabel() {\r\n const userLen = this.creatPerson.userList.length || 0;\r\n const depLen = this.creatPerson.depList.length || 0;\r\n const userText = userLen ? `已选${userLen}名员工` : '';\r\n const deptText = depLen ? `${userText ? ',' : '已选'}${depLen}个部门` : '';\r\n return userText + deptText;\r\n },\r\n // 群标签label\r\n groupTagLabel() {\r\n const { groupTagList } = this.groupTagInfo;\r\n return groupTagList.length ? `已选${groupTagList.length}个标签` : '';\r\n },\r\n filterList() {\r\n return [this.creatPersonLabel, this.groupTagLabel].filter(item => !!item);\r\n }\r\n },\r\n methods: {\r\n getParams(options) {\r\n this.searchOption.ownerList = this.creatPerson.userList.map(user => user.userId) || [];\r\n this.searchOption.ownerDeptIdList = this.creatPerson.depList.map(dep => dep.depId) || [];\r\n this.searchOption.labelType = this.groupTagInfo.radio || 1;\r\n this.searchOption.tagIdList = this.groupTagInfo.groupTagList.map(tag => tag.tagId) || [];\r\n return {\r\n ...this.searchOption,\r\n ...options,\r\n currentIndex: options.pageIndex\r\n };\r\n },\r\n getData(params) {\r\n return request({\r\n url: '/bff/customer/private/pc/chat/list'\r\n }).then(res=> {\r\n return { list: res.records, total: res.total };\r\n });\r\n },\r\n filterReset() {\r\n this.creatPerson = {\r\n userList: [],\r\n depList: []\r\n };\r\n this.groupTagInfo = {\r\n groupTagList: [], radio: 1\r\n };\r\n },\r\n filterDone() {\r\n console.log('filterDone');\r\n },\r\n confirm(list) {\r\n console.log('选择的数据', list);\r\n }\r\n }\r\n});\r\n</script>\r\n```\r\n\r\n### Props\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|------------------|------------------------------------------------------------------------------------------------------------|---------------|-----|-------|\r\n| rowKey | 数据唯一标识KEY | String | - | - |\r\n| defaultSelection | 已选数据,(界面需要展示的数据都需要提供) | Array | - | - |\r\n| limit | 限制可选数量 | Number | - | - |\r\n| multiple | 是否多选 | Boolean | - | false |\r\n| pageSize | 一页加载数据量 | Number | - | 10 |\r\n| unit | 已选数据后的单位文本 | String | - | '个' |\r\n| filterList | 展示已选数据格式 | Array | - | - |\r\n| back | 返回方法 | Function | - | - |\r\n| getData | 提供获取数据源的方法: ({ name, pageIndex, pageSize }) => Promise<{ list: Array, total: number}> | Function | - | - |\r\n\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n|---------|--------------------------------------------|\r\n| default | 主体区域显示格式的默认插槽,用 WeShineTypeSelectItem 占位使用 |\r\n| filter | 筛选器插槽,用 ws-type-filter 子组件 占位使用 |\r\n\r\n### Events\r\n\r\n| 名称 | 说明 |\r\n|-------------|----------------------|\r\n| filterReset | 筛选重置时触发事件,需要清空筛选条件 |\r\n| filterDone | 筛选确定时触发事件 |\r\n| confirm | 确定时触发事件,回调参数为当前已选的数据 |"
},
{
"name": "ws-paragraph-text-box",
"category": "移动端组件库",
"content": "## WeShineParagraphTextBox 组件\r\n\r\n段落文本输入框\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineParagraphTextBox } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineParagraphTextBox', WeShineParagraphTextBox);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-time-panel\">\r\n <Nav :title=\"title\" />\r\n <div class=\"ws-doc-demo-block\">\r\n <h2 class=\"ws-doc-demo-block__title\">段落文本输入框</h2>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"visible = true\">段落文本输入框</ws-button>\r\n </div>\r\n <p class=\"demo-button-row\">段落文本输入框:</p>\r\n <p class=\"demo-text-row\">{{ content }}</p>\r\n </div>\r\n <we-shine-paragraph-text-box :visible=\"visible\" @cancel=\"cancel\" @confirm=\"confirm\">\r\n <div slot=\"action\" class=\"tips fs12\">拒绝本次退款申请。拒绝后,买家无法再次申请退款</div>\r\n </we-shine-paragraph-text-box>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n visible: false,\r\n title: 'WeShineParagraphTextBox',\r\n content: ''\r\n };\r\n },\r\n methods: {\r\n cancel() {\r\n this.visible = false;\r\n },\r\n confirm(content) {\r\n this.content = content;\r\n this.cancel();\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | ---------------------------------- | ------- | ------ | -------- |\r\n| visible | 是否显示动作面板 | boolean | - | false |\r\n| content | 内容 | string | - | - |\r\n| title | 标题 | string | - | - |\r\n| placeholder | 提供可描述输入字段预期值的提示信息 | string | ' | '请输入' |\r\n| maxlength | 输入框最大字数限制 | number | - | 100 |\r\n| isRequired | 是否为必填 | boolean | - | false |\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ------ | -------- |\r\n| action | 输入框上 |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ------------ | ---------------------------------------- |\r\n| cancel | 取消操作 | 需将传参置为false |\r\n| confirm | 点击确认操作 | content:输入的内容; 需将传参置为false |"
},
{
"name": "ws-pillar-graph",
"category": "移动端组件库",
"content": "## WeShinePillarGraph 混合图(柱形+折线图)组件\r\n\r\n混合图组件,基于F2二次封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShinePillarGraph } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShinePillarGraph', WeShinePillarGraph);\r\n```\r\n\r\n### 混合图形\r\n\r\n:::demo 1组数据,7条。\r\n\r\n```html\r\n<template>\r\n <we-shine-pillar-graph\r\n :params=\"params1\"\r\n :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params1: [],\r\n };\r\n },\r\n created() {\r\n this.params1 = this.createChartData(['已分配线索'], 7);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 1组数据,30条,滚动条。\r\n\r\n```html\r\n<template>\r\n <we-shine-pillar-graph\r\n :params=\"params2\"\r\n :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params2: [],\r\n };\r\n },\r\n created() {\r\n this.params2 = this.createChartData(['已分配线索'], 30);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 1组数据,1条。\r\n\r\n```html\r\n<template>\r\n <we-shine-pillar-graph\r\n :params=\"params2\"\r\n :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params3: [],\r\n };\r\n },\r\n created() {\r\n this.params3 = this.createChartData(['已分配线索'], 1);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 3组数据,1条。\r\n\r\n```html\r\n<template>\r\n <we-shine-pillar-graph\r\n :params=\"params4\"\r\n :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params4: [],\r\n };\r\n },\r\n created() {\r\n this.params4 = this.createChartData(['北京', '上海', '武汉'], 1);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 3组数据,7条。\r\n\r\n```html\r\n<template>\r\n <we-shine-pillar-graph\r\n :params=\"params5\"\r\n :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params5: [],\r\n };\r\n },\r\n created() {\r\n this.params5 = this.createChartData(['北京', '上海', '武汉'], 7);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 3组数据,30条。\r\n\r\n```html\r\n<template>\r\n <we-shine-pillar-graph\r\n :params=\"params6\"\r\n :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params6: [],\r\n };\r\n },\r\n created() {\r\n this.params6 = this.createChartData(['北京', '上海', '武汉'], 30);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------------- | ------------------------------- | ------------------------ | ------ | ------ |\r\n| params | 展示的数据 | PillarChartDataType[] | - | |\r\n| tickInterval | x轴刻度间隔展示 | number | - | 1 |\r\n| lineAlias | 折线别名,用于图例和tooltip标注 | string | - | 转化率 |\r\n| leftRate | 左y轴是否展示百分比 | boolean | - | false |\r\n| rightRate | 右y轴是否展示百分比 | boolean | - | false |\r\n| yCount | y轴刻度(含0) | number | - | 6 |\r\n| xFormatter | 格式化x轴名称 | (text: string) => string | - | - |\r\n| labelHorizontal | label是否横向展示 | boolean | - | true |\r\n| point | 是否描绘数据点 | boolean | - | true |\r\n\r\n### PillarChartDataType Attributes\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|-----------|--------|-----|-----|\r\n| xName | 横轴指标 | string | - | - |\r\n| count | 主y轴值 | number | - | 0 |\r\n| type | 分类纬度 | string | - | - |\r\n| lineValue | 折线值(即副y轴) | number | - | 0 |"
},
{
"name": "ws-polyline-graph",
"category": "移动端组件库",
"content": "## WeShinePolylineGraph 折线图组件\r\n\r\n折线图组件,基于F2二次封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShinePolylineGraph } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShinePolylineGraph', WeShinePolylineGraph);\r\n```\r\n\r\n### 面积图\r\n\r\n:::demo 3组数据,7条。\r\n\r\n```html\r\n<template>\r\n <we-shine-polyline-graph :params=\"params5\" :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params5: [],\r\n };\r\n },\r\n created() {\r\n this.params5 = this.createChartData(['北京', '上海', '武汉'], 7);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 1组数据,7条。\r\n\r\n```html\r\n<template>\r\n <we-shine-polyline-graph :params=\"params1\" :x-formatter=\"formatter\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params1: [],\r\n };\r\n },\r\n created() {\r\n this.params1 = this.createChartData(['已分配线索'], 7);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 3组数据,30条, 滚动条。\r\n\r\n```html\r\n<template>\r\n <we-shine-polyline-graph :params=\"params6\" :label-horizontal=\"false\" />\r\n</template>\r\n\r\n<script>\r\n// import dayjs from 'dayjs';\r\n\r\nexport default {\r\n data() {\r\n return {\r\n params6: [],\r\n };\r\n },\r\n created() {\r\n this.params5 = this.createChartData(['北京', '上海', '武汉'], 7);\r\n },\r\n methods: {\r\n /**\r\n * 创建面积图,柱状图数据\r\n * @param types\r\n * @param count\r\n * @param negative\r\n */\r\n createChartData(types, count, negative = false) {\r\n let result = [];\r\n for (let index = 0; index < count; index++) {\r\n const day = dayjs().add(index, 'day').format('YYYY/MM/DD');\r\n const lineValue = Math.floor(Math.random() * 100);\r\n types.forEach(type => {\r\n const count = Math.floor(Math.random() * 100);\r\n result.push({ xName: day, lineValue, type, count: negative ? count * -1 : count });\r\n });\r\n }\r\n return result;\r\n },\r\n formatter(val) {\r\n return dayjs(val).format('MM/DD');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| --------------- | ----------------------------------- | ------------------------ | ------ | ------ |\r\n| params | 展示的数据 | NormalChartDataType[] | - |\r\n| labelHorizontal | label是否横向展示,用于横向超出情况 | boolean | true |\r\n| rate | y轴是否展示百分比 | boolean | - | false |\r\n| yCount | y轴刻度(含0) | number | - | 6 |\r\n| xFormatter | 格式化x轴名称 | (text: string) => string | - | - |\r\n| smooth | 线条是否是平滑曲线 | boolean | - | true |\r\n\r\n### NormalChartDataType Attributes\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|-----------|--------|-----|-----|\r\n| xName | 横轴指标 | string | - | - |\r\n| count | 主y轴值 | number | - | 0 |\r\n| type | 分类纬度 | string | - | - |"
},
{
"name": "ws-progress-line-graph",
"category": "移动端组件库",
"content": "## WeShineProgressLineGraph 横向柱形图带标注组件\r\n\r\n横向柱形图带标注组件,基于F2二次封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineProgressLineGraph } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineProgressLineGraph', WeShineProgressLineGraph);\r\n```\r\n\r\n### 其他\r\n\r\n:::demo 横向柱形图带标注。\r\n\r\n```html\r\n<template>\r\n <we-shine-progress-line-graph />\r\n</template>\r\n<template>\r\n <we-shine-horizontal-pillar-graph :params=\"params\" :note-list=\"noteList\" />\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n params: [\r\n { xName: '首次分配时长', count: 101 },\r\n { xName: '首次跟进时长', count: 100 },\r\n { xName: '转化时长', count: 102 }\r\n ],\r\n noteList: [\r\n '新增线索',\r\n '完成分配',\r\n '首次跟进',\r\n '客户通过'\r\n ]\r\n };\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------|--------|---------------------| ------ | ------ |\r\n| params | 展示的数据 | BaseChartDataType[] | - |\r\n| noteList | 标注文案列表 | string[] | - |\r\n\r\n### BaseChartDataType Attributes\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|------|--------|-----|-----|\r\n| xName | 分类名称 | string | - | - |\r\n| count | 分类值 | number | - | 0 |"
},
{
"name": "ws-time-axis-item",
"category": "移动端组件库",
"content": "## WeShineTimeAxisItem 时间轴组件\r\n\r\n时间轴组件,右侧展示区域开发者自定义\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineTimeAxis, WeShineTimeAxisItem } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WeShineTimeAxis', WeShineTimeAxis);\r\nVue.component('WeShineTimeAxisItem', WeShineTimeAxisItem);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <WeShineTimeAxis>\r\n <WeShineTimeAxisItem v-for=\"(item, index) of data\" :key=\"index\" :time=\"item.time\">\r\n <div class=\"flow-base\">\r\n <p class=\"flow-title fs14\">{{item.title}}</p>\r\n <p class=\"flow-desc fs14\">{{item.desc}}</p>\r\n <p class=\"flow-staff fs12\">{{item.flowStaff}}</p>\r\n </div>\r\n </WeShineTimeAxisItem>\r\n </WeShineTimeAxis>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WeShineTimeAxisItem',\r\n data: [\r\n {\r\n time: '12/06',\r\n title: '线索跟进状态变更',\r\n desc: '由 待处理 变更为 等待验证1',\r\n flowStaff: '由「芳芳」跟进'\r\n },\r\n {\r\n time: '12/06',\r\n title: '线索跟进状态变更',\r\n desc: '由 待处理 变更为 等待验证2',\r\n flowStaff: '由「芳芳」跟进'\r\n },\r\n {\r\n time: '12/06',\r\n title: '线索跟进状态变更',\r\n desc: '由 待处理 变更为 等待验证3',\r\n flowStaff: '由「芳芳」跟进'\r\n }\r\n ]\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------ | ---------- | ------ | ------ | ------ |\r\n| time | 时间轴时间 | string | - | - |\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ---- | ------------------------- | ---- |\r\n| - | WeShineTimeAxisItem的内容 | - |\r\n\r\n### Events\r\n\r\n无"
},
{
"name": "ws-type-select",
"category": "移动端组件库",
"content": "## 类型选择\r\n\r\n用于类型选择组件\r\n\r\n:::demo\r\n```html\r\n<WeShineTypeSelect\r\n title=\"标题\"\r\n v-model=\"styleShow\">\r\n <WeShineTypeSelectItem\r\n title-icon=\"afterTip\"\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>标题</div>\r\n <div slot=\"desc\">描述字段</div>\r\n </WeShineTypeSelectItem>\r\n <WeShineTypeSelectItem\r\n title-icon\r\n type=\"radio\"\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>标题</div>\r\n </WeShineTypeSelectItem>\r\n <WeShineTypeSelectItem\r\n type=\"radio\"\r\n reverse\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>标题</div>\r\n <div slot=\"desc\">描述字段</div>\r\n </WeShineTypeSelectItem>\r\n <WeShineTypeSelectItem\r\n type=\"radio\"\r\n reverse\r\n status=\"half\"\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>标题</div>\r\n <div slot=\"desc\">描述字段</div>\r\n </WeShineTypeSelectItem>\r\n <WeShineTypeSelectItem\r\n type=\"radio\"\r\n reverse\r\n disabled\r\n status=\"checked\"\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>标题</div>\r\n <div slot=\"desc\">描述字段</div>\r\n </WeShineTypeSelectItem>\r\n <WeShineTypeSelectItem\r\n type=\"radio\"\r\n reverse\r\n disabled\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>标题</div>\r\n <div slot=\"img\" class=\"img-box\"></div>\r\n <div slot=\"desc\">描述字段</div>\r\n </WeShineTypeSelectItem>\r\n </WeShineTypeSelect>\r\n\r\n <WeShineTypeSelect\r\n title=\"标题\"\r\n reverse\r\n type=\"customTitle\"\r\n left-btn=\"取消\"\r\n right-btn=\"确定\"\r\n item-type=\"radio\"\r\n @clickRight=\"clickRight\"\r\n @clickLeft=\"clickLeft\"\r\n :get-list=\"getList\"\r\n v-model=\"radioShow\">\r\n <WeShineTypeSelectItem\r\n slot-scope=\"slotProps\"\r\n title-icon=\"afterTip\"\r\n :item-data=\"slotProps.item\"\r\n :status.sync=\"slotProps.item.status\"\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>{{slotProps.item.name}}</div>\r\n <div slot=\"desc\">描述字段: {{slotProps.index}}</div>\r\n </WeShineTypeSelectItem>\r\n </WeShineTypeSelect>\r\n\r\n <WeShineTypeSelect\r\n title=\"标题\"\r\n reverse\r\n type=\"customTitle\"\r\n left-btn=\"取消\"\r\n right-btn=\"确定\"\r\n item-type=\"select\"\r\n has-clear\r\n @clickRight=\"submit\"\r\n @clickLeft=\"clickLeft\"\r\n :get-list=\"getList\"\r\n v-model=\"selectShow\">\r\n <WeShineTypeSelectItem\r\n slot-scope=\"slotProps\"\r\n :item-data=\"slotProps.item\"\r\n :status.sync=\"slotProps.item.status\"\r\n @itemClick=\"itemClick\"\r\n @iconClick=\"iconClick\">\r\n <div>{{slotProps.item.name}}</div>\r\n <div slot=\"img\" class=\"img-box\"></div>\r\n <div slot=\"desc\">描述字段: {{slotProps.index}}</div>\r\n </WeShineTypeSelectItem>\r\n </WeShineTypeSelect>\r\n```\r\n:::\r\n\r\n```jsx\r\nimport { WeShineTypeSelect, WeShineTypeSelectItem } from '@wshoto/h5-base-ui';\r\n```\r\n\r\n\r\n### Props\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|----------|-----------------------------|----------|--------------------------|---------|\r\n| mode | 模式分为:底部弹出层选择、跳转页面选择 | string | popup、page | popup |\r\n| v-model | 显示/隐藏 | boolean | - | false |\r\n| itemType | 是selectItem组件的type属性,会透传下去 | string | 'arrow'、'radio' 、'select' | 'arrow' |\r\n| reverse | 左右是否转换位置 | boolean | - | false |\r\n| getList | 需要加载数据能力传此属性,作用与ws-list组件一致 | Function | - | - |\r\n| hasClear | 提供底部清空按钮能力 | boolean | - | false |\r\n\r\n:::tip\r\npopup模式下,底部选择基于ws-custom-panel组件封装,会透传此组件的props\r\n:::\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- |----------|--------------------|\r\n| clickLeft | 标题左侧点击事件 | - |\r\n| clickRight | 标题右侧点击事件 | 选中的Array<传入的数据或索引> |\r\n\r\n### 调用\r\n\r\n| 方法名称 | 说明 | 回调参数 |\r\n|-------------|-----------|-----------------|\r\n| getSelected | 获取当前勾选的数组 | Array<传入的数据或索引> |\r\n | reset | 还原勾选状态 | - |\r\n | confirm | 确定勾选状态 | - |\r\n\r\n\r\n## WeShineTypeSelectItem 组件\r\n\r\n:::tip\r\nWeShineTypeSelectItem 可单独使用\r\n:::\r\n\r\n\r\n### Props\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|---------|-----------------------------------------------|----------------|---------------------------|----------|\r\n| type | 类型,与WsShineTypeSelect搭配使用时,可不传,会取itemType | string | 'arrow'、'radio' 、'select' | 'arrow' |\r\n| disabled | 是否禁用 | boolean | - | false |\r\n| status | 当前状态 | string | 'checked'、'normal'、'half' | 'normal' |\r\n| titleIcon | 标题上的iconclass,为true时默认为new icon | boolean/string | - | false |\r\n| itemData | 组件上的数据源,与WsShineTypeSelect搭配使用时用于状态还原和获取选中的数据 | - | - | - |\r\n| reverse | 左右是否转换位置,与WsShineTypeSelect搭配使用时,可不传,会取reverse | boolean | - | false |\r\n\r\n### slots\r\n| 参数名 | 说明 |\r\n|-----|------------|\r\n| default | 默认插槽, 标题内容 |\r\n| desc | 描述插槽, 描述内容 |\r\n| img | 图片插槽, 图片内容 |\r\n\r\n### Events\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- |--------------|------------------|\r\n| iconClick | 标题上的icon点击事件 | 当前的itemData |\r\n| rightClick | 右侧图标点击事件 | 当前的itemData |\r\n| itemClick | 点击事件 | 当前的itemData |"
},
{
"name": "ws-button-filter",
"category": "移动端组件库",
"content": "## WsButtonFilter 组件\r\n\r\n以多个按钮组合的方式出现,常用于二级导航栏。\r\n\r\n居于基础组件按钮 `type: borderBG | info`, `size: small` 扩展\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsButtonFilter } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsButtonFilter', WsButtonFilter);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 基础的按钮组合用法。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options1\" :index.sync=\"index1\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index1: 0,\r\n options1: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 }\r\n ],\r\n }\r\n },\r\n methods: {\r\n mainHandleClick() {\r\n this.$toast('我是主按钮');\r\n setTimeout(() => {\r\n this.loading = !this.loading;\r\n }, 2000);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 通过名称匹配。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options2\" :index.sync=\"index2\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index2: 2,\r\n options2: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 }\r\n ],\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 标签栏滚动。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options3\" :index.sync=\"index3\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index3: 0,\r\n options3: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 },\r\n { text: '标签5', value: 4 },\r\n { text: '标签6', value: 5 },\r\n { text: '标签7', value: 6 },\r\n { text: '标签8', value: 7 }\r\n ],\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 是否省略过长的标题文字。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options4\" :index.sync=\"index4\" ellipsis />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index4: 0,\r\n options4: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签标签标签标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 }\r\n ],\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 禁用标签。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options5\" :index.sync=\"index5\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index5: 0,\r\n options5: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1, disabled: true },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 }\r\n ],\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo `click` 事件。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options6\" :index.sync=\"index6\" @click=\"handleClick\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index6: 0,\r\n options6: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 }\r\n ],\r\n }\r\n },\r\n methods: {\r\n handleClick(value) {\r\n const { options6 } = this;\r\n this.$toast(`click on ${options6[value].text}`);\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo `change` 事件。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options7\" :index.sync=\"index7\" @change=\"handleChange\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index7: 0,\r\n options7: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 }\r\n ],\r\n }\r\n },\r\n methods: {\r\n handleChange(value) {\r\n const { options7 } = this;\r\n this.$toast(`change on ${options7[value].text}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 标签栏换行(单选+取消选中)。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options8\" :index.sync=\"index8\" wrap />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index8: 0,\r\n options8: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 },\r\n { text: '标签5', value: 4 },\r\n { text: '标签6', value: 5 },\r\n { text: '标签7', value: 6 },\r\n { text: '标签8', value: 7 }\r\n ],\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 标签栏换行(多选+取消选中)。\r\n```html\r\n<template>\r\n <ws-button-filter :option=\"options9\" :index.sync=\"index9\" wrap />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n index9: [0, 1, 2, 3],\r\n options9: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 },\r\n { text: '标签5', value: 4 },\r\n { text: '标签6', value: 5 },\r\n { text: '标签7', value: 6 },\r\n { text: '标签8', value: 7 }\r\n ]\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 |\r\n| ---------- | ---------------------------------------- | --------------------------- | --------- |\r\n| index | 当前选中项对应的 value(支持.sync 更新) | number \\| string \\| Array | - |\r\n| background | 背景色 | string | #F2F4F8 |\r\n| option | 选项数组 | Option[] | [] |\r\n| ellipsis | 是否省略过长的标题文字 | boolean | false |\r\n| wrap | 配置换行(三个为一行, 可取消选中) | boolean | false |\r\n| dot | 红点配置 | Array<Option['value']> | [] |\r\n\r\n#### Option 数据结构\r\n\r\n`Option` 属性是一个由对象构成的数组,数组中的每个对象配置一列,对象可以包含以下值:\r\n\r\n| 键名 | 说明 | 类型 |\r\n| -------- | ---------------------- | ------------------ |\r\n| text | 显示文本 | string |\r\n| disabled | 是否为禁用状态 | boolean |\r\n| value | 当前选中项对应的 value | number \\| string |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ---------------- | ------------------------- |\r\n| click | 导航栏点击触发 | value: number \\| string |\r\n| change | 导航栏改变时触发 | value: number \\| string |"
},
{
"name": "ws-calendar",
"category": "移动端组件库",
"content": "## WsCalendar 日期选择器组件\r\n\r\n日期区间选择器,基于vant calendar进行二次封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsCalendar } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsCalendar', WsCalendar);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button\r\n block\r\n @click=\"options1.show = true\"\r\n >open WsCalendar</ws-button>\r\n <ws-calendar\r\n v-model=\"options1.show\"\r\n @confirm=\"confirm\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCalendar',\r\n options1: {\r\n show: false\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm(date) {\r\n const [beginTime, endTime] = date;\r\n this.$toast(`开始时间:${beginTime}, 结束时间:${endTime}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 自定义日期区间。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button\r\n block\r\n @click=\"options2.show = true\"\r\n >自定义日期区间</ws-button>\r\n <ws-calendar\r\n v-model=\"options2.show\"\r\n :min-date=\"options2.minDate\"\r\n :max-date=\"options2.maxDate\"\r\n @confirm=\"confirm\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCalendar',\r\n options2: {\r\n show: false,\r\n minDate: new Date('2021-4-1'),\r\n maxDate: new Date('2023-5-1')\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm(date) {\r\n const [beginTime, endTime] = date;\r\n this.$toast(`开始时间:${beginTime}, 结束时间:${endTime}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 自定义区间最大范围。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button\r\n block\r\n @click=\"options3.show = true\"\r\n >自定义区间最大范围</ws-button>\r\n <ws-calendar\r\n v-model=\"options3.show\"\r\n :max-range=\"options3.maxRange\"\r\n :range-prompt=\"options3.rangePrompt\"\r\n @confirm=\"confirm\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCalendar',\r\n options3: {\r\n show: false,\r\n maxRange: 3,\r\n rangePrompt: '选择天数不能超过 3 天'\r\n },\r\n };\r\n },\r\n methods: {\r\n confirm(date) {\r\n const [beginTime, endTime] = date;\r\n this.$toast(`开始时间:${beginTime}, 结束时间:${endTime}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 默认日期。\r\n\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button\r\n block\r\n @click=\"options4.show = true\"\r\n >默认日期</ws-button>\r\n <ws-calendar\r\n v-model=\"options4.show\"\r\n :min-date=\"options4.minDate\"\r\n :max-date=\"options4.maxDate\"\r\n :default-date=\"options4.defaultDate\"\r\n @confirm=\"confirm\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCalendar',\r\n options4: {\r\n show: false,\r\n minDate: new Date('2021-5-1'),\r\n maxDate: new Date('2023-5-1'),\r\n defaultDate: [new Date('2021-9-1'), new Date('2022-4-1')]\r\n }\r\n };\r\n },\r\n methods: {\r\n confirm(date) {\r\n const [beginTime, endTime] = date;\r\n this.$toast(`开始时间:${beginTime}, 结束时间:${endTime}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------------- | -------------------------------------- | ------------- | ------ | ---------------------- |\r\n| v-model | 是否显示日历弹窗 | boolean | - | false | false |\r\n| title | 日历标题 | string | - | 日期选择 |\r\n| min-date | 可选择的最小日期 | Date | - | 当前日期 |\r\n| max-date | 可选择的最大日期 | Date | - | 当前日期的六个月后 |\r\n| max-range | 日期区间最多可选天数 | number/string | - | 无限制 |\r\n| range-prompt | 范围选择超过最多可选天数时的提示文案 | string | - | 选择天数不能超过 xx 天 |\r\n| default-date | 默认选中的日期 | Date[] | - | [null, null] |\r\n| show-mark | 是否显示月份背景水印 | boolean | - | false |\r\n| readonly | 是否为只读状态,只读状态下不能选择日期 | boolean | - | false |\r\n| poppable | 是否以弹层的形式展示日历 | boolean | - | true |\r\n| show-title | 是否展示日历标题 | boolean | - | true |\r\n| allow-same-day | 是否允许日期范围的起止时间为同一天 | boolean | - | false |\r\n| lazy-render | 是否只渲染可视区域的内容 | - | true |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| ---------- | ---------------------------- | ----------------------------- |\r\n| select | 点击并选中任意日期时触发 | date: Array<Date \\| null> |\r\n| confirm | 点击确认按钮后触发 | date: Date[] |\r\n| open | 打开弹出层时触发 | - |\r\n| close | 关闭弹出层时触发 | - |\r\n| opened | 打开弹出层且动画结束后触发 | - |\r\n| closed | 关闭弹出层且动画结束后触发 | - |\r\n| month-show | 当某个月份进入可视区域时触发 | { date: Date, title: string } |\r\n\r\n### Methods\r\n\r\n通过 ref 可以获取到 Calendar 实例并调用实例方法。\r\n| 事件名称 | 说明 | 回调参数 |\r\n| ------------ | ---------------------------------------------------- | ------------ |\r\n| reset | 将选中的日期重置到指定日期,未传参时会重置到默认日期 | date: Date[] |\r\n| scrollToDate | 滚动到某个日期 | date: Date |"
},
{
"name": "ws-card",
"category": "移动端组件库",
"content": "## WsCard 卡片组件\r\n\r\n卡片组件,用于提供基础卡片样式\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsCard } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsCard', WsCard);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <ws-card background=\"#fff\"> 内容 </ws-card>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCard'\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 配置背景色。\r\n\r\n```html\r\n<template>\r\n <ws-card background=\"red\"> 我是卡片-背景红色 </ws-card>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCard'\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ---------- | ------ | ------ | ------ | ------ |\r\n| background | 背景色 | string | | '#fff' |\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ------- | ------------------ |\r\n| default | 自定义卡片内容区域 |\r\n\r\n### Events\r\n\r\n无"
},
{
"name": "ws-cell",
"category": "移动端组件库",
"content": "## WsCell 组件\r\n\r\n列表中的单个展示项\r\n\r\n居于 vant Cell 单元格组件进行封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsCell } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsCell', WsCell);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 基础的组件用法。\r\n```html\r\n<template>\r\n <ws-cell title='WsCell 单元格基础使用' right-content='内容' @click='$toast(\"toast 提示\")' />\r\n</template>\r\n```\r\n:::\r\n\r\n:::demo 类型: `select`。\r\n```html\r\n<template>\r\n <ws-cell\r\n required\r\n type='select'\r\n title='我是select类型'\r\n sub-title='点击可以切换状态,不信你试试'\r\n :right-content=\"pitchOnSelect ? '选中了,颜色变了' : '选我选我'\"\r\n :pitch-on='pitchOnSelect'\r\n @click='show = true'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCell',\r\n show: false,\r\n pitchOnSelect: false,\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型: `radio`。\r\n```html\r\n<template>\r\n <ws-cell\r\n required\r\n type='radio'\r\n title='我是radio类型'\r\n sub-title='点击可以切换状态,不信你试试'\r\n :pitch-on='pitchOnRadio'\r\n @click='handleRadioChange'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCell',\r\n pitchOnRadio: false\r\n };\r\n },\r\n methods: {\r\n handleRadioChange() {\r\n this.pitchOnRadio = !this.pitchOnRadio;\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 类型: `switch`。\r\n```html\r\n<template>\r\n <ws-cell\r\n required\r\n type='switch'\r\n title='我是switch类型'\r\n sub-title='点击可以切换状态,不信你试试'\r\n :pitch-on='pitchOnSwitch'\r\n @click='handleSwitchChange'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCell',\r\n pitchOnSwitch: false\r\n };\r\n },\r\n methods: {\r\n handleSwitchChange() {\r\n this.pitchOnSwitch = !this.pitchOnSwitch;\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 |\r\n| ------------ | ----------------------------------------------------- | --------- | ----------- |\r\n| type | 类型,可选值为 default、select、radio、switch | string | default |\r\n| title | 主标题 | string | 确定 |\r\n| subTitle | 副标题 | string | 取消 |\r\n| rightContent | 右侧内容,在 type==='select' 时生效 | string | 取消 |\r\n| pitchOn | 是否选中,改变值对于类型视图发生变化 | boolean | false |\r\n| required | 是否必填 | boolean | false |\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ---------------- | -------------- |\r\n| click | 点击单元格时触发 | event: Event |\r\n\r\n注意事项:\r\n\r\n- `pitchOn` 是异步控制的,改变值会对类型视图产生影响。\r\n- `rightContent` 只在 `type==='select'` 时生效。"
},
{
"name": "ws-check-box",
"category": "移动端组件库",
"content": "## WsCheckBox 组件\r\n\r\n复选框组件\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsCheckBox } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsCheckBox', WsCheckBox);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 标签类型。\r\n\r\n```html\r\n<template>\r\n <ws-check-box :initChecked.sync=\"checked\">{{ checked ? '选中' : '不选中' }}</ws-check-box>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsCheckBox',\r\n checked: false\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 |\r\n| ---------------- | -------------------------------------- | --------- | ------- |\r\n| initChecked.sync | 是否选中,采用.sync 进行双向数据流绑定 | boolean | false |\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ------- | ---------- |\r\n| default | 自定义文本 |\r\n\r\n### Events\r\n\r\n无"
},
{
"name": "ws-default-page",
"category": "移动端组件库",
"content": "## WsDefaultPage 缺省页面组件\r\n\r\n空状态时的占位提示\r\n\r\n居于 vant Empty 空状态 进行封装\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsDefaultPage } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsDefaultPage', WsDefaultPage);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 配置主标题。\r\n\r\n```html\r\n<template>\r\n <ws-default-page title='主标题' @click='handleListClick' />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsDefaultPage'\r\n };\r\n },\r\n methods: {\r\n handleListClick() {\r\n this.$toast('按钮事件提示');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 配置主标题+副标题+按钮。\r\n\r\n```html\r\n<template>\r\n <ws-default-page\r\n title='主标题'\r\n subTitle='副标题'\r\n buttonText='按钮文案'\r\n @click='handleListClick'\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsDefaultPage'\r\n };\r\n },\r\n methods: {\r\n handleListClick() {\r\n this.$toast('按钮事件提示');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 属性名 | 说明 | 类型 | 默认值 |\r\n| ----------- | ---------------------- | ------ | ------------ |\r\n| background | 背景色 | string | #f2f4f8 |\r\n| image | 项目 SVG 类名 | string | default-icon |\r\n| title | 主标题 | string | - |\r\n| subTitle | 副标题 | string | - |\r\n| buttonText | 按钮文案,留空则不显示 | string | - |\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ---------------- | ------------ |\r\n| click | 按钮点击触发事件 | Event |"
},
{
"name": "ws-dropdown-menu-filter",
"category": "移动端组件库",
"content": "## WsDropdownMenuFilter 下拉菜单过滤器组件\r\n\r\n用于下拉条件筛选\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsDropdownMenuFilter, WsDropdownMenuItem } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsDropdownMenuFilter', WsDropdownMenuFilter);\r\nVue.component('WsDropdownMenuItem', WsDropdownMenuItem);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 分类1。\r\n\r\n```html\r\n<template>\r\n <ws-dropdown-menu-item v-model=\"value1\" title=\"分类1\" :options=\"opt1\" :customKey=\"customKey1\" @change=\"change1\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsDropdownMenuFilter',\r\n value1: '',\r\n opt1: [\r\n { text: 21323, value1: 222 },\r\n { text: '2222222222222222222222222222222222212321312321', value1: 2 },\r\n { text: 123, value1: 22 }\r\n ],\r\n customKey1: {\r\n value1: 'value'\r\n },\r\n };\r\n },\r\n methods: {\r\n change1(value) {\r\n console.log(value);\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 分类2。\r\n\r\n```html\r\n<template>\r\n <ws-dropdown-menu-item\r\n v-model=\"value2\"\r\n title=\"分类2\"\r\n :options=\"opt2\"\r\n :customKey=\"customKey2\"\r\n isTreeSelect\r\n automaticAll\r\n @change=\"change2\"\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsDropdownMenuFilter',\r\n value2: '',\r\n opt2: [\r\n {\r\n text: '分类1分类1分类1分类1分类1分类1分类1分类1分类1分类1',\r\n value1: '1',\r\n child: [\r\n { text: '分类1-1211111111111111111111111111111111111111111', value1: '2' },\r\n { text: '分类1-2', value1: '3' },\r\n { text: '分类1-3', value1: '4' },\r\n { text: '分类1-3', value1: '41' },\r\n { text: '分类1-3', value1: '42' },\r\n { text: '分类1-3', value1: '43' },\r\n { text: '分类1-3', value1: '44' },\r\n { text: '分类1-3', value1: '45' }\r\n ]\r\n }\r\n ],\r\n customKey2: {\r\n value1: 'id',\r\n child: 'children'\r\n },\r\n };\r\n },\r\n methods: {\r\n change2(value) {\r\n console.log(value);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n与 van DropdownMenu 属性一致,只是 active-color 颜色定制为#2b60dd\r\n\r\n### ws-dropdown-menu-item\r\n\r\n| 属性名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------ | ------------------------------------------------- | ------------- | ------ | ------ |\r\n| value | 当前选中项对应的 value,可以通过 v-model 双向绑定 | string/number | | |\r\n| isTreeSelect | 是否为 treeSelect 模式 | boolean | false | |\r\n| options | 选项数组 | array | [] | |\r\n| title | 菜单项默认标题 | string | | |\r\n| title-class | 标题额外类名 | string | | |\r\n| customKey | 自定义配置字段,详细见下方注意事项 | Object | | |\r\n| customSetAll | 自定义生成全部,仅 treeSelect 模式生效项 | Boolean | | |\r\n\r\n### ws-dropdown-menu-item Events\r\n\r\n| 事件名 | 说明 | 回调参数 |\r\n| ------ | ---------------- | ------------------------------- |\r\n| change | 改变选择项时触发 | 选中的值(option 设置的 value) |\r\n\r\n### ws-dropdown-menu-item Slots\r\n\r\n| 名称 | 说明 |\r\n| ------- | -------- |\r\n| default | 菜单内容 |\r\n\r\n#### 自定义设置全部数据结构\r\n\r\n```js\r\nallJson: {\r\n text: '全部',\r\n id: '-1'\r\n}\r\n```\r\n\r\n#### 注意事项\r\n\r\n- customKey,组件正常运行需要有一些必要字段,而传入的 options 又不能满足,这时候需要使用 customKey 指定配置 如“把 treeSelect 模式时必须要有 id 字段 而传入的 options 只有 ID 这个时候需要 设置:customKey=\"{ ID: 'id' }\"”\r\n\r\n#### 注意\r\n\r\n- ws-dropdown-menu-filter 需要与 ws-dropdown-menu-item 搭配使用\r\n- 业务传入的 options 一维数组组件展现形式为下拉菜单 多维数组组件展示形式为 treeSelect\r\n- 业务方使用组件需注意 下拉菜单展示形式要确保有 text、value 字段;TreeSelect 要确保有 text、id、children。传入的 options 不能满足的需要使用自定义指定设置相关字段"
},
{
"name": "ws-dynamic-component",
"category": "移动端组件库",
"content": "## WsDynamicComponent - 微盛动态组件\r\n\r\n因前端组件化改造,页面模块可能会引用端上公共的模块,比如 H5端客户详情客户信息tab组件。\r\n或者 定开项目需要在标品指定页面填充内容(静态插槽)。\r\n\r\n可通过此组件,跨页面复用组件\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------|------|--------|-----|-----|\r\n| component | 组件标识 | string | 必传 | 无 |\r\n\r\n### 使用示例\r\n\r\n组件标识需要全局惟一,需由 '模块名称-页面名称[-插槽名称]' 拼接而成,如 'customer-detail-drawer'、'\r\ncustomer-detail-drawer-top'\r\n\r\n标品提供的组件会在main.ts中注册, 注意以异步模块的方式导入 () => import\r\n\r\n```html\r\n<!-- 简单示例 -->\r\n<ws-dynamic-component component=\"customer-detail-info-tab\"></ws-dynamic-component>\r\n\r\n```\r\n### PC端已支持组件\r\n| 组件名称 | 组件说明 |\r\n|------|--|\r\n| customer-detail-info-tab | 客户画像-客户信息tab组件 |\r\n\r\n#### 开发者\r\n\r\n老田"
},
{
"name": "ws-ellipses-text",
"category": "移动端组件库",
"content": "## WsEllipsesText 组件\r\n文本溢出收起展开组件。\r\n当文本过多溢出省略号,并显示展示收起按钮。\r\n\r\n### 引入\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsEllipsesText } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsEllipsesText', WsEllipsesText);\r\n```\r\n### 基本用法\r\n\r\n:::demo 基础的组件用法\r\n\r\n```html\r\n<template>\r\n <WsEllipsesText\r\n :content=\"content\"\r\n :row=\"row\"\r\n :newTabOpen=\"newTabOpen\" />\r\n</template>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n content: '',\r\n row: 5,\r\n newTabOpen: false,\r\n };\r\n }\r\n }\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 属性名 | 类型 | 说明 | 可选值 | 默认值 | 备注 |\r\n|:-----------|---------|:--------------------|:----|:------|:----|\r\n| content | String | 文本内容 | —— | —— | —— |\r\n| row | Number | 最多展示的行数 | —— | 5 | —— |\r\n| newTabOpen | Boolean | 文本内容中链接打开方式是否是新页面打开 | —— | false | —— |"
},
{
"name": "ws-input-download-h5",
"category": "移动端组件库",
"content": "## WsInputDownload 名称输入组件\r\n\r\n基于 [van-field](https://youzan.github.io/vant/v2/#/zh-CN/field) 开发,用于可能有输入相关名称,并可在后续用于下载、导出的场景下使用\r\n\r\n:::tip\r\n主要作用:\r\n过滤掉特殊字符,如:`.` 、 空格、斜杠 等等。\r\n:::\r\n\r\n:::tip\r\n#### 开发规范\r\n在用于有输入相关名称,并在后续用于下载、导出的场景中作为文件名时,必须使用此组件。\r\n(比如:创建活码时,活码名称表单项)\r\n:::\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsInputDownload } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsInputDownload', WsInputDownload);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <ws-input-download v-model=\"fileName\" ref=\"input\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n fileName: ''\r\n };\r\n },\r\n mounted() {\r\n this.$nextTick(() => {\r\n (this.$refs.input).focus();\r\n });\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n使用及 **API** 与 [van-field](https://youzan.github.io/vant/v2/#/zh-CN/field#api) 无异\r\n\r\n| 参数 | 说明 | 类型 | 默认值 |\r\n|------------- |---------------- |---------------- |---------------------- |\r\n| v-model (value) | 当前输入的值 | number/string | — |\r\n|label|\t输入框左侧文本|\tstring|\t-|\r\n|name|\t名称,提交表单的标识符\t|string\t|-|\r\n|type\t|输入框类型, 可选值为 |tel |digit|\r\n|number| textarea password 等|\tstring\t|text|\r\n|size\t|大小,可选值为 large|\tstring|\t-|\r\n|maxlength|\t输入的最大字符数|\tnumber / string|\t-|\r\n|placeholder|\t输入框占位提示文字|\tstring|\t-|\r\n|border\t|是否显示内边框|\tboolean|\ttrue|\r\n|disabled\t|是否禁用输入框|\tboolean|\tfalse|\r\n|readonly|\t是否只读|\tboolean\t|false|\r\n|colon|\t是否在 label 后面添加冒号|\tboolean|\tfalse|\r\n|required|\t是否显示表单必填星号\t|boolean|\tfalse|\r\n|center\t|是否使内容垂直居中\t|boolean|\tfalse|\r\n|clearable\t|是否启用清除图标,点击清除图标后会清空输入框|\tboolean\t|false|\r\n|clear-trigger|显示清除图标的时机,always 表示输入框不为空时展示,focus 表示输入框聚焦且不为空时展示\t|string|\tfocus|\r\n|clickable|\t是否开启点击反馈\t|boolean\t|false|\r\n|s-link\t|是否展示右侧箭头并开启点击反馈\t|boolean|\tfalse|\r\n|autofocus\t|是否自动聚焦,iOS 系统不支持该属性\t|boolean|\tfalse|\r\n|show-word-limit\t|是否显示字数统计,需要设置maxlength属性\t|boolean|\tfalse|\r\n|error\t|是否将输入内容标红|\tboolean|\tfalse|\r\n|error-message|\t底部错误提示文案,为空时不展示|\tstring|\t-|\r\n|formatter\t|输入内容格式化函数\t|Function\t|-|\r\n|format-trigger|\t格式化函数触发的时机,可选值为 onBlur\t|string\t|onChange|\r\n|arrow-direction\t|箭头方向,可选值为 left up down|\tstring\t|right|\r\n|label-class|\t左侧文本额外类名|\tany|\t-|\r\n|label-width|\t左侧文本宽度,默认单位为px|\tnumber / string|\t6.2em|\r\n|label-align|\t左侧文本对齐方式,可选值为 center right\t|string\t|left|\r\n|input-align|\t输入框对齐方式,可选值为 center right|\tstring|\tleft|\r\n|error-message-align\t|错误提示文案对齐方式,可选值为 center right\t|string|\tleft|\r\n|autosize|\t是否自适应内容高度,只对 textarea 有效,可传入对象,如 { maxHeight: 100, minHeight: 50 },单位为px\t|boolean / object\t|false|\r\n|left-icon|\t左侧图标名称或图片链接|\tstring\t|-|\r\n|right-icon\t|右侧图标名称或图片链接|\tstring\t|-|\r\n|icon-prefix |\t图标类名前缀,同 Icon 组件的 class-prefix 属性|\tstring\t|van-icon|\r\n|autocomplete\t|input 标签原生的自动完成属性|\tstring\t|-|\r\n\r\n\r\n### Events\r\n\r\n使用及 **API** 与 [van-field](https://youzan.github.io/vant/v2/#/zh-CN/field#events) 无异\r\n除下列事件外,Field 默认支持 Input 标签所有的原生事件\r\n\r\n| 事件 | 说明 | 回调参数 |\r\n|------------- |---------------- |---------------- |\r\n|input|\t输入框内容变化时触发|\tvalue: string (当前输入的值)|\r\n|focus|\t输入框获得焦点时触发|\tevent: Event|\r\n|blur\t|输入框失去焦点时触发|\tevent: Event|\r\n|clear\t|点击清除按钮时触发|\tevent: Event|\r\n|click|\t点击 Field 时触发\t|event: Event|\r\n|click-input|\t点击输入区域时触发|\tevent: Event|\r\n|click-left-icon|\t点击左侧图标时触发|\tevent: Event|\r\n|click-right-icon|\t点击右侧图标时触发\t|event: Event|\r\n\r\n\r\n### Methods\r\n通过 ref 可以获取到 Field 实例并调用实例方法,详见组件实例方法。\r\n\r\n| 方法名 | 说明 | 参数 | 返回值|\r\n|------------- |---------------- |---------------- |----------- |\r\n|focus|\t获取输入框焦点|\t-\t|-|\r\n|blur\t|取消输入框焦点|\t-|\t-|\r\n\r\n\r\n### Slots\r\n| 名称 | 说明 |\r\n|------------- |---------------- |\r\n|label|\t自定义输入框 label 标签|\r\n|input\t|自定义输入框,使用此插槽后,与输入框相关的属性和事件将失效。在 Form 组件进行表单校验时,会使用 input 插槽中子组件的 value,而不是 Field 组件的 value。\r\n|left-icon\t|自定义输入框头部图标|\r\n|right-icon\t|自定义输入框尾部图标|\r\n|button|\t自定义输入框尾部按钮|\r\n|extra|\t自定义输入框最右侧的额外内容|"
},
{
"name": "ws-material-grid",
"category": "移动端组件库",
"content": "## WsMaterialGrid 九宫格素材展示组件\r\n\r\n九宫格素材展示组件\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineMaterialGrid } from '@wshoto/h5-base-ui';\r\n\r\n// TODO: 目前端上使用 WsMaterialGrid\r\nVue.component('WsMaterialGrid', WeShineMaterialGrid);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 基础的组件用法。\r\n\r\n```html\r\n<template>\r\n <we-shine-material-grid\r\n :mode=\"mode\"\r\n :isPreview=\"isPreview\"\r\n :data=\"fileList\"\r\n :columnNum=\"columnNum\"\r\n :gutter=\"gutter\"\r\n :border=\"border\"\r\n :radius=\"radius\"\r\n :isTrackOfWeb=\"isTrackOfWeb\"\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsMaterialGrid',\r\n fileList: [\r\n {\r\n id: 218210,\r\n cosUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/16290933509743713e0b4ca3d43f498209e6d07ef2d83.jpg',\r\n type: 'image',\r\n imageBase: 45364,\r\n imageBaseUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/16290933509743713e0b4ca3d43f498209e6d07ef2d83.jpg',\r\n name: '微信图片_2021081613',\r\n fileExtension: '__vue_devtool_undefined__',\r\n size: '__vue_devtool_undefined__',\r\n isMaterial: true,\r\n materialId: 45364,\r\n abstractInfo: '',\r\n webUrl: '__vue_devtool_undefined__',\r\n shortLink: '__vue_devtool_undefined__'\r\n },\r\n {\r\n id: 218498,\r\n cosUrl: '',\r\n type: 'article',\r\n imageBase: 45838,\r\n imageBaseUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/1629270529180486edad9ea484a0d8be1eb0e550908e8.jpg',\r\n name: '暂停!关闭!限流!武汉新晋排队巨头发布紧急通知...',\r\n fileExtension: '__vue_devtool_undefined__',\r\n size: '__vue_devtool_undefined__',\r\n isMaterial: true,\r\n materialId: '',\r\n abstractInfo: '冲冲冲!',\r\n webUrl:\r\n 'https://platform-test.wshoto.com/v3/resource-center/index/web.html?id=218498&originUrl=https://mp.weixin.qq.com/s/75gtPF1T5ynMAyKSVL6ydA',\r\n shortLink: '__vue_devtool_undefined__'\r\n },\r\n {\r\n id: 218485,\r\n cosUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/16292512346785dc29dd1de564b8b917ea0bd1a3a47b5.png',\r\n type: 'web',\r\n imageBase: 45813,\r\n imageBaseUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/16292512346785dc29dd1de564b8b917ea0bd1a3a47b5.png',\r\n name: '腾讯网',\r\n fileExtension: '__vue_devtool_undefined__',\r\n size: '__vue_devtool_undefined__',\r\n isMaterial: true,\r\n materialId: '',\r\n abstractInfo: '',\r\n webUrl: '__vue_devtool_undefined__',\r\n shortLink: 'https://platform-test.wshoto.com/v3/resource-center/public/link?id=218485'\r\n },\r\n {\r\n id: 218273,\r\n cosUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/1629099250358710ae67ee9a3496895e79bd632129528.mp4',\r\n type: 'video',\r\n imageBase: 45471,\r\n imageBaseUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/1629099250358710ae67ee9a3496895e79bd632129528.jpg',\r\n name: '天龙八部.mp4',\r\n fileExtension: '__vue_devtool_undefined__',\r\n size: '__vue_devtool_undefined__',\r\n isMaterial: true,\r\n materialId: 45470,\r\n abstractInfo: '',\r\n webUrl: '__vue_devtool_undefined__',\r\n shortLink: '__vue_devtool_undefined__'\r\n },\r\n {\r\n id: 218507,\r\n cosUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/16292740397032fcda5142d174737a37860e0f0a6006a.docx',\r\n type: 'file',\r\n imageBase: '__vue_devtool_undefined__',\r\n imageBaseUrl: '',\r\n name: '新建 DOCX 文档.docx',\r\n fileExtension: 'docx',\r\n size: 11018,\r\n isMaterial: true,\r\n materialId: '',\r\n abstractInfo: '',\r\n webUrl: '__vue_devtool_undefined__',\r\n shortLink: '__vue_devtool_undefined__'\r\n },\r\n {\r\n id: 218268,\r\n cosUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/1629096171806748ebdd834bd4f219afff9e959fe9013.jpg',\r\n type: 'miniApp',\r\n imageBase: 45449,\r\n imageBaseUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/1629096171806748ebdd834bd4f219afff9e959fe9013.jpg',\r\n name: '商城中心',\r\n fileExtension: '__vue_devtool_undefined__',\r\n size: '__vue_devtool_undefined__',\r\n isMaterial: true,\r\n materialId: '',\r\n abstractInfo: '',\r\n webUrl: '__vue_devtool_undefined__',\r\n shortLink: '__vue_devtool_undefined__',\r\n appId: 'wxa7bb16ec8562d3a9',\r\n appPath: 'weshineo2o@163.com'\r\n }\r\n ],\r\n mode: 'grid',\r\n isPreview: true,\r\n columnNum: 3,\r\n gutter: 12,\r\n border: true,\r\n radius: 8,\r\n isTrackOfWeb: false\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n#### 基础属性 \r\n\r\n| 属性 | 说明 | 类型 | 默认值 | 备注 |\r\n|-----------------|-------------------------------------|---------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\r\n| mode | 展示模式 grid(宫格)、list(列表) | String | grid | |\r\n| data | 需要渲染的数据 | Array | - | {<br/>&nbsp;&nbsp;&nbsp;&nbsp;// fileExtension: undefined, // 素材类型为file时的文件拓展名可以为空 <br/>&nbsp;&nbsp;&nbsp;&nbsp;// id: 165860, // 素材id<br/>&nbsp;&nbsp;&nbsp;&nbsp;// imageBase: 42036, // 素材的展示id<br/>&nbsp;&nbsp;&nbsp;&nbsp;// name: '呃呃呃', // 素材名称<br/>&nbsp;&nbsp;&nbsp;&nbsp;// type: 'image', // 素材类型<br/>&nbsp;&nbsp;&nbsp;&nbsp;// cosUrl: '', // 真实地址 预留时必要字段<br/>&nbsp;&nbsp;&nbsp;&nbsp;// status: '' // 配合上传组件才用到 可以不管<br/>&nbsp;&nbsp;&nbsp;&nbsp;// isMaterial // 预留字段不管<br/>} |\r\n| isPreview | 是否可预览 | Boolean | false | |\r\n| isCustomPreview | 是否开启自定义预览 开启后会有回传自定义customPreview方法 | Boolean | false | |\r\n| columnNum | 列数 | Number | 3 | |\r\n| gutter | 间距 | Number | 12 | |\r\n| border | 是否显示边框 | Boolean | false | |\r\n| radius | 圆角(px) | Number | 8 | |\r\n| isTrackOfWeb | 网页文件是否需要埋点 | Boolean | false | |\r\n| isDelete | 是否可删除 | Boolean | false | |\r\n| isShowLoading | 是否显示上传中的loading状态 (grid模式) | Boolean | false | |\r\n\r\n#### 搭配上传组件属性\r\n\r\n| 属性名 | 说明 | 类型 | 默认值 | 备注 |\r\n|:---------------------|:---------------------|:---------|:------|:----|\r\n| isUpload | 是否和上传文件组件连用 | Boolean | false | |\r\n| isShowAdd | 是否显示添加按钮(与上传组件连用时生效) | Boolean | false | |\r\n| gridHandlerIcon | 九宫格触发上传按钮icon | String | | |\r\n| isSync | 是否同步到素材库 | Boolean | false | |\r\n| isEditTitle | 是否可编辑素材名称(list模式可用) | Boolean | false | |\r\n| privateMaterialFlag | 是否是私有素材 | Boolean | true | |\r\n| isShowToggleBtn | 是否显示展开按钮 | Boolean | true | |\r\n| limitEditTitleLenght | 限制编辑标题的字数 | Number | 15 | |\r\n| disabledDeleteIds | 不能删除的id集合 | Array | | |\r\n| isShowDeleteStatus | 是否展示素材异常状态 | Boolean | false | |\r\n| hasSendType | 是否展示轨迹素材的发送方式 | Boolean | false | |\r\n| validSendType | 校验素材发送方式 | Function | | |\r\n\r\n\r\n**注意: type 需要自行转化 (素材中心 素材类型:1-海报, 2-文本, 3-图片, 4-网页, 5-语音, 6-视频, 7-文件, 8-小程序;组件素材类型:文本-text,图片-image,视频-video,文件-file,网页-web,文章-article,小程序-miniApp)**"
},
{
"name": "ws-material-upload",
"category": "移动端组件库",
"content": "## WsMaterialUpload 九宫格上传组件\r\n\r\n九宫格展示媒体信息, 支持素材库选择与本地文件上传\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WeShineMaterialUpload } from '@wshoto/h5-base-ui';\r\n\r\n// TODO: 目前端上使用 WsMaterialUpload\r\nVue.component('WeShineMaterialUpload', WeShineMaterialUpload);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 基础的组件用法。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <h2 class=\"ws-doc-demo-block__title\">默认情况<span v-if=\"isUploading\">(上传中...)</span></h2>\r\n <div class=\"demo-button-row\" style=\"padding: 20px; background-color: white\">\r\n <we-shine-material-upload\r\n v-model=\"fileList\"\r\n :isUploading.sync=\"isUploading\"\r\n :materialTypes=\"materialTypes\"\r\n :uploadTypes=\"['image','video','file']\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isUploading: false,\r\n fileList: [],\r\n materialTypes: ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp', 'goods', 'coupon', 'seckill', 'poster', 'market']\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 文件选取后拦截验证处理(视频长度小于30s)。\r\n\r\n```html\r\n<template>\r\n <we-shine-material-upload v-model=\"fileList1\" :materialTypes=\"materialTypes\" :afterReadFilter=\"afterReadFilter\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n fileList1: [],\r\n materialTypes: ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp', 'goods', 'coupon', 'seckill', 'poster', 'market']\r\n };\r\n },\r\n methods: {\r\n /**\r\n * @description: 文件选取后拦截处理\r\n * @param {*} file 选取的文件\r\n * @return {Boolean}\r\n */\r\n afterReadFilter(file) {\r\n const fileType = file && file.file && file.file.type && file.file.type.split('/')[0];\r\n if (fileType === 'video') {\r\n this.getVideoInfo(file).then(function(res) {\r\n console.log(res);\r\n if (res.duration > 30) {\r\n this.$toast('视频不合法');\r\n return false;\r\n }\r\n }.bind(this));\r\n }\r\n\r\n return true;\r\n },\r\n\r\n getVideoInfo(src) {\r\n try {\r\n return new window.Promise((resolve, reject) => {\r\n let video = this.$refs.video;\r\n const objectURL = URL.createObjectURL(src.file);\r\n video.src = objectURL;\r\n video.addEventListener('loadedmetadata', (v) => {\r\n resolve({\r\n width: v.target ? v.target.videoWidth : undefined,\r\n height: v.target ? v.target.videoHeight : undefined,\r\n duration: v.target ? v.target.duration : undefined\r\n });\r\n URL.revokeObjectURL(objectURL);\r\n });\r\n });\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 触发器宫格展示。\r\n\r\n```html\r\n<template>\r\n <we-shine-material-upload v-model=\"fileList11\" :triggerMode=\"2\" :materialTypes=\"materialTypes\" :columnNum=\"4\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n fileList11: [],\r\n materialTypes: ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp', 'goods', 'coupon', 'seckill', 'poster', 'market']\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 列表展示。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <h2 class=\"ws-doc-demo-block__title\">列表展示<span v-if=\"isUploading2\">(上传中...)</span></h2>\r\n <div class=\"demo-button-row\" style=\"padding: 20px; background-color: white\">\r\n <we-shine-material-upload\r\n v-model=\"fileList2\"\r\n :isEditTitle=\"true\"\r\n :limitEditTitleLenght=\"18\"\r\n meterialShowMode=\"list\"\r\n hasSendType\r\n :isUploading.sync=\"isUploading2\"\r\n :materialTypes=\"materialTypes\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isUploading2: false,\r\n fileList2: [],\r\n materialTypes: ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp', 'goods', 'coupon', 'seckill', 'poster', 'market']\r\n };\r\n },\r\n methods: {\r\n /**\r\n * @description: 文件选取后拦截处理\r\n * @param {*} file 选取的文件\r\n * @return {Boolean}\r\n */\r\n afterReadFilter(file) {\r\n const fileType = file && file.file && file.file.type && file.file.type.split('/')[0];\r\n if (fileType === 'video') {\r\n this.getVideoInfo(file).then(function(res) {\r\n console.log(res);\r\n if (res.duration > 30) {\r\n this.$toast('视频不合法');\r\n return false;\r\n }\r\n }.bind(this));\r\n }\r\n\r\n return true;\r\n },\r\n\r\n getVideoInfo(src) {\r\n try {\r\n return new window.Promise((resolve, reject) => {\r\n let video = this.$refs.video;\r\n const objectURL = URL.createObjectURL(src.file);\r\n video.src = objectURL;\r\n video.addEventListener('loadedmetadata', (v) => {\r\n resolve({\r\n width: v.target ? v.target.videoWidth : undefined,\r\n height: v.target ? v.target.videoHeight : undefined,\r\n duration: v.target ? v.target.duration : undefined\r\n });\r\n URL.revokeObjectURL(objectURL);\r\n });\r\n });\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n },\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 不触发弹窗直接上传。\r\n\r\n```html\r\n<template>\r\n <we-shine-material-upload\r\n v-model=\"fileList3\"\r\n isImmediately\r\n accept=\"application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\r\n :afterReadExtFilter=\"afterReadExtFilter\"\r\n :isCustomPreview=\"true\"\r\n @customPreview=\"customPreview\"\r\n :guideText=\"guideText\"\r\n meterialShowMode=\"list\"\r\n :disabledDeleteIds=\"disabledDeleteIds\"\r\n :beforeDelete=\"beforeDelete\"\r\n @uploadSuccess=\"uploadSuccess\"\r\n @deletedSuccess=\"deletedSuccess\"\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n fileList3: [],\r\n guideText: '<p>上传附件<span style=\"color:#999;\">(仅支持xls/xlsx格式文件)</span></p>',\r\n disabledDeleteIds: []\r\n };\r\n },\r\n methods: {\r\n uploadSuccess(fileInfo) {\r\n console.log(fileInfo);\r\n this.$toast('上传成功');\r\n },\r\n\r\n // 自定义预览\r\n customPreview(file) {\r\n console.log(file);\r\n },\r\n\r\n // 文件格式校验\r\n afterReadExtFilter(file) {\r\n console.log(file);\r\n return true;\r\n },\r\n beforeDelete(file) {\r\n console.log('beforeDelete', file);\r\n return true;\r\n },\r\n deletedSuccess(file) {\r\n console.log('deletedSuccess', file);\r\n this.$toast('删除成功');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 多选文本。\r\n\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <h2 class=\"ws-doc-demo-block__title\">多选文本<span v-if=\"isUploading\">(上传中...)</span></h2>\r\n <div class=\"demo-button-row\" style=\"padding: 20px; background-color: white\">\r\n <we-shine-material-upload\r\n v-model=\"fileList4\"\r\n multipleText\r\n :isUploading.sync=\"isUploading\"\r\n :materialTypes=\"materialTypes\"\r\n meterialShowMode=\"list\"\r\n :uploadTypes=\"['image','video','file']\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isUploading: false,\r\n fileList4: [],\r\n materialTypes: ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp', 'goods', 'coupon', 'seckill', 'poster', 'market']\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 轨迹素材选择发送形式。\r\n```html\r\n<template>\r\n <div class=\"ws-doc-demo-block\">\r\n <h2 class=\"ws-doc-demo-block__title\">轨迹素材选择发送形式</h2>\r\n <div class=\"demo-button-row\" style=\"padding: 20px; background-color: white\">\r\n <we-shine-material-upload\r\n v-model=\"fileList5\"\r\n :validSendType=\"validSendType\"\r\n :setSendType=\"setSendType\"\r\n hasSendType\r\n meterialShowMode=\"list\"\r\n :materialTypes=\"materialTypes\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n fileList5: [],\r\n materialTypes: ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp', 'goods', 'coupon', 'seckill', 'poster', 'market']\r\n };\r\n },\r\n \r\n methods: {\r\n // 校验轨迹素材发送形式\r\n validSendType(materialInfo) {\r\n const { type, size } = materialInfo;\r\n const res = {\r\n hasSendType: false\r\n };\r\n\r\n const trackMaterials = ['article', 'web', 'video', 'file'];\r\n // 轨迹素材才开启选择发送形式功能\r\n if (trackMaterials.includes(type)) {\r\n res.hasSendType = true;\r\n res.hasSwitch = true;\r\n }\r\n if (type === 'video' && size >= 20 * 1024 * 1024) {\r\n // 视频素材大小超过2M则只能选择轨迹形式发送\r\n res.hasSwitch = false;\r\n res.tips = '视频素材大小超过2M则只能选择轨迹形式发送';\r\n }\r\n return res;\r\n },\r\n\r\n setSendType(materialInfo) {\r\n let sendType = 1;\r\n const { type } = materialInfo;\r\n console.log(materialInfo, type);\r\n const defaultTypes = ['web', 'video'];\r\n if (defaultTypes.includes(type)) {\r\n sendType = 2;\r\n }\r\n return sendType;\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n通过v-model 传入绑定当前选择的素材信息,传入素材信息列表,定义示例:\r\n\r\n```js\r\n{\r\n _fid: 1628147687796,\r\n cosUrl:\r\n 'https://javatest-1253767630.cos.ap-shanghai.myqcloud.com/test/ws/1628147687350bc8c7529d873486bae2a9387ab9672ef.png',\r\n fileExtension: 'png',\r\n id: 22716,\r\n imageBase: '',\r\n isMaterial: false,\r\n name: '企业微信截图_20210607093135.png',\r\n size: 30131,\r\n status: 'ok',\r\n type: 'image'\r\n}\r\n```\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 | 备注 |\r\n|----------------------|---------------------------------------------------|----------|-------------------------------------------------|-----------------------------------------------------------------|--------------|\r\n| guideText | 初始状态,展示的引导语 ,+号右侧文本 | string | - | 添加附件 | 支持插入html标签 | \r\n| materialTypes | 素材库可选择文件类型 | Array | text, image, article, web, video, file, miniApp | ['text', 'image', 'article', 'web', 'video', 'file', 'miniApp'] | - | \r\n| uploadTypes | 本地可上传文件类型 | Array | image, video | ['image', 'video'] | - | \r\n| isUpLoading | 本地文件上传中标识,通过.sync绑定 | boolean | - | false | - | \r\n| maxNum | 支持累加最多选择的媒体数量 | number | - | 9 | - | \r\n| isSync | 是否同步到素材中心 | boolean | true/false | true | - | \r\n| privateMaterialFlag | 是否是私有素材 | boolean | true/false | true | - | \r\n| videoMaxSize | 最大上传视频 | number | - | 100 | - | \r\n| imageMaxSize | 最大上传图片 | number | - | 20 | - | \r\n| meterialShowMode | 素材上传后的展示形式 | string | grid/list | grid | - | \r\n| isImmediately | 是否立即上传(直接使用上传功能,不触发弹窗再使用上传功能) | boolean | true/false | false | - | \r\n| afterReadFilter | 选取文件后拦截过滤 | function | - | - | 返回true/false | \r\n| accept | 设置文件上传类型 | string | - | image/* | - | \r\n| isEditTitle | 是否可编辑素材名称(list模式可用)未同步到素材库,编辑的标题只改当前文件名不会调修改素材的接口 | boolean | - | false | - | \r\n| limitEditTitleLenght | 限制编辑名称的字数(list模式可用) | Number | - | 15 | - | \r\n| isCustomPreview | 是否开启自定义预览功能 | boolean | - | false | - |\r\n| multiple | 是否可多选文件 | boolean | - | true | - |\r\n| afterReadExtFilter | 自定义文件格式校验 | function | - | - | - |\r\n| beforeDelete | 删除文件前的验证处理 | function | - | - | 返回Boolean |\r\n| disabledDeleteIds | 素材不能删除的id集合 | array | - | - | - |\r\n| hasSendType | 是否显示轨迹素材的发送方式 | array | - | - | - |\r\n| triggerMode | 触发器样式 1:正常的icon加文案 2:宫格展示 | number | - | 1 | - |\r\n| columnNum | 宫格展示的列数 | number | - | 3 | - |\r\n| gutter | 宫格展示间距 | number | - | 12 | 单位px |\r\n| handlerIcon | 触发上传按钮icon | string | - | plus-new | - |\r\n| disabledHandlerIcon | 禁用的触发上传按钮icon | string | - | plus-new-disable | - |\r\n| gridHandlerIcon | 九宫格触发上传按钮icon | string | - | feedback-add | - |\r\n| validSendType | 校验素材发送方式 | Function | - | - | - |\r\n| useSource | 调用组件的业务来源 | string | - | - | - |\r\n| setSendType | 设置sendType值 | Function | - | - | - |\r\n\r\n:::tip\r\n#### validSendType 校验素材发送方式\r\n```js\r\n(materialInfo) => {\r\n hasSendType: boolean // 是否开启选择发送形式 true 开启\r\n hasSwitch: boolean, // 是否支持切换发送形式 true 支持\r\n tips: string // 自定义提示内容 hasSwitch 为 false 时的提示内容,为空不显示提示icon\r\n}\r\n```\r\n:::\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 | 示例 |\r\n|---------------|---------------------------------------------------|----------------------------------------|----------------------------------|\r\n| itemClick | 底部弹起的媒体类型选择面板,媒体类点击事件:如图片图标 | event: { isMaterial: boolean, type } | {isMaterial:false, type:'image'} |\r\n| textSelect | materialTypes包含了文本[\"text\"]时,用户选择了文本素材,通过此事件返回文本内容 | event: { id // 素材id, text // 素材文本的内容 } | |\r\n| uploadSuccess | 上传成功后的回调 | fileInfo | - |--|\r\n| customPreview | 自定义预览开启后的回调 | fileInfo | - |--|\r\n\r\n- 素材库\r\n - 支持选择类型:['text', 'image', 'article', 'web', 'video', 'file', 'miniApp']\r\n- 本地上传\r\n - 支持类型: ['image', 'video']\r\n\r\n### 素材类型\r\n\r\n| 类型 | 説明 | 素材库类型 |\r\n|---------|----------|-------|\r\n| text | 文本 | 2 |\r\n| image | 图片 | 3 |\r\n| article | 文章(公众号) | 4 |\r\n| web | 网页(非公众号) | 9 |\r\n| file | 素材库文件 | 7 |\r\n| miniApp | 小程序 | 8 |\r\n| coupon | 优惠券(小程序) | 10 |\r\n| goods | 商品(小程序) | 11 |\r\n| seckill | 活动(小程序) | 12 |\r\n\r\n### 素材主要参数定义\r\n\r\n| 参数名 | 定义 |\r\n|---------------|--------------------|\r\n| id | 素材id |\r\n| cosUrl | 素材的cos地址(主要用这个去展示) |\r\n| imageBase | 视频封面图 |\r\n| imageBaseUrl | 视频封面图 |\r\n| name | 素材名称 |\r\n| type | 素材类型 |\r\n| fileExtension | 素材类型为file时的文件拓展名 |\r\n| size | 素材大小 |"
},
{
"name": "ws-result-page",
"category": "移动端组件库",
"content": "## WsResultPage 结果页面组件\r\n\r\n显示满屏状态时的占位提示\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsResultPage } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsResultPage', WsResultPage);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 成功 + 单按钮。\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"isReportActivity = !isReportActivity\"> open WsResultPage</ws-button>\r\n <ws-result-page :show=\"isReportActivity\" type=\"success\" title=\"我是标题\" subTitle=\"我是副标题\">\r\n <!-- <ws-button block @click=\"isReportActivity = !isReportActivity\"> </ws-button> -->\r\n <ws-button-bar\r\n background=\"#fff\"\r\n @click=\"isReportActivity = !isReportActivity\"\r\n mainText=\"点击关闭结果页面\"\r\n />\r\n </ws-result-page>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsResultPage',\r\n isReportActivity: false,\r\n isReportActivity1: false,\r\n isReportActivity2: false\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 失败 + WsButtonBar组件。\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"isReportActivity1 = !isReportActivity1\"> open WsResultPage1</ws-button>\r\n <ws-result-page :show=\"isReportActivity1\" type=\"error\" title=\"我是标题\" subTitle=\"我是副标题\">\r\n <ws-button-bar\r\n background=\"#fff\"\r\n type=\"doubleEqual\"\r\n mainText=\"主要按钮\"\r\n secondaryText=\"次要按钮\"\r\n @click=\"isReportActivity1 = !isReportActivity1\"\r\n @secondaryClick=\"isReportActivity1 = !isReportActivity1\"\r\n />\r\n </ws-result-page>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsResultPage',\r\n isReportActivity: false,\r\n isReportActivity1: false,\r\n isReportActivity2: false\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 失败 + 自定义。\r\n```html\r\n<template>\r\n <div class=\"demo-button-row\">\r\n <ws-button block @click=\"isReportActivity2 = !isReportActivity2\"> open WsResultPage2</ws-button>\r\n <ws-result-page :show=\"isReportActivity2\" type=\"info\" title=\"我是标题\" subTitle=\"我是副标题我是副标题我是副标题我是副标题我是副标题我是副标题我是副标题我是副标题我是副标题我是副标题\">\r\n <ws-button-bar\r\n background=\"#fff\"\r\n type=\"doubleEqual\"\r\n mainText=\"主要按钮\"\r\n secondaryText=\"次要按钮\"\r\n @click=\"isReportActivity2 = !isReportActivity2\"\r\n @secondaryClick=\"isReportActivity2 = !isReportActivity2\"\r\n />\r\n <p class=\"test-style fs16\" @click=\"isReportActivity2 = !isReportActivity2\">返回列表</p>\r\n </ws-result-page>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsResultPage',\r\n isReportActivity: false,\r\n isReportActivity1: false,\r\n isReportActivity2: false\r\n };\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------- | ---------------- | ------- | ------------------ | ------- |\r\n| show | 是否显示结果页面 | boolean | - | false |\r\n| type | 图标状态 | string | success/error/info | success |\r\n| title | 标题 | string | - | - |\r\n| subhead | 副标题 | string | - | - |\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ------ | ---------------------- |\r\n| footer | 自定义底部操作按钮区域 |\r\n\r\n### Events\r\n\r\n无"
},
{
"name": "ws-search-with-filter",
"category": "移动端组件库",
"content": "## WsSearchWithFilter 搜索筛选组件\r\n\r\n用于列表展示筛选结果\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsSearchWithFilter } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsSearchWithFilter', WsSearchWithFilter);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <ws-search-with-filter />\r\n</template>\r\n```\r\n\r\n:::\r\n\r\n:::demo 配置文案。\r\n\r\n```html\r\n<template>\r\n <ws-search-with-filter isTeam initRoleTitle='全部' switchRoleTitle='我的' />\r\n</template>\r\n```\r\n\r\n:::\r\n\r\n:::demo 新增团队切换与右侧按钮,新增筛选点击事件。\r\n\r\n```html\r\n<template>\r\n <ws-search-with-filter\r\n isTeam\r\n background=\"#fff\"\r\n placeholder=\"搜索-placeholder\"\r\n rightIcon\r\n :totalCount=\"12\"\r\n @roleChange=\"roleChange\"\r\n @rightAction=\"searchRightAction\"\r\n @screen=\"screen\"\r\n />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsSearchWithFilter'\r\n };\r\n },\r\n methods: {\r\n roleChange({ mode }) {\r\n console.log(mode);\r\n this.$toast(`切换角色:${mode}`);\r\n },\r\n searchRightAction() {\r\n this.$toast('搜索右侧点击事件');\r\n },\r\n screen() {\r\n this.$toast('触发筛选事件');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 新增团队切换与右侧插槽,新增中间区域插槽内容。\r\n\r\n```html\r\n<template>\r\n <ws-search-with-filter\r\n isTeam\r\n background=\"#fff\"\r\n placeholder=\"搜索-placeholder\"\r\n :totalCount=\"120\"\r\n showAction\r\n :filter-list=\"['06.17-06.20','已选员工(4)','已选标签(3)']\"\r\n leftIcon=\"lottery-info-icon\"\r\n @leftIconClick=\"handleLeftIconClick\"\r\n @roleChange=\"roleChange\"\r\n @screen=\"screen\"\r\n >\r\n <template slot=\"action\">\r\n <span\r\n class=\"right-icon\"\r\n v-for=\"i in 3\"\r\n :key=\"i\"\r\n :style=\"`${i !== 1 && 'margin-left: .16rem'}`\"\r\n @click=\"searchRightSlotClick(i)\"\r\n >\r\n <!-- <svg-icon :src=\"require('../assets/plus.svg')\" /> -->\r\n <img src=\"~examples/assets/h5/plus.svg\" alt=\"\">\r\n </span>\r\n </template>\r\n <template slot=\"check\">\r\n <van-tabs>\r\n <van-tab title=\"标签 1\"></van-tab>\r\n <van-tab title=\"标签 2\"></van-tab>\r\n <van-tab title=\"标签 3\"></van-tab>\r\n <van-tab title=\"标签 4\"></van-tab>\r\n </van-tabs>\r\n </template>\r\n </ws-search-with-filter>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsSearchWithFilter',\r\n index3: 0,\r\n options3: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 },\r\n { text: '标签5', value: 4 },\r\n { text: '标签6', value: 5 },\r\n { text: '标签7', value: 6 },\r\n { text: '标签8', value: 7 }\r\n ]\r\n };\r\n },\r\n methods: {\r\n roleChange({ mode }) {\r\n console.log(mode);\r\n this.$toast(`切换角色:${mode}`);\r\n },\r\n searchRightAction() {\r\n this.$toast('搜索右侧点击事件');\r\n },\r\n searchRightSlotClick(index) {\r\n this.$toast(`搜索右侧插槽点击事件:${index}`);\r\n },\r\n screen() {\r\n this.$toast('触发筛选事件');\r\n },\r\n handleLeftIconClick() {\r\n this.$toast('触发页面右侧事件');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 新增团队切换与右侧插槽,新增中间区域插槽内容。\r\n\r\n```html\r\n<template>\r\n <ws-search-with-filter\r\n isTeam\r\n background=\"#fff\"\r\n placeholder=\"搜索-placeholder\"\r\n :totalCount=\"120\"\r\n showAction\r\n leftIcon=\"lottery-info-icon\"\r\n @leftIconClick=\"handleLeftIconClick\"\r\n @roleChange=\"roleChange\"\r\n @screen=\"screen\"\r\n >\r\n <template slot=\"action\">\r\n <span\r\n class=\"right-icon\"\r\n v-for=\"i in 3\"\r\n :key=\"i\"\r\n :style=\"`${i !== 1 && 'margin-left: .16rem'}`\"\r\n @click=\"searchRightSlotClick(i)\"\r\n >\r\n <!-- <svg-icon :src=\"require('../assets/plus.svg')\" /> -->\r\n <img src=\"~examples/assets/h5/plus.svg\" alt=\"\">\r\n </span>\r\n </template>\r\n <template slot=\"check\">\r\n <ws-button-filter :option=\"options3\" :index.sync=\"index3\" />\r\n </template>\r\n </ws-search-with-filter>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsSearchWithFilter',\r\n index3: 0,\r\n options3: [\r\n { text: '标签1', value: 0 },\r\n { text: '标签2', value: 1 },\r\n { text: '标签3', value: 2 },\r\n { text: '标签4', value: 3 },\r\n { text: '标签5', value: 4 },\r\n { text: '标签6', value: 5 },\r\n { text: '标签7', value: 6 },\r\n { text: '标签8', value: 7 }\r\n ]\r\n };\r\n },\r\n methods: {\r\n roleChange({ mode }) {\r\n console.log(mode);\r\n this.$toast(`切换角色:${mode}`);\r\n },\r\n searchRightAction() {\r\n this.$toast('搜索右侧点击事件');\r\n },\r\n searchRightSlotClick(index) {\r\n this.$toast(`搜索右侧插槽点击事件:${index}`);\r\n },\r\n screen() {\r\n this.$toast('触发筛选事件');\r\n },\r\n handleLeftIconClick() {\r\n this.$toast('触发页面右侧事件');\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | ------------------------ | -------- | ------ | ------- |\r\n| background | 背景色 | string | | #F2F4F8 |\r\n| showSearch | 是否显示搜索组件区域 | boolean | - | true |\r\n| showTotal | 是否显示筛选区域 | boolean | - | true |\r\n| totalCount | 结果总个数 | number | - | 0 |\r\n| showFilter | 是否显示筛选右侧显示区域 | boolean | - | true |\r\n| filterCount | 筛选右侧显示个数 | number | - | 0 |\r\n| filterList | 筛选右侧显示内容 | string[] | - | [] |\r\n\r\n#### 变更:filterCount 已被废弃,请使用 filterList、leftIcon 添加传boolean值时默认icon为提示图标\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ----- | ------------------ |\r\n| check | 自定义中间选择区域 |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ---------------- | -------- |\r\n| screen | 筛选右侧点击事件 | - |"
},
{
"name": "ws-table-h5",
"category": "移动端组件库",
"content": "## WsTable 组件\r\n\r\n表格组件\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsTable } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsTable', WsTable);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 单页模式。\r\n\r\n```html\r\n<template>\r\n <ws-table\r\n :key=\"pageMode\"\r\n ref=\"wstable\"\r\n :getList=\"getList\"\r\n pageMode=\"one\"\r\n multiTrigger\r\n hasRefresh\r\n @header-click=\"headerClick\"\r\n @sort-click=\"sortClick\"\r\n @row-click=\"rowClick\"\r\n @cell-click=\"cellClick\">\r\n <ws-table-column\r\n prop=\"info\"\r\n fixed\r\n width=\"2\">\r\n <template slot=\"header\">\r\n 商品信息\r\n </template>\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"购买人\"\r\n prop=\"name\"\r\n headerAlign=\"center\"\r\n align=\"center\"\r\n width=\"1.5\"\r\n sortable\r\n sortHandle\r\n className=\"bbb\"\r\n headerClassName=\"aaa\"\r\n :formatter=\"(v)=>v.split('').join('-')\">\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"年龄\"\r\n prop=\"age\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n sortHandle>\r\n <template slot-scope=\"scope\">\r\n {{scope.row.age}}\r\n </template>\r\n </ws-table-column>\r\n <ws-table-column\r\n prop=\"money\"\r\n width=\"2\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n :sortHandle=\"sortHandel\">\r\n <template #header>\r\n <div>\r\n <div style=\"margin-bottom: .05rem\">订单金额</div>\r\n <div style=\"text-align: right\">(元)</div>\r\n </div>\r\n </template>\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"金额\"\r\n prop=\"money\"\r\n width=\"2\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n :sortHandle=\"sortHandel\">\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"金额\"\r\n prop=\"money\"\r\n width=\"2\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n :sortHandle=\"sortHandel\">\r\n </ws-table-column>\r\n <ws-table-column type=\"arrow\" align=\"right\">\r\n </ws-table-column>\r\n </ws-table>\r\n</template>\r\n\r\n<script>\r\n\r\nconst mock = [\r\n { name: '孔勇', age: 86, info: '把量院问地律自市离取入社者公。', money: 551839264 },\r\n { name: '唐娟', age: 15, info: '响问标教取省做月接组情省我式立般。', money: 226074362 },\r\n { name: '姚娟', age: 81, info: '温转按以教华多没为斗京手看保。', money: 203649478 },\r\n { name: '龚强', age: 79, info: '物需儿证精这期拉政层切从里长半地认。', money: 201438820 },\r\n { name: '汤勇', age: 43, info: '往西布得计常可压须干有县条真员时社。', money: 175700070 },\r\n { name: '郑娜', age: 29, info: '报放天表点打由速单正么即式属至工有。', money: 993332025 },\r\n { name: '许明', age: 23, info: '委每团场实委共别务导会龙用。', money: 172290896 },\r\n { name: '史芳', age: 73, info: '已开教认历派时细后代运听完。', money: 994096604 },\r\n { name: '雷芳', age: 56, info: '治量区解油步究地强资主构音治六易光。', money: 302318096 },\r\n { name: '秦娜', age: 21, info: '受今必难好交子光红车图知。', money: 297721529 }\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsTable',\r\n pageMode: 'mutil',\r\n key: '',\r\n pageSize: 10,\r\n mockTotal: 0,\r\n tableData: []\r\n };\r\n },\r\n methods: {\r\n createMock() {\r\n // await new Promise(resolve => setTimeout(resolve, 2000));\r\n // eslint-disable-next-line no-undef\r\n return Promise.resolve({\r\n data: {\r\n list: mock,\r\n total: 42\r\n },\r\n code: '00000',\r\n message: ''\r\n });\r\n },\r\n getList(pageNum) {\r\n return this.createMock().then(({ data, code, message }) => {\r\n if (code === '00000') {\r\n return {\r\n list: data.list,\r\n total: data.total\r\n };\r\n } else {\r\n throw new Error(message);\r\n }\r\n });\r\n },\r\n sortHandel(column) {\r\n return (a, b) => {\r\n const rev = column.filterDir === 'bottom' ? 1 : -1;\r\n a = a[column.property];\r\n b = b[column.property];\r\n return a < b ? rev * -1 : a > b ? rev * 1 : 0;\r\n };\r\n },\r\n headerClick(args) {\r\n console.log('header', args);\r\n },\r\n sortClick(args) {\r\n console.log('sort', args);\r\n },\r\n cellClick(args) {\r\n console.log('cell', args);\r\n },\r\n rowClick(args) {\r\n console.log('row', args);\r\n },\r\n scroll(e) {\r\n if (e.target.scrollTop > 300) {\r\n (this.$refs.wstable).check();\r\n }\r\n },\r\n clearSort() {\r\n (this.$refs.wstable).clearSort();\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n:::demo 多页模式。\r\n\r\n```html\r\n<template>\r\n <ws-table\r\n :key=\"pageMode\"\r\n ref=\"wstable\"\r\n :getList=\"getList\"\r\n pageMode=\"mutil\"\r\n multiTrigger\r\n hasRefresh\r\n @header-click=\"headerClick\"\r\n @sort-click=\"sortClick\"\r\n @row-click=\"rowClick\"\r\n @cell-click=\"cellClick\">\r\n <template slot=\"bread\" v-if=\"jumpLevelName.length > 0\">\r\n <i class=\"icon-lib-common-arrow-left-16\" style=\"color: #BFC7CF; margin-right: 0.04rem;\" @click=\"backParentNode\"></i>\r\n\r\n <span v-for=\"(level, index) in jumpLevelName\" :key=\"index\" @click=\"backToLevel(level, index)\">\r\n <span :style=\"{color: index !== jumpLevelName.length - 1 ? 'var(--color-primary)' : '#222'}\">{{ level }}</span>\r\n <i class=\"icon-lib-common-slash-16\" style=\"color: #BFC7CF;\" v-if=\"index !== jumpLevelName.length - 1\"></i>\r\n </span>\r\n </template>\r\n <ws-table-column\r\n prop=\"info\"\r\n fixed\r\n :width=\"3.2\">\r\n <template slot=\"header\">\r\n 部门\r\n </template>\r\n <template slot-scope=\"scope\">\r\n <!-- 根据具体业务而定-->\r\n <div class=\"wrap-header_cell\" style=\"display: flex; align-items: center;\" @click=\"gotoNextLevel(scope.row)\">\r\n <div class=\"wrap-img\" v-if=\"scope.row.isDep || scope.row.isStaff\">\r\n <img v-if=\"scope.row.isDep\" src=\"~examples/assets/h5/placeholder-file-blue.png\" alt=\"\">\r\n <img v-if=\"scope.row.isStaff\" src=\"~examples/assets/h5/placeholder-portrait-blue.png\" alt=\"\">\r\n </div>\r\n <div class=\"van-multi-ellipsis--l2\" style=\"max-width: 1.6rem;\" v-if=\"!scope.row.depName\">\r\n {{ scope.row.info }}\r\n </div>\r\n <div v-else>\r\n <div class=\"van-ellipsis\" style=\"max-width: 1.8rem;\">{{ scope.row.info }}</div>\r\n <div style=\"color: #999999; font-size: 12px;\">{{ scope.row.depName }}</div>\r\n </div>\r\n <svg-icon icon-class=\"next-level-arrow\" class=\"arrow-icon\" v-if=\"scope.row.isHaveChild\" />\r\n </div>\r\n </template>\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"购买人\"\r\n prop=\"name\"\r\n headerAlign=\"center\"\r\n align=\"center\"\r\n width=\"1.5\"\r\n sortable\r\n sortHandle\r\n className=\"bbb\"\r\n headerClassName=\"aaa\"\r\n :formatter=\"(v)=>v.split('').join('-')\">\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"年龄\"\r\n prop=\"age\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n sortHandle>\r\n <template slot-scope=\"scope\">\r\n {{scope.row.age}}\r\n </template>\r\n </ws-table-column>\r\n <ws-table-column\r\n prop=\"money\"\r\n width=\"2\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n :sortHandle=\"sortHandel\">\r\n <template #header>\r\n <div>\r\n <div style=\"margin-bottom: .05rem\">订单金额</div>\r\n </div>\r\n </template>\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"金额\"\r\n prop=\"money\"\r\n width=\"2\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n :sortHandle=\"sortHandel\">\r\n </ws-table-column>\r\n <ws-table-column\r\n label=\"金额\"\r\n prop=\"money\"\r\n width=\"2\"\r\n headerAlign=\"right\"\r\n align=\"right\"\r\n sortable\r\n :sortHandle=\"sortHandel\">\r\n </ws-table-column>\r\n <ws-table-column type=\"arrow\" align=\"right\">\r\n </ws-table-column>\r\n </ws-table>\r\n</template>\r\n\r\n<script>\r\n\r\nconst mock = [\r\n { name: '孔勇', age: 86, info: '这是一个部门,(只模拟下钻样式)', money: 551839264, isDep: true, isHaveChild: true },\r\n { name: '唐娟', age: 15, info: '部门', money: 226074362, isDep: true, isHaveChild: true },\r\n { name: '姚娟', age: 81, info: '这里是一个部门的名称的名称的名称', money: 203649478, isDep: true, isHaveChild: true },\r\n { name: '龚强', age: 79, info: '这里是一个部门的名称的名称的名称', money: 201438820, isDep: true, isHaveChild: true },\r\n { name: '汤勇', age: 43, info: '这里是一个部门的名称的名称的名称', money: 175700070, isDep: true, isHaveChild: true },\r\n { name: '汤勇', age: 43, info: '这里是一个部门的名称的名称的名称名称。', money: 175700070, isDep: true, isHaveChild: true },\r\n { name: '郑娜', age: 29, info: '这里是一个部门的名称的名称的名称', money: 993332025, isDep: true, isHaveChild: true },\r\n { name: '许明', age: 23, info: '这里是一个部门的名称的名称的名称', money: 172290896, isDep: true, isHaveChild: true },\r\n { name: '史芳', age: 73, info: '部门', money: 994096604, isDep: true, isHaveChild: true },\r\n { name: '雷芳', age: 56, info: '这里是一个部门的名称的名称的名称', money: 302318096, isDep: true, isHaveChild: true },\r\n { name: '秦娜', age: 21, info: '这里是一个部门的名称的名称的名称', money: 297721529, isDep: true, isHaveChild: true }\r\n];\r\n\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsTable',\r\n pageMode: 'mutil',\r\n key: '',\r\n pageSize: 10,\r\n mockTotal: 0,\r\n tableData: [],\r\n jumpLevelName: [],\r\n currentName: ''\r\n };\r\n },\r\n methods: {\r\n createMock() {\r\n // await new Promise(resolve => setTimeout(resolve, 2000));\r\n // eslint-disable-next-line no-undef\r\n return Promise.resolve({\r\n data: {\r\n list: mock,\r\n total: 42\r\n },\r\n code: '00000',\r\n message: ''\r\n });\r\n },\r\n getList(pageNum) {\r\n return this.createMock().then(({ data, code, message }) => {\r\n if (code === '00000') {\r\n return {\r\n list: data.list,\r\n total: data.total\r\n };\r\n } else {\r\n throw new Error(message);\r\n }\r\n });\r\n },\r\n sortHandel(column) {\r\n return (a, b) => {\r\n const rev = column.filterDir === 'bottom' ? 1 : -1;\r\n a = a[column.property];\r\n b = b[column.property];\r\n return a < b ? rev * -1 : a > b ? rev * 1 : 0;\r\n };\r\n },\r\n headerClick(args) {\r\n console.log('header', args);\r\n },\r\n sortClick(args) {\r\n console.log('sort', args);\r\n },\r\n cellClick(args) {\r\n console.log('cell', args);\r\n },\r\n rowClick(args) {\r\n console.log('row', args);\r\n },\r\n scroll(e) {\r\n if (e.target.scrollTop > 300) {\r\n (this.$refs.wstable).check();\r\n }\r\n },\r\n clearSort() {\r\n (this.$refs.wstable).clearSort();\r\n },\r\n /**\r\n * 下钻选择\r\n */\r\n gotoNextLevel({ isHaveChild, info }) {\r\n if (!isHaveChild) return;\r\n this.jumpLevelName.push(info);\r\n this.currentName = info;\r\n },\r\n /**\r\n * 返回到上一级\r\n */\r\n backParentNode() {\r\n this.jumpLevelName.pop();\r\n this.currentName = this.jumpLevelName.length === 0 ? '' : this.jumpLevelName[this.jumpLevelName.length - 1];\r\n },\r\n /**\r\n * 具体场景做具体请求,此处只做示例\r\n * @param level\r\n * @param index\r\n */\r\n backToLevel(level, index) {\r\n this.jumpLevelName.splice(index, this.jumpLevelName.length - index);\r\n this.currentName = this.jumpLevelName.length === 0 ? '' : this.jumpLevelName[this.jumpLevelName.length - 1];\r\n // todo 业务中需重新请求当前表格数据\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Table Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|--------------|---------------------------------------------------------------------------------------------------|----------|-----------|-------|\r\n| getList | 获取数据的方法, 接收一个参数(当前页码), 必须返回一个包含着list、total(总条数)的对象 , 注:没有使用request封装的请求需要处理异常情况,异常情况需要throw error | Function | - | - |\r\n| pageSize | 每页多少条数据 | Number | - | 10 |\r\n| hasRefresh | 是否需要下拉刷新 | Boolean | - | false |\r\n| pageMode | 单页、多页模式 | String | one/mutil | mutil |\r\n| multiTrigger | 多页模式下是否由外部触发滚动事件,此属性和下拉刷新是冲突的 | Boolean | - | false |\r\n| stripe | 是否为斑马纹 | Boolean | - | true |\r\n\r\n### 注释: multiTrigger 属性适用的场景是 表格容器不在首屏的视窗内。\r\n 原因: vant的list源码里是根据两个元素和视窗的底部距离相减来判断是否加载数据,但现在我们有些场景表格是在首屏视窗外的,导致判断出错,出现无限加载数据\r\n\r\n### Table-Column Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n|-----------------|-----------------------------------------|--------------------------|-------------------|-------|\r\n| type | 类型 | string | arrow | - |\r\n| label | 显示的标题 | string | - | - |\r\n| prop | 对应列内容的字段名,也可以使用 property 属性 | string | - | - |\r\n| width | 对应列的宽度(单位rem) | string | - | - |\r\n| className | 列的 className | string | - | - |\r\n| headerClassName | header的 className | string | - | - |\r\n| align | 对齐方式 | string | left/center/right | left |\r\n| headerAlign | header的对齐方式 | string | left/center/right | left |\r\n| formatter | 用来格式化内容 | Function(cellValue) | - | - |\r\n| sortable | 对应列是否有排序功能 | boolean | - | false |\r\n| sortHandle | 排序的处理函数,传true时由表格提供的排序功能自动排序(最好单页模式下使用) | Function(column)/boolean | - | - |\r\n\r\n### Table Events\r\n\r\n| 事件名称 | 说明 | 参数 | \r\n|--------------|--------------------------|--------------------------|\r\n| header-click | 当某一列的表头被点击时会触发该事件 | column |\r\n| cell-click | 当某个单元格被点击时会触发该事件 | cell, column, event, row | \r\n| row-click | 当某一行点击时会触发该事件 | row, rowIndex, event |\r\n| sort-click | 当某一列表头存在排序功能且被点击时,会触发该事件 | column, direction | \r\n\r\n### Table Methods\r\n\r\n| 方法名称 | 说明 | 参数 | \r\n|-----------|---------------------------------------------|-----|\r\n| reset | 重置方法,重新加载数据时可调用 | - |\r\n| check | multiTrigger 属性为true时,由外部控制时机调用check属性来加载数据 | - |\r\n| clearSort | 清空排序状态,会重新请求数据 | - |\r\n\r\n### Table-column Scoped Slot\r\n\r\n| 名称 | 说明 | 参数 | \r\n|-----------|-------------------------------------|-----|\r\n| default | 自定义列的内容,参数为 { row, column, $index } | - |\r\n| header | 自定义表头的内容. 参数为 { column, $index } | - |\r\n| clearSort | 清空排序状态,会重新请求数据 | - |\r\n| bread | 有点击下一层时,传相关文案展示 | - |"
},
{
"name": "ws-tag",
"category": "移动端组件库",
"content": "## WsTag 组件\r\n\r\n标签组件\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsTag } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsTag', WsTag);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 标签类型。\r\n```html\r\n<template>\r\n <ws-tag type='success'>success</ws-tag>\r\n <ws-tag type='info'>info</ws-tag>\r\n <ws-tag type='warning'>warning</ws-tag>\r\n <ws-tag type='primary'>primary</ws-tag>\r\n <ws-tag type='danger'>danger</ws-tag>\r\n</template>\r\n\r\n```\r\n:::\r\n\r\n:::demo 标签尺寸 - small。\r\n```html\r\n<template>\r\n <ws-tag type='success' size='small'>success</ws-tag>\r\n <ws-tag type='info' size='small'>info</ws-tag>\r\n <ws-tag type='warning' size='small'>warning</ws-tag>\r\n <ws-tag type='primary' size='small'>primary</ws-tag>\r\n <ws-tag type='danger' size='small'>danger</ws-tag>\r\n</template>\r\n\r\n```\r\n:::\r\n\r\n:::demo 标签自定义颜色。\r\n```html\r\n<template>\r\n <ws-tag color='#7232dd' text-color='red'>标签</ws-tag>\r\n <ws-tag color='#ffe1e1' text-color='#ad0000'>标签</ws-tag>\r\n <ws-tag color='red' text-color='blue'>标签</ws-tag>\r\n</template>\r\n\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 |\r\n| --------- | ---------------------------------------------------------------------- | ------ | ----------- |\r\n| type | 标签类型,可选项为 success、info、warning、primary 和 danger | string | primary |\r\n| size | 标签尺寸,可选项为 normal 或 small | string | normal |\r\n| color | 标签颜色,支持 CSS 颜色字符串 | string | - |\r\n| textColor | 文本颜色,支持 CSS 颜色字符串 | string | - |\r\n\r\n### Slots\r\n\r\n| 名称 | 说明 |\r\n| ------- | ------------ |\r\n| default | 标签显示内容 |\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| -------- | ---------------- | ----------------- |\r\n| click | 标签点击触发事件 | event: MouseEvent |"
},
{
"name": "ws-team-switch",
"category": "移动端组件库",
"content": "## WsTeamSwitch 团队切换组件\r\n\r\n用于想要切换 `团队-我的` 场景的输入框组件。\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsTeamSwitch } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsTeamSwitch', WsTeamSwitch);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n```html\r\n<template>\r\n <ws-team-switch @onRoleChange='onRoleChange' />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsTeamSwitch'\r\n };\r\n },\r\n methods: {\r\n onRoleChange({ mode }) {\r\n console.log(mode);\r\n this.$toast(`切换角色:${mode}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 改变主题。\r\n```html\r\n<template>\r\n <ws-team-switch @onRoleChange='onRoleChange' theme='blue' />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsTeamSwitch'\r\n };\r\n },\r\n methods: {\r\n onRoleChange({ mode }) {\r\n console.log(mode);\r\n this.$toast(`切换角色:${mode}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n:::demo 文案配置。\r\n```html\r\n<template>\r\n <ws-team-switch @onRoleChange='onRoleChange' initRoleTitle='全部' switchRoleTitle='我的' />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n title: 'WsTeamSwitch'\r\n };\r\n },\r\n methods: {\r\n onRoleChange({ mode }) {\r\n console.log(mode);\r\n this.$toast(`切换角色:${mode}`);\r\n }\r\n }\r\n}\r\n</script>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 |\r\n| --------------- | ---------------------------------------- | ------ | --------- |\r\n| type | 控件类型,可选项为 light 或 blue | string | light |\r\n| initRoleId | 初始化角色 | number | 1 |\r\n| initRoleTitle | 主标题(有权限展示,例如超管,分管) | string | 团队 |\r\n| switchRoleTitle | 副标题 (取反) | string | 我的 |\r\n\r\n### Slots\r\n\r\n无\r\n\r\n### Events\r\n\r\n| 事件名称 | 说明 | 回调参数 |\r\n| ------------ | ---------------------------------- | -------- |\r\n| onRoleChange | 角色变更触发事件,一般点击团队切换 | - |"
},
{
"name": "ws-tips-bar-h5",
"category": "移动端组件库",
"content": "## WsTipsBar - 页面横幅提示组件\r\n\r\n### 基本使用\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <ws-tips-bar\r\n mode='warning'\r\n tipsContent='提示内容'\r\n buttonTxt='联系客服'\r\n >\r\n </ws-tips-bar>\r\n <br/>\r\n <ws-tips-bar\r\n mode='info'\r\n tipsContent='提示内容'\r\n buttonTxt='联系客服'\r\n />\r\n</template>\r\n```\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------- |----------|---------|-----|------|\r\n| mode | 提示类型 | string | warning \\| info \\| | warning |\r\n| isTipsIcon | 是否显示提示按钮 | Boolean | — | true |\r\n| tipsContent | 提示内容 | string | — | '' |\r\n| buttonTxt | 按钮文案 | string | — | '' |\r\n\r\n#### Events\r\n\r\n| 名称 | 说明 | 参数 |\r\n| ------- |---------| --------- |\r\n| clickBtn | 点击按钮时触发 | - |\r\n\r\n### Slot\r\n\r\n| 参数 | 说明 |\r\n| --------- |-------------|\r\n| tipsContent | 提供替换提示内容的插槽 |\r\n| tipsBtn | 提供替换提示按钮的插槽 |"
},
{
"name": "ws-type-filter",
"category": "移动端组件库",
"content": "## WsTypeFilter - 筛选器\r\n\r\n`WsTypeFilter` 是一个用于展示筛选条件的弹窗组件,通常用于列表筛选功能。该组件基于 `WsCustomPanel`、`WsFixBottomLayout` 和 `WsButtonBar` 组件封装,提供了筛选条件的展示、确认和重置功能。\r\n\r\n- `WsTypeFilter` 组件通过 `WsCustomPanel` 实现弹窗展示,支持自定义标题和懒加载渲染。\r\n- 组件底部通过 `WsFixBottomLayout` 实现固定布局,确保筛选按钮始终固定在底部。\r\n- 组件底部按钮通过 `WsButtonBar` 实现,提供“确定”和“重置”按钮,用户可以通过点击按钮进行筛选操作。\r\n- 点击遮罩层会关闭动作弹框\r\n- 子类组件`WsTypeFilterItem`、`WsTypeFilterDate`、`WsTypeFilterSelector`、`WsTypeFilterTag`、`WsTypeFilterNumberRange`、`WsTypeFilterMultiSelect`、`WsTypeFilterCascadeSelect`、 `WsTypeFilterMultiLoadSelector`与父组件`WsTypeFilter`搭配使用,放入父组件的内容区域。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter` 组件,并在页面中注册:\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsTypeFilter` 组件可以通过 `show` 属性控制弹窗的显示与隐藏,`title` 属性用于设置弹窗的标题。筛选条件通过默认插槽传入,底部按钮通过 `WsButtonBar` 提供“确定”和“重置”。\r\n\r\n```html\r\n<template>\r\n <ws-type-filter :show.sync=\"isFilterVisible\" title=\"筛选条件\">\r\n <div>筛选子组件内容</div>\r\n </ws-type-filter>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n };\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n#### 懒加载渲染\r\n\r\n通过 `lazyRender` 属性可以控制是否启用懒加载渲染。懒加载渲染可以在弹窗首次打开时才渲染内容,提升性能。\r\n\r\n\r\n#### 确定与重置操作\r\n\r\n`WsTypeFilter` 组件提供了 `confirm` 和 `reset` 事件,分别用于处理用户点击“确定”和“重置”按钮时的操作,子组件的确认、重置皆通过父组件完成。\r\n\r\n```html\r\n<template>\r\n <ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n >\r\n <div>筛选子组件内容</div>\r\n </ws-type-filter>\r\n</template>\r\n\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ---------- | ------------------ | ------- | ------ | ------ |\r\n| show | 是否显示筛选器 | boolean | — | false |\r\n| title | 筛选器标题 | string | — | 筛选 |\r\n| lazyRender | 是否启用懒加载渲染 | boolean | — | true |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| ----------- | -------------------------- | ---- |\r\n| confirm | 当用户点击“确定”按钮时触发 | — |\r\n| reset | 当用户点击“重置”按钮时触发 | — | \r\n| cancel | 当用户取消或关闭弹窗时触发 | — |\r\n\r\n \r\n\r\n## WsTypeFilterItem - 子筛选项组件\r\n\r\n`WsTypeFilterItem` 支持两种展示形式,默认用于平铺展示筛选项的组件,支持单选和多选模式,该组件有标题和选项数据上下结构组合而成,可以根据传入的选项数据源,直接展示筛选项,并允许用户选择或取消选择。`type`还支持‘select’,左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,支持自定义事件。组件支持自定义筛选项的布局、样式、提示文案等。\r\n\r\n### 默认类型组件功能\r\n\r\n- 支持单选和多选模式。\r\n- 支持自定义筛选项的列数和间距。\r\n- 支持禁用某些筛选项,并提供禁用提示。\r\n- 支持自定义筛选项的展示文案和选择提示。\r\n- 禁用背景色`#f8f9fb`、字色`#999` 、边框色`#e7ebf0`; 默认背景色`#f2f4f8`、字色`#545454` 、边框色`#d8d8d8`; 选中背景色`#2b60dd`、字色`#eaeffc` 、边框色`rgba(22, 87, 242, 0.1)`\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter`、`WsTypeFilterItem` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterItem } from `@wshoto/h5-base-ui`;\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterItem\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsTypeFilterItem` 组件可以通过传入 `options` 属性来展示筛选项。每个筛选项可以通过 `valueKey` 和 `labelKey` 来指定其值和显示的文本。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-item\r\n label=\"筛选项\"\r\n :options=\"[\r\n { id: 1, name: '选项1' },\r\n { id: 2, name: '选项2' },\r\n { id: 3, name: '选项3' }\r\n ]\"\r\n v-model=\"selectedValue\"\r\n />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedValue: [],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n#### 多选模式\r\n\r\n通过设置 `multiple` 属性为 `true`,可以启用多选模式,用户可以选择多个筛选项。\r\n\r\n\r\n#### 自定义列数和间距\r\n\r\n可以通过 `columnNum` 和 `gutter` 属性自定义筛选项的列数和间距。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-item\r\n label=\"筛选项\"\r\n :options=\"[\r\n { id: 1, name: '选项1' },\r\n { id: 2, name: '选项2' },\r\n { id: 3, name: '选项3' }\r\n ]\"\r\n :column-num=\"4\"\r\n :gutter=\"0.5\"\r\n v-model=\"selectedValue\"\r\n />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedValue: [],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n#### 禁用筛选项\r\n\r\n通过在 `options` 中设置 `disabled` 属性,可以禁用某些筛选项。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-item\r\n label=\"筛选项\"\r\n :options=\"[\r\n { id: 1, name: '选项1' },\r\n { id: 2, name: '选项2', disabled: true, disabledTip: '该选项不可用' },\r\n { id: 3, name: '选项3' }\r\n ]\"\r\n v-model=\"selectedValue\"\r\n />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedValue: [],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------- | --------------------------------------------------------------- | -------------- | -------------------- | --------- |\r\n| label | 筛选项的标题 | `string` | — | `''` |\r\n| type | 筛选项的类型,`default` 为块级筛选项,`select` 为选择类型筛选项 | `string` | `default` / `select` | `default` |\r\n| value | 当前选中的值,支持单选和多选模式 | `any` | — | — |\r\n| options | 筛选项的数据源,数组中的每个对象代表一个筛选项 | `OptionInfo[]` | — | `[]` |\r\n| valueKey | 指定筛选项中作为值的字段名 | `string` | — | `id` |\r\n| labelKey | 指定筛选项中作为显示文本的字段名 | `string` | — | `name` |\r\n| multiple | 是否启用多选模式 | `boolean` | — | `false` |\r\n| checkedCancel | 单选模式下,选中的值是否可以取消 | `boolean` | — | `true` |\r\n| columnNum | 筛选项的列数 | `number` | — | `3` |\r\n| gutter | 筛选项之间的间距,单位为 `rem` | `number` | — | `0.24` |\r\n| actionText | 选择操作的提示文案 | `string` | — | `请选择` |\r\n| selectLabel | 根据选择值展现的文案描述 | `string` | — | `''` |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| -------- | ------------------------ | ------- |\r\n| input | 当选中值发生变化时触发 | `value` |\r\n| onSelect | 当某个筛选项被选中时触发 | `item` |\r\n\r\n### Slots \r\n- 针对`type`类型为`select`时,插槽`label`、`selected`起作用\r\n\r\n| name | 说明 |\r\n| -------- | ---------------------------------------------------------------- |\r\n| default | 自定义筛选项内容,位于筛选项列表中 |\r\n| label | 自定义筛选项标题内容,位于筛选项标题旁边 |\r\n| selected | 自定义选择类型筛选项的已选中值展示区域,位于选择类型筛选项的右侧 |\r\n\r\n### 类型定义\r\n\r\n```ts\r\ninterface OptionInfo {\r\n id: string | number; // 筛选项的唯一标识\r\n name: string; // 筛选项的显示名称\r\n disabled?: boolean; // 是否禁用该筛选项\r\n disabledTip?: string; // 禁用时的提示信息\r\n [propName: string]: any; // 其他自定义属性\r\n}\r\n```\r\n\r\n## WsTypeFilterSelector - 选择人组件\r\n\r\n`WsTypeFilterSelector` 是一个用于筛选员工、部门或两者的组件,支持单选和多选模式。该组件集成了组织架构树,允许用户根据不同的权限和选择模式进行筛选。组件内部通过事件机制与页面交互,支持自定义筛选行为。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,跳转选择内容界面。\r\n\r\n### 组件功能\r\n\r\n- **单选/多选模式**:支持单选和多选模式,默认多选。\r\n- **选择类型**:支持选择成员、部门或两者,默认选择成员和部门。\r\n- **权限控制**:支持带权限和不带权限的选择,默认带权限。\r\n- **自定义筛选形态**:支持不同场景下的展示形态,如任务创建、列表筛选等。\r\n- **一键直达选人**:支持一键直达选人功能,快速选择成员或部门。\r\n- **选择操作提示**:支持自定义选择操作的提示文案和选择值的展示文案。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter`、`WsTypeFilterSelector` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterSelector } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterSelector,\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsTypeFilterSelector` 组件可以用于选择成员或部门,支持单选和多选模式。通过配置 `mode` 属性来控制选择模式,`choiceType` 属性来控制选择的类型(成员、部门或两者)。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-selector\r\n label=\"选择成员\"\r\n v-model=\"selectedValue\"\r\n :mode=\"2\"\r\n :choiceType=\"3\"\r\n />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedValue: {\r\n userList: [],\r\n depList: [],\r\n },\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n#### 单选/多选模式\r\n\r\n默认情况下,组件是多选模式。通过设置 `mode` 属性为 `2`,可以启用多选模式。 通过设置 `mode` 属性为 `1`,可以启用单选模式。\r\n\r\n\r\n#### 选择部门\r\n\r\n通过设置 `choiceType` 属性为 `2`,可以启用仅选择部门的模式。\r\n\r\n\r\n#### 自定义选择提示文案\r\n\r\n可以通过 `actionText` 属性自定义选择操作的提示文案。\r\n\r\n\r\n#### 只读模式\r\n\r\n通过设置 `readOnly` 属性为 `true`,可以启用只读模式,禁止用户进行选择操作。\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ----------------------------------- | -------- |\r\n| label | 筛选标题 | string | — | '' |\r\n| value | 已选值,包含成员列表和部门列表 | { userList: UserInfo[], depList: depInfo[] } | — | 必填 |\r\n| mode | 选择模式,1-单选,2-多选 | number | 1/2 | 2 |\r\n| choiceType | 选择类型,1-选择成员,2-选择部门,3-选择部门和成员 | number | 1/2/3 | 3 |\r\n| authorityType | 权限类型,1-带权限,2-不带权限 | number | 1/2 | 1 |\r\n| readOnly | 是否为只读模式,禁止选择操作 | boolean | — | false |\r\n| disableTipsText | 禁用提示文案 | string | — | '' |\r\n| checkedPanelTitle | 已选面板标题 | string | — | '' |\r\n| validStffHoldCustomerCount | 有效员工持有客户数量 | number | — | — |\r\n| distributeCustomerCount | 分配客户数量 | number | — | — |\r\n| coopModeType | 合作模式类型 | number | — | — |\r\n| disabledTypeTips | 禁用类型提示文案 | string | — | '' |\r\n| selectLimit | 选择限制 | number | — | — |\r\n| limitTips | 选择限制提示文案 | string | — | '' |\r\n| limit | 是否启用选择限制 | boolean | — | false |\r\n| shape | 不同场景下展示形态(select-创建任务时选择员工或部门,禁止选择成员状态是已禁用,退出企业或已离职的节点,禁止选择账号状态是未开通或已过期的节点; filter-列表筛选时选择员工或部门,展示“已离职成员”集合,禁止选择账号状态未开通或已过期的节点; filter-none-auth-node:禁止选择账号状态是未开通和已过期的节点,目前应用于客户/客户群列表数据和统计的筛选场景 默认filter ) | string | select/filter/filter-none-auth-node | filter |\r\n| actionText | 选择操作的提示文案 | string | — | '请选择' |\r\n| selectLabel | 根据选择值展现的文案描述 | string | — | '' |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| ----------- | ---------------------- | -------------------------------------------- |\r\n| input | 当选择值发生变化时触发 | { userList: UserInfo[], depList: depInfo[] } |\r\n| onSelect | 当用户点击选择时触发 | — |\r\n\r\n\r\n### Slots\r\n\r\n| name | 说明 |\r\n| -------- | ---------------------------------------------------------------- |\r\n| default | 自定义筛选项内容,位于筛选项列表中 |\r\n| label | 自定义筛选项标题内容,位于筛选项标题旁边 |\r\n| selected | 自定义选择类型筛选项的已选中值展示区域,位于选择类型筛选项的右侧 |\r\n\r\n\r\n### 类型定义\r\n\r\n```ts\r\ninterface UserInfo {\r\n userId: string; // 用户ID\r\n name: string; // 用户名\r\n}\r\n\r\ninterface depInfo {\r\n depId: number; // 部门ID\r\n name: string; // 部门名称\r\n}\r\n\r\ninterface SelectorInfo {\r\n userList: UserInfo[]; // 已选成员列表\r\n depList: depInfo[]; // 已选部门列表\r\n}\r\n```\r\n\r\n## WsTypeFilterTag - 标签筛选器\r\n\r\n`WsTypeFilterTag` 是一个用于筛选标签的组件,支持多种标签类型的筛选,包括群标签、企业标签、业务标签等。该组件提供了丰富的配置选项,允许用户根据业务需求自定义筛选行为,如标签的选择方式、标签的展示顺序、是否过滤自动标签等。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,跳转选择标签界面。\r\n\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter`、`WsTypeFilterTag` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterTag} from `@wshoto/h5-base-ui`;\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterTag\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-tag label=\"选择标签\" v-model=\"selectedTags\" />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedTags: {\r\n cropTagList: [],\r\n businessTagList: [],\r\n noAuthBusinessTagList: [],\r\n },\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n#### 标签选择模式\r\n\r\n组件支持多种标签选择模式,通过 `mode` 属性进行配置。可选值包括:\r\n\r\n- `group`: 群标签模式\r\n- `business`: 业务标签模式(默认)\r\n\r\n\r\n#### 标签选择限制\r\n\r\n通过 `limit` 属性可以限制用户最多选择的标签数量。\r\n\r\n\r\n#### 自动标签过滤\r\n\r\n通过 `isFilterAuto` 属性可以控制是否过滤自动标签,默认值为 `false`。\r\n\r\n\r\n#### 标签组选择\r\n\r\n通过 `isTagGroups` 属性可以启用标签组选择功能。\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------------------- | ----------------------------------------------------------------- | ----------------------- | -------------------- | ----------- |\r\n| label | 筛选器的标题 | `string` | — | `''` |\r\n| value | 已选标签信息,包含群标签、企业标签、业务标签等 | `SelectTagInfo` | — | 必填 |\r\n| mode | 标签选择模式,`group` 为群标签模式,`business` 为业务标签模式 | `string` | `group` / `business` | `business` |\r\n| limit | 限制用户最多选择的标签数量 | `number` | — | `undefined` |\r\n| isRadioGroup | 是否显示筛选条件 | `boolean` | — | `false` |\r\n| groupDisabledTagListProps | 禁止选中的群标签 ID 列表 | `Array<string>` | — | `[]` |\r\n| submitText | 底部确定按钮的文案 | `string` | — | `确定` |\r\n| isClue | 是否为线索标识 | `boolean` | — | `false` |\r\n| isTagGroups | 是否启用标签组选择功能 | `boolean` | — | `false` |\r\n| isDemo | 是否展示 demo 数据 | `boolean` | — | `false` |\r\n| isFilterAuto | 是否过滤自动标签 | `boolean` | — | `false` |\r\n| isToppingAuto | 是否置顶自动标签 | `boolean` | — | `false` |\r\n| isRestoreType | 是否还原标签 | `boolean` | — | `false` |\r\n| isFilterBusinessTag | 是否过滤业务标签 | `boolean` | — | `false` |\r\n| businessTagRange | 业务标签查询范围 | `0 \\| 1 \\| 2 \\| 3 \\| 4` | — | `4` |\r\n| isFooterTipsText | 是否展示选中文案提示 | `boolean` | — | `false` |\r\n| userId | 查询 userId 管理组业务标签 | `string` | — | `undefined` |\r\n| radioProps | 标签选择模式,1: 满足任意一个标签,2: 同时满足所选标签,3: 无标签 | `1 \\| 2 \\| 3` | — | `undefined` |\r\n| scene | 场景标识,用于过滤系统标签 | `string` | — | `undefined` |\r\n| isFilterAutoTagEdit | 自动标签区域仅展示已选的自动标签,且不可以编辑 | `boolean` | — | `false` |\r\n| actionText | 选择操作的提示文案 | `string` | — | `请选择` |\r\n| selectLabel | 根据选择值展现的文案描述 | `string` | — | `''` |\r\n| hasRadioGroupAndTagGroup | 是否同时存在筛选条件和标签组 | `boolean` | — | `false` |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| -------- | ------------------------ | --------------- |\r\n| input | 当标签选择发生变化时触发 | `SelectTagInfo` |\r\n| onSelect | 当用户点击选择标签时触发 | — |\r\n\r\n### Slots\r\n\r\n 同上`WsTypeFilterSelector`组件\r\n\r\n### 类型定义\r\n\r\n```ts\r\n/** 标签基础类型 */\r\nexport interface Tag {\r\n /** 标签id */\r\n tagId: string;\r\n /** 标签名称 */\r\n tagName: string;\r\n /** 标签组排序的次序值,order值大的排序靠前。有效的值范围是[0, 2^32) */\r\n order?: number;\r\n}\r\n\r\n/** 标签选择信息 */\r\nexport type SelectTagInfo = {\r\n groupTagList?: Tag[]; // 群标签\r\n cropTagList?: Tag[]; // 企业标签\r\n businessTagList?: Tag[]; // 业务标签\r\n noAuthBusinessTagList?: Tag[]; // 业务标签无权限\r\n radio: 1 | 2 | 3; // 标签选择模式\r\n};\r\n```\r\n\r\n## WsTypeFilterDate - 日期筛选器\r\n\r\n`WsTypeFilterDate` 是一个日期筛选器组件,允许用户选择日期范围。该组件支持快捷日期选择、日期范围选择,并允许配置是否允许选择同一天作为起止日期。组件内部集成了 `WsCalendar` 日历组件,提供了丰富的日期选择功能。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,弹出选择日期面板。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter`、`WsTypeFilterDate` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterDate } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterDate,\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n#### 基本使用\r\n\r\n`WsTypeFilterDate` 组件允许用户选择日期范围,并通过 `v-model` 绑定选中的日期值。默认情况下,组件会显示一个提示文案,用户点击后弹出日期选择器。\r\n\r\n```html\r\n<template>\r\n <ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n >\r\n <ws-type-filter-date v-model=\"selectedDates\" label=\"选择日期\" />\r\n </ws-type-filter>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedDates: [],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n};\r\n</script>\r\n```\r\n\r\n#### 自定义提示文案\r\n\r\n可以通过 `actionText` 属性自定义选择日期的提示文案。\r\n\r\n\r\n#### 自定义选择后的文案\r\n\r\n可以通过 `selectLabel` 属性自定义选择日期后的展示文案。\r\n\r\n\r\n#### 显示/隐藏快捷日期选择\r\n\r\n通过 `isShowDateType` 属性控制是否显示快捷日期选择区域,默认显示。\r\n\r\n\r\n#### 允许选择同一天\r\n\r\n通过 `allowSameDay` 属性控制是否允许选择的日期范围为同一天,默认允许。\r\n\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| -------------- | -------------------------------------------- | --------- | ------ | -------- |\r\n| label | 筛选标题 | `string` | — | `''` |\r\n| value | 已选日期值,日期数组,长度为 2 | `Date[]` | — | `[]` |\r\n| actionText | 选择操作的提示文案 | `string` | — | `请选择` |\r\n| selectLabel | 根据选择值展现的文案描述 | `string` | — | `''` |\r\n| isShowDateType | 是否显示选择日期快捷区间类型,默认显示 | `boolean` | — | `true` |\r\n| allowSameDay | 是否允许日期范围的起止时间为同一天,默认允许 | `boolean` | — | `true` |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| -------- | ------------------------ | -------- |\r\n| input | 当日期选择发生变化时触发 | `Date[]` |\r\n| onSelect | 当用户点击选择日期时触发 | — |\r\n\r\n### Slots\r\n\r\n 同上`WsTypeFilterSelector`组件\r\n\r\n## WsTypeFilterCascadeSelect - 级联选择筛选器\r\n\r\n`WsTypeFilterCascadeSelect` 是一个级联选择筛选器组件,支持多层级的选项选择。该组件通常用于需要多层级筛选的场景,例如地区选择、分类选择等。组件内部集成了 `CascadePicker` 组件,支持多选和回显选项值。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,弹出选择联级内容面板。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter`、`WsTypeFilterCascadeSelect` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterCascadeSelect } from `@wshoto/h5-base-ui`;\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterCascadeSelect\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsTypeFilterCascadeSelect` 组件支持多层级的选项选择,用户可以通过点击触发选择器,选择所需的选项。选择完成后,选中的值会通过 `v-model` 进行双向绑定。当用户重新打开选择器时,组件会自动回显之前选中的值,用户可以继续选择或修改。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-cascade-select\r\n label=\"地区选择\"\r\n v-model=\"selectedRegions\"\r\n :options=\"regionOptions\"\r\n action-text=\"请选择地区\"\r\n select-label=\"已选择地区\"\r\n />\r\n</ws-type-filter>\r\n```\r\n\r\n```js\r\nexport default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedRegions: [\"1-1\"],\r\n regionOptions: [\r\n {\r\n id: \"1\",\r\n name: \"省份1\",\r\n children: [\r\n { id: \"1-1\", name: \"城市1-1\" },\r\n { id: \"1-2\", name: \"城市1-2\" },\r\n ],\r\n },\r\n {\r\n id: \"2\",\r\n name: \"省份2\",\r\n children: [\r\n { id: \"2-1\", name: \"城市2-1\" },\r\n { id: \"2-2\", name: \"城市2-2\" },\r\n ],\r\n },\r\n ],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n};\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | ------------------------------------------------------------------- | --------------- | ------ | -------- |\r\n| label | 筛选器左侧的标题 | `string` | — | `''` |\r\n| value | 绑定的选择值,数组形式,存储选中的选项 id | `string[]` | — | `[]` |\r\n| actionText | 选择操作的提示文案 | `string` | — | `请选择` |\r\n| selectLabel | 根据选择值展现的文案描述 | `string` | — | `''` |\r\n| options | 可供选择的多选选项,支持多层级结构,格式为 `{ id, name, children }` | `CascadeNode[]` | — | `[]` |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| -------- | ------------------------ | ----------------- |\r\n| input | 当选择值发生变化时触发 | `value: string[]` |\r\n| onSelect | 当用户点击选择操作时触发 | — |\r\n\r\n### Slots\r\n\r\n 同上`WsTypeFilterSelector`组件\r\n\r\n### 类型定义\r\n\r\n```ts\r\ninterface CascadeNode {\r\n id: string; // 选项的唯一标识\r\n name: string; // 选项的名称\r\n checked?: boolean; // 是否选中\r\n half?: boolean; // 是否半选中\r\n children?: CascadeNode[]; // 子选项\r\n}\r\n```\r\n\r\n## WsTypeFilterMultiLoadSelector - 多选加载筛选器\r\n\r\n`WsTypeFilterMultiLoadSelector` 是一个多选加载筛选器组件,支持通过 API 动态加载选项,并允许用户进行多选操作。该组件适用于需要动态加载选项并进行多选筛选的场景。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,弹出选择内容面板。\r\n\r\n- 该组件基于 `MultiSelectLoad` 组件封装,提供了动态加载选项的能力。\r\n- 组件支持通过 `fetchApi` 属性传入 API 函数来获取选项数据。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入 `WsTypeFilter`、`WsTypeFilterMultiLoadSelector` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterMultiLoadSelector } from `@wshoto/h5-base-ui`;\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterMultiLoadSelector\r\n }\r\n }\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n通过 `fetchApi` 属性传入一个函数,用于从远程接口加载多选框的选项。该函数应返回一个 Promise,Promise 解析后的数据将作为选项展示。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-multi-load-selector\r\n label=\"远程加载筛选项\"\r\n v-model=\"selectedValues\"\r\n :fetch-api=\"fetchOptions\"\r\n />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedValues: [],\r\n };\r\n },\r\n methods: {\r\n fetchOptions() {\r\n return new Promise((resolve) => {\r\n setTimeout(() => {\r\n resolve([\"选项1\", \"选项2\", \"选项3\"]);\r\n }, 1000);\r\n });\r\n },\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | --------------------------------------------------------------------- | ------------------------- | ------ | ---------------- |\r\n| label | 筛选器左侧的标题 | `string` | — | `''` |\r\n| value | 绑定的选择值,必须为字符串数组 | `string[]` | — | `[]` |\r\n| actionText | 选择操作的提示文案 | `string` | — | `请选择` |\r\n| selectLabel | 根据选择值展现的文案描述 | `string` | — | `''` |\r\n| fetchApi | 多选选项请求的 API 函数,返回一个 Promise,Promise 解析后的数据为选项 | `() => Promise<string[]>` | — | `() => Function` |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| --------- | ---------------------- | ----------------- |\r\n| input | 当选择值发生变化时触发 | `value: string[]` |\r\n| onSelect | 当筛选器被点击时触发 | — |\r\n| onConfirm | 当用户确认选择时触发 | `value: string[]` |\r\n\r\n\r\n### Slots\r\n\r\n 同上`WsTypeFilterSelector`组件\r\n\r\n\r\n\r\n## WsTypeFilterMultiSelect - 多选筛选器\r\n\r\n`WsTypeFilterMultiSelect` 是一个多选筛选器组件,允许用户从多个选项中进行选择。该组件通常用于筛选条件的选择,支持多选操作,并提供了选择、重置、取消等功能。组件内部集成了 `MultipleSelectPicker` 组件,用于展示多选框。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,弹出选择内容面板。\r\n\r\n### 导入方式\r\n\r\n需从 `@wshoto/h5-base-ui` 中具名导入`WsTypeFilter`、 `WsTypeFilterMultiSelect` 组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterMultiSelect } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterMultiSelect,\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-multi-select\r\n label=\"筛选项\"\r\n v-model=\"selectedValues\"\r\n :options=\"options\"\r\n action-text=\"请选择\"\r\n select-label=\"已选择项\"\r\n />\r\n</ws-type-filter>\r\n```\r\n\r\n```js\r\nexport default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedValues: [], // 绑定的选择值\r\n options: [\r\n { id: \"1\", name: \"选项1\" },\r\n { id: \"2\", name: \"选项2\" },\r\n { id: \"3\", name: \"选项3\" },\r\n ],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n};\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ----------- | ------------------------------------------------------------ | -------------- | ------ | -------- |\r\n| label | 筛选的左侧标题 | `string` | — | `''` |\r\n| value | 绑定选择值 | `string[]` | — | `[]` |\r\n| actionText | 选择操作的提示文案 | `string` | — | `请选择` |\r\n| selectLabel | 根据选择值展现的文案描述 | `string` | — | `''` |\r\n| options | 可供选择的多选选项,数组中的每个对象包含 `id` 和 `name` 字段 | `OptionType[]` | — | `[]` |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| -------- | ---------------------- | ----------------- |\r\n| input | 当选择值发生变化时触发 | `value: string[]` |\r\n| onSelect | 触发选择事件时触发 | — |\r\n\r\n### Slots\r\n\r\n 同上`WsTypeFilterSelector`组件\r\n\r\n### 类型定义\r\n\r\n```ts\r\ntype OptionType = {\r\n id: string; // 选项的唯一标识\r\n name: string; // 选项的名称\r\n};\r\n```\r\n\r\n\r\n## WsTypeFilterNumberRange - 数字范围筛选器\r\n\r\n`WsTypeFilterNumberRange`组件用于在筛选条件中选择一个数字范围。该组件通常用于需要用户输入一个数字区间的场景。组件内部集成了`NumberPicker`组件,用于选择数字范围,并提供了重置、取消等功能。该组件左侧展示标题,右侧展示文案(提示文案或已选内容回显文案)及向右的箭头,当点击右侧时,弹出数字区间面板。\r\n\r\n### 导入方式\r\n\r\n需从`@wshoto/h5-base-ui`中具名导入`WsTypeFilter`、`WsTypeFilterNumberRange`组件,并在页面中注册。\r\n\r\n```html\r\n<script>\r\n import { WsTypeFilter, WsTypeFilterNumberRange } from \"@wshoto/h5-base-ui\";\r\n\r\n export default {\r\n components: {\r\n WsTypeFilter,\r\n WsTypeFilterNumberRange,\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### 组件功能\r\n\r\n#### 基本使用\r\n\r\n`WsTypeFilterNumberRange`组件用于选择一个数字范围,用户点击筛选项后会弹出数字选择器,选择完成后点击确认即可完成筛选。\r\n\r\n```html\r\n<ws-type-filter\r\n :show.sync=\"isFilterVisible\"\r\n title=\"筛选条件\"\r\n @confirm=\"onConfirm\"\r\n @reset=\"onReset\"\r\n>\r\n <ws-type-filter-number-range\r\n label=\"价格区间\"\r\n v-model=\"selectedRange\"\r\n action-text=\"请选择价格区间\"\r\n select-label=\"已选择价格区间\" \r\n />\r\n</ws-type-filter>\r\n<script>\r\n export default {\r\n data() {\r\n return {\r\n isFilterVisible: false,\r\n selectedRange: [\"100\", \"500\"],\r\n };\r\n },\r\n methods: {\r\n onConfirm() {\r\n console.log(\"用户点击了确定\");\r\n },\r\n onReset() {\r\n console.log(\"用户点击了重置\");\r\n },\r\n },\r\n };\r\n</script>\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------ | -------------------------- | -------- | ------ | ------ |\r\n| label | 筛选项的左侧标题 | string | — | '' |\r\n| value | 绑定的选择值,数字范围数组 | string[] | — | 必填 |\r\n| action-text | 选择操作的提示文案 | string | — | 请选择 |\r\n| select-label | 根据选择值展现的文案描述 | string | — | '' |\r\n\r\n### Events\r\n\r\n| 事件名 | 说明 | 参数 |\r\n| -------- | ---------------------- | --------------- |\r\n| input | 当选择值发生变化时触发 | value: string[] |\r\n| onSelect | 当用户点击筛选项时触发 | — |\r\n\r\n### Slots\r\n\r\n 同上`WsTypeFilterSelector`组件"
},
{
"name": "ws-footer",
"category": "移动端组件库",
"content": "## WsFooter 公司底部信息\r\n\r\n公司底部信息,用于提供公司名称或者技术支持\r\n\r\n### 引入\r\n\r\n```js\r\nimport Vue from 'vue';\r\nimport { WsFooter } from '@wshoto/h5-base-ui';\r\n\r\nVue.component('WsFooter', WsFooter);\r\n```\r\n\r\n### 基本用法\r\n\r\n:::demo 默认情况。\r\n\r\n```html\r\n<template>\r\n <ws-footer :model=\"0\" />\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n };\r\n },\r\n methods: {\r\n }\r\n}\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 可选值 | 默认值 |\r\n| ------------------ | -------------- | ------ | ------ | ------ |\r\n| type | 文字类型 | String | | '0' |\r\n| model(已废弃) | 是否固定在底部 | number | 0/1 | 1 |\r\n| background(已废弃) | 背景色 | string | | '#fff' |\r\n\r\n注: type:0-微盛·企微管家,1-微盛·企微管家 提供技术支持(文案配置在:ProjectVariables)"
},
{
"name": "ws-tag-select",
"category": "移动端组件库",
"content": "## WsTagSelect 标签页面组件\r\n\r\n选择标签页面组件。\r\n\r\n由于是页面级组件,所以不需要引入,直接使用即可\r\n\r\n### 基本用法(无筛选条件, 业务标签)\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag1'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive1' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList1.radio'>{{ tagList1.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中企业标签' name='2'>\r\n <template v-if='tagList1.cropTagList && tagList1.cropTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList1.cropTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中企业标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中业务标签' name='3'>\r\n <template v-if='tagList1.businessTagList && tagList1.businessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList1.businessTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中无权限业务标签' name='4'>\r\n <template v-if='tagList1.noAuthBusinessTagList && tagList1.noAuthBusinessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList1.noAuthBusinessTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中无权限业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList1: {},\r\n collapseActive1: '0'\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect1':\r\n this.tagList1 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag1() {\r\n const arr1 = this.tagList1.businessTagList ? this.tagList1.businessTagList.map(tag => tag.tagId) : [];\r\n const arr2 = this.tagList1.noAuthBusinessTagList ? this.tagList1.noAuthBusinessTagList.map(tag => tag.tagId) : [];\r\n const cropTagList = [...arr1, ...arr2];\r\n\r\n const corpCheckTagListProps = this.tagList1.cropTagList ? this.tagList1.cropTagList.map(tag => tag.tagId) : null;\r\n const businessCheckTagListProps = cropTagList;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect1', this.requestPageRouterName, {\r\n radioProps: this.tagList1.radio,\r\n corpCheckTagListProps,\r\n businessCheckTagListProps\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 有筛选条件(业务标签)\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag2'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive2' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList2.radio'>{{ tagList2.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中企业标签' name='2'>\r\n <template v-if='tagList2.cropTagList && tagList2.cropTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList2.cropTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中企业标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中业务标签' name='3'>\r\n <template v-if='tagList2.businessTagList && tagList2.businessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList2.businessTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中无权限业务标签' name='4'>\r\n <template v-if='tagList2.noAuthBusinessTagList && tagList2.noAuthBusinessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList2.noAuthBusinessTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中无权限业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList2: {},\r\n collapseActive2: '0'\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect2':\r\n this.tagList2 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag2() {\r\n const radioProps = this.tagList2.radio || null;\r\n const corpCheckTagListProps = this.tagList2.cropTagList ? this.tagList2.cropTagList.map(tag => tag.tagId) : null;\r\n const businessCheckTagListProps = this.tagList2.businessTagList ? this.tagList2.businessTagList.map(tag => tag.tagId) : null;\r\n const noAuthBusinessCheckTagListProps = this.tagList2.noAuthBusinessTagList ? this.tagList2.noAuthBusinessTagList.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect2', this.requestPageRouterName, {\r\n isRadioGroup: true,\r\n radioProps,\r\n corpCheckTagListProps,\r\n businessCheckTagListProps,\r\n noAuthBusinessCheckTagListProps\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 有筛选条件 + 客户群标签 + 关闭展示选中文案提示\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag3'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive3' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList3.radio'>{{ tagList3.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中标签' name='2'>\r\n <template v-if='tagList3.list && tagList3.list.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList3.list' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中标签数据</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList3: {},\r\n collapseActive3: '0',\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect3':\r\n this.tagList3 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag3() {\r\n const radioProps = this.tagList3.radio || null;\r\n const groupCheckTagListProps = this.tagList3.list ? this.tagList3.list.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect3', this.requestPageRouterName, {\r\n type: 'group',\r\n isRadioGroup: true,\r\n isFooterTipsText: false,\r\n radioProps,\r\n groupCheckTagListProps\r\n });\r\n },\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 有筛选条件 + 标签组\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag4'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive4' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList4.radio'>{{ tagList4.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中企业标签' name='2'>\r\n <template v-if='tagList4.cropTagList && tagList4.cropTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList4.cropTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中企业标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中业务标签' name='3'>\r\n <template v-if='tagList4.businessTagList && tagList4.businessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList4.businessTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中无权限业务标签' name='4'>\r\n <template v-if='tagList4.noAuthBusinessTagList && tagList4.noAuthBusinessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList4.noAuthBusinessTagList' :key='i.tagId' :text='i.tagName'/>\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中无权限业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList4: {},\r\n collapseActive4: '0',\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect4':\r\n this.tagList4 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag4() {\r\n const radioProps = this.tagList4.radio || null;\r\n const corpCheckTagListProps = this.tagList4.cropTagList ? this.tagList4.cropTagList.map(tag => tag.tagId) : null;\r\n const businessCheckTagListProps = this.tagList4.businessTagList ? this.tagList4.businessTagList.map(tag => tag.tagId) : null;\r\n const noAuthBusinessCheckTagListProps = this.tagList4.noAuthBusinessTagList ? this.tagList4.noAuthBusinessTagList.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect4', this.requestPageRouterName, {\r\n isRadioGroup: true,\r\n isTagGroups: true,\r\n radioProps,\r\n corpCheckTagListProps,\r\n businessCheckTagListProps,\r\n noAuthBusinessCheckTagListProps\r\n });\r\n },\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 有筛选条件 + 过滤自动标签 + 还原标签\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag5'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive5' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList5.radio'>{{ tagList5.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中企业标签' name='2'>\r\n <template v-if='tagList5.cropTagList && tagList5.cropTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList5.cropTagList' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中企业标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中业务标签' name='3'>\r\n <template v-if='tagList5.businessTagList && tagList5.businessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList5.businessTagList' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中无权限业务标签' name='4'>\r\n <template v-if='tagList5.noAuthBusinessTagList && tagList5.noAuthBusinessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList5.noAuthBusinessTagList' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中无权限业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList5: {\r\n cropTagList: [{\r\n tagId: 'etDkH9EAAArb7hDL3PT4UCWNUN9ITj7A',\r\n tagName: '分类3'\r\n }, {\r\n tagId: 'etDkH9EAAATOkyYkuKZrNJQGBcy_BaHA',\r\n tagName: '分类2'\r\n }]\r\n },\r\n collapseActive5: '0',\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect5':\r\n this.tagList5 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag5() {\r\n const radioProps = this.tagList5.radio || null;\r\n const corpCheckTagListProps = this.tagList5.cropTagList ? this.tagList5.cropTagList.map(tag => tag.tagId) : null;\r\n const businessCheckTagListProps = this.tagList5.businessTagList ? this.tagList5.businessTagList.map(tag => tag.tagId) : null;\r\n const noAuthBusinessCheckTagListProps = this.tagList5.noAuthBusinessTagList ? this.tagList5.noAuthBusinessTagList.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect5', this.requestPageRouterName, {\r\n isRadioGroup: true,\r\n isRestoreType: true,\r\n isFilterAutoTagEdit: true,\r\n isToppingAuto: false,\r\n radioProps,\r\n corpCheckTagListProps,\r\n businessCheckTagListProps,\r\n noAuthBusinessCheckTagListProps\r\n });\r\n },\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 客户画像·示例(isDemo)\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag6'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive6' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList6.radio'>{{ tagList6.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中标签' name='2'>\r\n <template v-if='tagList6.list && tagList6.list.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList6.list' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中标签数据</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList6: {\r\n list: [{\r\n tagId: '54',\r\n tagName: '已购买客户'\r\n }, {\r\n tagId: '56',\r\n tagName: '浏览频次中'\r\n }]\r\n },\r\n collapseActive6: '0',\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect6':\r\n this.tagList6 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag6() {\r\n const radioProps = this.tagList6.radio || null;\r\n const groupCheckTagListProps = this.tagList6.list ? this.tagList6.list.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect6', this.requestPageRouterName, {\r\n isDemo: true,\r\n isFilterAutoTagEdit: true,\r\n type: 'business',\r\n radioProps,\r\n groupCheckTagListProps\r\n });\r\n },\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 客户群画像·示例(isDemo)\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag8'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive8' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList8.radio'>{{ tagList8.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中标签' name='2'>\r\n <template v-if='tagList8.list && tagList8.list.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList8.list' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中标签数据</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList8: {},\r\n collapseActive8: '0'\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect8':\r\n this.tagList8 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag8() {\r\n const radioProps = this.tagList6.radio || null;\r\n const groupCheckTagListProps = this.tagList6.list ? this.tagList6.list.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect8', this.requestPageRouterName, {\r\n isDemo: true,\r\n type: 'group',\r\n isFilterAutoTagEdit: true,\r\n radioProps,\r\n groupCheckTagListProps\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n### 无权限业务标签\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag7'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive7' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList7.radio'>{{ tagList7.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中企业标签' name='2'>\r\n <template v-if='tagList7.cropTagList && tagList7.cropTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList7.cropTagList' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中企业标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中业务标签' name='3'>\r\n <template v-if='tagList7.businessTagList && tagList7.businessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList7.businessTagList' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n <van-collapse-item title='选中无权限业务标签' name='4'>\r\n <template v-if='tagList7.noAuthBusinessTagList && tagList7.noAuthBusinessTagList.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList7.noAuthBusinessTagList' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中无权限业务标签</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n </van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList7: {},\r\n collapseActive7: '0',\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect7':\r\n this.tagList7 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag7() {\r\n const radioProps = this.tagList5.radio || null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect7', this.requestPageRouterName, {\r\n isRadioGroup: true,\r\n isRestoreType: true,\r\n isFilterAutoTagEdit: true,\r\n isToppingAuto: false,\r\n radioProps,\r\n selectedNoAuthBusinessTagList: this.NoAuthBusinessTagList\r\n });\r\n },\r\n }\r\n };\r\n</script>\r\n```\r\n:::\r\n\r\n### 标签四种组合\r\n\r\n:::demo\r\n\r\n```html\r\n\r\n<template>\r\n <div class='demo-button-row'>\r\n <ws-button block @click='selectCustomerTag9'>跳转选标签组件页面</ws-button>\r\n <van-collapse v-model='collapseActive9' accordion>\r\n <van-collapse-item title='选中radio' name='1' v-if='tagList9.radio'>{{ tagList9.radio }}</van-collapse-item>\r\n <van-collapse-item title='选中标签' name='2'>\r\n <template v-if='tagList9.list && tagList9.list.length'>\r\n <van-grid square direction='horizontal'>\r\n <van-grid-item v-for='i in tagList9.list' :key='i.tagId' :text='i.tagName' />\r\n </van-grid>\r\n </template>\r\n <template v-else>\r\n <van-divider dashed>暂无选中标签数据</van-divider>\r\n </template>\r\n </van-collapse-item>\r\n</van-collapse>\r\n </div>\r\n</template>\r\n\r\n<script>\r\n // import Vue from 'vue';\r\n // import {Collapse, CollapseItem, Divider, Grid, GridItem} from 'vant';\r\n //\r\n // Vue.use(Collapse);\r\n // Vue.use(CollapseItem);\r\n // Vue.use(Divider);\r\n // Vue.use(Grid);\r\n // Vue.use(GridItem);\r\n\r\n export default {\r\n data() {\r\n return {\r\n title: 'WsTagSelect',\r\n requestPageRouterName: {name: 'WsTagSelectPage'},\r\n tagList9: {},\r\n collapseActive9: '0'\r\n };\r\n },\r\n created() {\r\n /**\r\n * 监听返回数据源\r\n */\r\n this.$pageContainer.$on('pageResult', (requestType, pageResult) => {\r\n switch (requestType) {\r\n case 'WsShineTagSelect9':\r\n this.tagList9 = Object.assign({}, pageResult);\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n },\r\n methods: {\r\n selectCustomerTag9() {\r\n const radioProps = this.tagList9.radio || null;\r\n const corpCheckTagListProps = this.tagList9.cropTagList ? this.tagList9.cropTagList.map(tag => tag.tagId) : null;\r\n const businessCheckTagListProps = this.tagList9.businessTagList ? this.tagList9.businessTagList.map(tag => tag.tagId) : null;\r\n const noAuthBusinessCheckTagListProps = this.tagList9.noAuthBusinessTagList ? this.tagList9.noAuthBusinessTagList.map(tag => tag.tagId) : null;\r\n\r\n this.$pageStack.requestPageResult('WsShineTagSelect9', this.requestPageRouterName, {\r\n isDemo: true,\r\n isTagGroups: false,\r\n isRadioGroup: true,\r\n hasRadioGroupAndTagGroup: true,\r\n radioProps,\r\n corpCheckTagListProps,\r\n businessCheckTagListProps,\r\n noAuthBusinessCheckTagListProps\r\n });\r\n }\r\n }\r\n };\r\n</script>\r\n```\r\n\r\n:::\r\n\r\n- 参数值类型如下 `Attributes`, 举个栗子 🌰\r\n\r\n```typescript\r\nthis.$pageStack.requestPageResult('WsShineTagSelect', {name: 'WsTagSelectPage'}, {\r\n /** 是否显示筛选条件 */\r\n isRadioGroup: true,\r\n /** 是否标签组 */\r\n isTagGroups: true,\r\n /** 是否同时存在筛选条件和标签组 (只客户标签使用) */\r\n hasRadioGroupAndTagGroup: true,\r\n /** radio - 回显 */\r\n radioProps: this.tagList.radio,\r\n /** 是否显示筛选条件 */\r\n corpCheckTagListProps: this.tagList.cropTagList?.map(tag => tag.tagId),\r\n /** 选中业务标签 - 回显 */\r\n businessCheckTagListProps: this.tagList.businessTagList?.map(tag => tag.tagId),\r\n /** 选中无权限业务标签 - 回显 */\r\n noAuthBusinessCheckTagListProps: this.tagList.noAuthBusinessTagList?.map(tag => tag.tagId)\r\n});\r\n```\r\n\r\n### Attributes\r\n\r\n| 参数名 | 说明 | 类型 | 默认值 | 可选值 |\r\n|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|----------|----------------|\r\n| title | 页面标题 | String | 选择标签 | - |\r\n| limit | 标签选择的限制 | Number | - | - |\r\n| isRadioGroup | 是否显示筛选条件 | Boolean | false | - |\r\n| type | 业务标识<br>`客户群标签: group`<br>`业务标签: business` | TagType | business | group,business |\r\n| groupDisabledTagListProps | 禁止选中客户群标签 | Array<Tag['tagId']> | [] | - |\r\n| submitText | 底部确定按钮文案 | String | 确定 | - |\r\n| isFilterAutoTagEdit | 自动标签区域仅展示已选的自动标签,且不可以编辑 | Boolean | false | - |\r\n| isTagGroups | 是否标签组 | Boolean | false | - |\r\n| hasRadioGroupAndTagGroup | (v3.0.9支持)\t是否同时存在筛选条件和标签组 (只能在类型为业务标签时使用: type = business) | Boolean | false | - |\r\n| radioGroupConfig | (v3.0.11支持) 标签关系(且,或,无,同组或,异组且)配置项,可自行编排后传入 (只能在类型为业务标签时使用: type = business) | Array\\<{ text: string, value: number, hidden?: boolean, disabled?: boolean }\\> | - | - |\r\n| radioGroupDisabled | (v3.0.11支持) 标签关系(且,或,无,同组或,异组且)是否禁用切换 | boolean | false | - |\r\n| radioGroupDisabledTips | (v3.0.11支持) 标签关系(且,或,无,同组或,异组且)禁用后的点击的提示文案 | string | '' | - |\r\n| isDemo | 展示 demo 数据(目前客户列表业务使用) | Boolean | false | - |\r\n| isFilterAuto | 自动标签 - 业务标签业务接口配置字段 | Boolean | false | - |\r\n| isToppingAuto | 置顶自动标签 - 业务标签业务接口配置字段(禁止使用,默认不需要) | Boolean | false | - |\r\n| isRestoreType | 是否还原标签 - 配置该属性清空选中标签数据. 反之恢复上一次数据, 也就是开发进入页面携带的数据, 如配置为true,底部按钮文案是'还原', 反之是'重置' | Boolean | false | - |\r\n| isFilterBusinessTag | 是否过滤业务标签 - 业务标签业务接口配置字段 | Boolean | false | - |\r\n| businessTagRange | 业务标签查询范围 - 业务标签业务接口配置字段<br>`0: 占位符,无其他作用`<br>`1: 我是管理员“的规则组标签`<br>`2: 我所在管理组的 规则组标签`<br>`3: 全部管理组的业务标签`<br>`4: 带权限查询全部管理组标签` | Number | 0 | 0,1,2,3,4 |\r\n| isFooterTipsText | 是否展示选中文案提示 | Boolean | true | - |\r\n| userId | 查询 userId 管理组业务标签 | String | - | - |\r\n| radioProps | radio - 回显 | TagRadioType | - | 1,2,3 |\r\n| groupCheckTagListProps | 选中客户群标签 - 回显 | Array<Tag['tagId']> | [] | - |\r\n| corpCheckTagListProps | 选中企业标签 - 回显 | Array<Tag['tagId']> | [] | - |\r\n| businessCheckTagListProps | 选中业务标签(有权限+无权限) - 回显 | Array<TagList['tagId']> | [] | - |\r\n| noAuthBusinessCheckTagListProps | 选中无权限业务标签 - 回显(群发使用-涉及到旧数据,停止使用,统一使用**businessCheckTagListProps**传值) | Array<TagList['tagId']> | [] | - |\r\n| selectedNoAuthBusinessTagList | 无权限业务标签 | Array\\<selectedNoAuthBusinessTagListTypes\\> | [] | - |\r\n| isFilterInnerTag | 是否过滤内部标签(某些场景下,需要单独过滤内部标签,例如群发朋友圈) | Boolean | false | - |\r\n| usage | 标签场景(MARK_TAG: 打标签,SEARCH:搜索标签),默认为搜索标签场景 | String | SEARCH | - |\r\n| selectedNoAuthInnerTagList | 无权限的内部标签 - 回显 | Array\\<selectedNoAuthInnerTagListTypes\\> | [] | - |\r\n| platform | 用于处理群发等特殊筛选场景,后端通过该值处理(SCRM:群发等特殊场景,其余默认为空字符串) | string | '' | 'SCRM','' |\r\n\r\n### Tag 数据结构\r\n\r\n| 键名 | 说明 | 类型 |\r\n|---------|------------------------------------------|----------|\r\n| tagId | 标签 id | string |\r\n| tagName | 标签名称 | string |\r\n| order | 标签组排序的次序值,order 值大的排序靠前。有效的值范围是[0, 2^32) | number |\r\n\r\n### TagList 数据结构\r\n\r\n> TagList 数据类型是在 Tag 基础上扩展\r\n\r\n| 键名 | 说明 | 类型 |\r\n|------------|------------------------------------------|----------|\r\n| tagId | 标签 id | string |\r\n| tagName | 标签名称 | string |\r\n| order | 标签组排序的次序值,order 值大的排序靠前。有效的值范围是[0, 2^32) | number |\r\n| createTime | 标签组创建时间 | string |\r\n\r\n\r\n### selectedNoAuthInnerTagListTypes 数据结构\r\n\r\n> selectedNoAuthInnerTagListTypes 数据类型是在 Tag 基础上扩展\r\n\r\n| 键名 | 说明 | 类型 |\r\n|------------|------------------------------------------|----------|\r\n| tagId | 标签 id | string |\r\n| tagName | 标签名称 | string |\r\n| tagGroupName | 标签组名称 | string |\r\n\r\n注意:\r\n\r\n- `type` 不同请求接口也不同, 如下:\r\n - 客户群标签: `group`\r\n\r\n ```typescript\r\n export const getGroupTagsApi = params => {\r\n return service.request({\r\n url: '/v3/company-server/groupTag/pagelist',\r\n method: 'post',\r\n data: params\r\n });\r\n };\r\n\r\n // 数据 types\r\n export interface groupDataTypes {\r\n groupId: string;\r\n groupName: string;\r\n mainDepartment: string;\r\n tagList: Tag[];\r\n userId: string;\r\n /**\r\n * 由 props isDemo 业务扩展,无其他作用\r\n */\r\n tagGroupName?: string;\r\n }\r\n /**\r\n * 群标签列表 数据类型\r\n */\r\n export interface getGroupTagsTypes {\r\n data: groupDataTypes[];\r\n }\r\n ```\r\n\r\n - 业务标签: `business`\r\n\r\n ```typescript\r\n export const getGroupTagsApi = params => {\r\n return service.request({\r\n url: '/v3/company-server/groupTag/pagelist',\r\n method: 'post',\r\n data: params\r\n });\r\n };\r\n\r\n // 数据 types\r\n /** 标签基础类型 */\r\n export interface Tag {\r\n /** 标签id */\r\n tagId: string;\r\n /** 标签名称 */\r\n tagName: string;\r\n /** 标签组排序的次序值,order值大的排序靠前。有效的值范围是[0, 2^32) */\r\n order?: number;\r\n }\r\n export interface CorpTagList {\r\n createTime: string;\r\n tagGroupId: string;\r\n createUser: string;\r\n order: number;\r\n tagList: Tag[];\r\n tagGroupName: string;\r\n }\r\n export interface BusinessTag {\r\n /** 标签组id */\r\n tagGroupId: string;\r\n /** 标签组名称 */\r\n tagGroupName: string;\r\n /** 标签组创建时间 */\r\n createTime: string;\r\n /** 规则组id */\r\n strategyId: string;\r\n /** 标签组内的标签列表 */\r\n tagList: TagList[];\r\n /** 标签组排序的次序值,order值大的排序靠前。有效的值范围是[0, 2^32) */\r\n order: number;\r\n }\r\n export interface BusinessTagList {\r\n /** 标签列表 */\r\n businessTags: BusinessTag[];\r\n /** 管理组名称 */\r\n authGroupName: string;\r\n /** 管理组Id */\r\n authGroupId: string;\r\n /** 规则组id */\r\n strategyId: string;\r\n }\r\n /**\r\n * 获取企业标签和业务标签 数据类型\r\n */\r\n export interface getCorpTagsAndBusinessTagsTypes {\r\n code: string;\r\n msg: string;\r\n data: {\r\n /** 业务标签 */\r\n businessTagList: BusinessTagList[];\r\n /** 企业标签 */\r\n corpTagList: CorpTagList[];\r\n /** 无权限业务标签 */\r\n noAuthBusinessTagList: BusinessTagList[];\r\n };\r\n }\r\n ```\r\n\r\n- `isDemo` 字段比较特殊, 数据来源于假数据 `src\\views\\noviceGuide\\config\\customerDetail.ts` `customerTagListDemo`,\r\n 业务使用在于客户列表-示例\r\n- 讲解下组件存在两处过滤自动标签字段: `isFilterAutoTagEdit` `isFilterAuto`\r\n - `isFilterAutoTagEdit`: 属于业务处理,如下三种情况\r\n 1. 展示自动标签(已选中), 不可以编辑 - 业务使用于`打标签(客户列表详情)`\r\n 2. 不需要展示自动标签(配置`isFilterAuto`为`false`) - 业务使用于`打标签(活码)`\r\n 3. 全部展示 - 业务使用于`列表(客户列表-筛选)`\r\n - `isFilterAuto`: 在传递组件类型为业务标签(`business`)接口配置项,也就是在数据层过滤的数据"
}
]
}

posted @ 2024-11-04 18:09  ____chen  阅读(85)  评论(0)    收藏  举报