Appearance
BizMessageCompose 消息发送面板
消息(站内信 / 短信 / 邮件 / 自定义渠道)发送编排面板:渠道选择 → 模板回填( 占位)→ 变量表单自动生成 → 实时渲染预览(短信含字数/计费条数)→ 人群选择(插槽接 BizTablePicker 等)→ 立即/定时发送。send 事件回传完整 payload(渠道 / 主题 / 渲染后内容 / 变量表 / 定时时间),业务侧拿去调发送接口——组件零接口。
适用于:运营后台群发通知、审批待办提醒、账单缴费提醒、值班通知等消息触达场景(接收侧见 BizNotificationCenter)。
基础用法
发送渠道
消息模板
选择模板回填内容(可清除后自由编辑)
主题*
消息内容*
0 / 500
效果预览
发送人群*
此处放人群选择组件(见「人群选择联动」示例)
发送时间
三渠道 + 模板 + 变量 + 预览 + 发送 payload 全链路(发送结果 JSON 展示)。
<script setup lang="ts">
/** 场景:基础用法——渠道/模板/变量/预览/发送 payload 全链路 */
import { ref } from 'vue'
import { BizMessageCompose } from 'vue3-ep-biz-lib'
import type { BizMessagePayload } from 'vue3-ep-biz-lib'
import { TEMPLATES } from './message-templates'
const loading = ref(false)
const payload = ref<string>('')
const onSend = (p: BizMessagePayload): void => {
loading.value = true
setTimeout(() => {
loading.value = false
payload.value = JSON.stringify(p, null, 2)
}, 600)
}
</script>
<template>
<el-space direction="vertical" size="large" style="width: 100%">
<BizMessageCompose
:templates="TEMPLATES"
:loading="loading"
@send="onSend"
>
<template #audience>
<el-alert type="info" :closable="false" title="此处放人群选择组件(见「人群选择联动」示例)" />
</template>
</BizMessageCompose>
<el-alert v-if="payload !== ''" type="success" :closable="false">
<pre style="margin: 0; font-size: 12px">{{ payload }}</pre>
</el-alert>
</el-space>
</template>
显示代码
变量联动
发送渠道
主题*
消息内容*
39 / 500
变量填写(3 个)
公司名
验证码
有效分钟
效果预览
【{{公司名}}】您的验证码为 {{验证码}},{{有效分钟}} 分钟内有效。
发送人群*
全部在线用户 直接在内容里写 {{变量名}} 占位即自动出变量表单;删掉占位对应表单项同步消失,预览未填变量原样保留便于发现缺口。
内容里的
占位自动出变量表单,增删占位表单项同步增减;预览实时替换,未填变量原样保留便于发现缺口。<script setup lang="ts">
/** 场景:变量联动——变量表单随内容占位自动增减,预览实时替换(未填保留占位) */
import { ref } from 'vue'
import { BizMessageCompose } from 'vue3-ep-biz-lib'
const payload = ref('')
</script>
<template>
<el-space direction="vertical" size="large" style="width: 100%">
<BizMessageCompose
:allow-schedule="false"
initial-content="【{{公司名}}】您的验证码为 {{验证码}},{{有效分钟}} 分钟内有效。"
@send="(p) => (payload = JSON.stringify(p.variables))"
>
<template #audience>
<el-tag>全部在线用户</el-tag>
</template>
</BizMessageCompose>
<p style="margin: 0; font-size: 13px; color: var(--el-text-color-secondary)">
直接在内容里写 <code v-pre>{{变量名}}</code> 占位即自动出变量表单;删掉占位对应表单项同步消失,预览未填变量原样保留便于发现缺口。
</p>
</el-space>
</template>
显示代码
人群选择联动
发送渠道
消息模板
选择模板回填内容(可清除后自由编辑)
主题*
消息内容*
0 / 500
效果预览
发送人群*
暂未选择
#audience 插槽放 BizTablePicker 选人;validate-audience 钩子拦截空人群。<script setup lang="ts">
/** 场景:人群选择联动——#audience 插槽 + BizTablePicker 选人 + validateAudience 拦截空人群 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizMessageCompose, BizTablePicker } from 'vue3-ep-biz-lib'
import { TEMPLATES } from './message-templates'
interface Staff {
[key: string]: unknown
id: number
name: string
dept: string
}
const staff: Staff[] = [
{ id: 1, name: '张伟', dept: '运维一部' },
{ id: 2, name: '王芳', dept: '运维一部' },
{ id: 3, name: '李娜', dept: '综合部' },
{ id: 4, name: '刘洋', dept: '综合部' },
{ id: 5, name: '陈静', dept: '安环部' },
]
const selected = ref<Staff[]>([])
/** 空人群拦截钩子 */
const validateAudience = (): true | string =>
selected.value.length > 0 ? true : '请选择发送人群'
const sending = ref(false)
const onSend = (): void => {
sending.value = true
setTimeout(() => {
sending.value = false
ElMessage.success(`已向 ${selected.value.length} 人发送`)
}, 600)
}
</script>
<template>
<BizMessageCompose
:templates="TEMPLATES"
:loading="sending"
:validate-audience="validateAudience"
:allow-schedule="false"
@send="onSend"
>
<template #audience>
<BizTablePicker
v-model="selected"
:data="staff"
row-key="id"
label-key="name"
multiple
button-text="选择人员"
:columns="[
{ prop: 'name', label: '姓名' },
{ prop: 'dept', label: '部门' },
]"
/>
</template>
</BizMessageCompose>
</template>
显示代码
定时发送
发送渠道
主题*
消息内容*
0 / 500
效果预览
发送人群*
华东大区全员发送时间
立即 / 定时切换 + 时间选择,payload 携带
scheduleAt(立即发送为 undefined)。<script setup lang="ts">
/** 场景:定时发送——立即/定时切换 + 时间选择,payload 携带 scheduleAt */
import { ref } from 'vue'
import { BizMessageCompose } from 'vue3-ep-biz-lib'
import type { BizMessagePayload } from 'vue3-ep-biz-lib'
const payload = ref('')
const onSend = (p: BizMessagePayload): void => {
payload.value = `渠道:${p.channel}|定时:${p.scheduleAt ?? '立即'}`
}
</script>
<template>
<el-space direction="vertical" size="large" style="width: 100%">
<BizMessageCompose
:channels="[{ key: 'inApp', label: '站内信' }]"
:allow-schedule="true"
@send="onSend"
>
<template #audience>
<el-tag>华东大区全员</el-tag>
</template>
</BizMessageCompose>
<el-alert v-if="payload !== ''" :title="payload" type="success" :closable="false" />
</el-space>
</template>
显示代码
短信计费提示
发送渠道
消息内容*
122 / 500
效果预览 122 字 · 2 条
尊敬的客户:您本月的服务账单已生成,账期 2026-10-01 至 2026-10-31,应缴金额 ¥1,268.00。请于 2026-11-10 前完成缴费,逾期将按合同约定计收违约金。如有疑问请联系客户经理或致电 400-000-0000。
发送人群*
已签约到期提醒客户 1,204 人sms 渠道实时显示「字数 · 拆分条数」(70 字内 1 条,超出按 67 字/条),运营改文案即见成本。
<script setup lang="ts">
/** 场景:短信计费提示——字数 / 拆分条数(70 字内 1 条,超出 67 字/条) */
import { BizMessageCompose } from 'vue3-ep-biz-lib'
const initial =
'尊敬的客户:您本月的服务账单已生成,账期 2026-10-01 至 2026-10-31,应缴金额 ¥1,268.00。请于 2026-11-10 前完成缴费,逾期将按合同约定计收违约金。如有疑问请联系客户经理或致电 400-000-0000。'
</script>
<template>
<BizMessageCompose
:channels="[{ key: 'sms', label: '短信' }]"
:initial-content="initial"
:allow-schedule="false"
:maxlength="500"
>
<template #audience>
<el-tag type="warning">已签约到期提醒客户 1,204 人</el-tag>
</template>
</BizMessageCompose>
</template>
显示代码
自定义渠道
发送渠道
消息内容*
34 / 500
变量填写(2 个)
负责人
电话
效果预览
【值班通知】今日值班负责人:{{负责人}},联系电话 {{电话}}。
发送人群*
运维值班群channels 传入钉钉 / 企微等任意渠道;no-subject-channels 声明无主题渠道(不出主题输入框)。<script setup lang="ts">
/** 场景:自定义渠道——钉钉/企微机器人等任意渠道 + 无主题渠道配置 */
import { ElMessage } from 'element-plus'
import { BizMessageCompose } from 'vue3-ep-biz-lib'
import type { BizMessagePayload } from 'vue3-ep-biz-lib'
const channels = [
{ key: 'dingtalk', label: '钉钉' },
{ key: 'wecom', label: '企业微信' },
]
const onSend = (p: BizMessagePayload): void => {
ElMessage.success(`已发送到 ${p.channel === 'dingtalk' ? '钉钉' : '企微'}:${p.content.slice(0, 20)}…`)
}
</script>
<template>
<BizMessageCompose
:channels="channels"
:no-subject-channels="['dingtalk', 'wecom']"
:allow-schedule="false"
initial-content="【值班通知】今日值班负责人:{{负责人}},联系电话 {{电话}}。"
@send="onSend"
>
<template #audience>
<el-tag>运维值班群</el-tag>
</template>
</BizMessageCompose>
</template>
显示代码
自由编辑(无模板)
发送渠道
主题*
消息内容*
0 / 200
效果预览
发送人群*
全体员工(326 人)不传
templates 自由编辑内容;maxlength 字数上限;send-text 定制按钮文案。<script setup lang="ts">
/** 场景:自由编辑(无模板)——不传 templates,maxlength 字数上限 + 邮件主题 */
import { ElMessage } from 'element-plus'
import { BizMessageCompose } from 'vue3-ep-biz-lib'
import type { BizMessagePayload } from 'vue3-ep-biz-lib'
const onSend = (p: BizMessagePayload): void => {
ElMessage.success(`邮件「${p.subject}」已发送(${p.content.length} 字)`)
}
</script>
<template>
<BizMessageCompose
:channels="[{ key: 'email', label: '邮件' }]"
:maxlength="200"
send-text="发送邮件"
:allow-schedule="false"
@send="onSend"
>
<template #audience>
<el-tag>全体员工(326 人)</el-tag>
</template>
</BizMessageCompose>
</template>
显示代码
弹窗内嵌
openBizDrawer 承载发送面板——通知中心「发通知」入口的典型形态。<script setup lang="ts">
/** 场景:弹窗内嵌——openBizDrawer 承载发送面板(通知中心「发通知」入口形态) */
import { defineComponent, h, ref } from 'vue'
import { ElButton, ElMessage, ElTag } from 'element-plus'
import { BizMessageCompose, openBizDrawer } from 'vue3-ep-biz-lib'
import type { BizMessagePayload } from 'vue3-ep-biz-lib'
import { TEMPLATES } from './message-templates'
/** 发送面板内容组件(发送成功提示后由使用方按需关闭) */
const ComposePanel = defineComponent({
name: 'ComposePanel',
setup() {
const loading = ref(false)
const onSend = (p: BizMessagePayload): void => {
loading.value = true
setTimeout(() => {
loading.value = false
ElMessage.success(`已发送(${p.channel})`)
}, 700)
}
return () =>
h(BizMessageCompose, { templates: TEMPLATES, loading: loading.value, onSend }, {
audience: () => h(ElTag, null, () => '全部用户'),
})
},
})
const open = (): void => {
openBizDrawer({
component: ComposePanel,
title: '发送通知',
size: 'small',
showConfirm: false,
cancelText: '关闭',
})
}
</script>
<template>
<ElButton type="primary" @click="open">发通知(滑窗)</ElButton>
</template>
显示代码
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| channels | BizMessageChannel[] | 站内信/短信/邮件 | 可用渠道({ key, label },key 可自定义) |
| templates | BizMessageTemplate[] | [] | 消息模板({ id, title, content },content 支持 ;不传则自由编辑) |
| no-subject-channels | string[] | ['sms'] | 无主题(不出主题输入框)的渠道 key |
| validate-audience | () => true | string | — | 人群校验钩子:返回文案拦截发送,true 放行 |
| allow-schedule | boolean | true | 允许定时发送(立即/定时选项) |
| initial-content | string | '' | 初始内容(草稿回填 / 预置 占位) |
| initial-content | string | '' | 初始内容(草稿回填 / 预置占位) |
| maxlength | number | 500 | 内容字符上限 |
| send-text | string | '发送' | 发送按钮文案 |
| loading | boolean | false | 发送中(按钮 loading) |
| show-sms-count | boolean | true | 短信字数/条数提示 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| send | (payload: BizMessagePayload) | 校验通过后的发送:{ channel, subject, content(变量已渲染), variables, scheduleAt? } |
Slots
| 插槽名 | 说明 |
|---|---|
| audience | 发送人群选择区(放 BizTablePicker / 部门选择等,配合 validate-audience 校验) |
| footer-extra | 发送按钮旁的附加操作(存草稿等) |
Expose
| 名称 | 类型 | 说明 |
|---|---|---|
| getPayload | () => BizMessagePayload | 组装 payload(不做校验,预检/草稿用) |
| setTemplate | (id: string) => void | 外部指定模板回填 |
| clear | () => void | 清空编辑态 |