一、场景与 API 定位
在元服务开发中,拨打电话是很常见的需求,例如客服页面一键拨号、紧急联系人快捷拨打。ASCF 提供了 has.makePhoneCall,用来拉起系统拨号界面。它的调用方式很简单,但行为边界和回调时机需要提前理解。
调用后不会直接自动拨出电话,而是进入系统拨号界面,用户确认后才真正拨打。参数上只需要一个 phoneNumber,必填,字符串类型;success、fail、complete 三个回调都是可选的。
基本用法如下:
- has.makePhoneCall({
- phoneNumber: '10086',
- success: () => {
- console.info('拨号成功');
- },
- fail: (err) => {
- console.error('拨号失败:', err);
- }
- });
复制代码
二、典型业务场景落地
场景一:客服热线。固定号码,用户点一下即拨。
- Page({
- callCustomerService() {
- has.makePhoneCall({
- phoneNumber: '400-123-4567',
- success: () => {
- console.info('正在拨打客服电话');
- },
- fail: (err) => {
- console.error('拨打失败:', err);
- }
- });
- }
- });
复制代码
场景二:从联系人列表中选择拨打。列表里每个联系人旁边放一个拨号按钮,通过 data-index 传递索引,再取出对应号码。
- Page({
- data: {
- contacts: [
- { name: '张三', phone: '13800138001' },
- { name: '李四', phone: '13900139002' },
- { name: '王五', phone: '15000150003' }
- ]
- },
- callContact(e) {
- const index = e.currentTarget.dataset.index;
- const contact = this.data.contacts[index];
- has.makePhoneCall({
- phoneNumber: contact.phone,
- success: () => {
- console.info('正在拨打:', contact.name);
- },
- fail: (err) => {
- console.error('拨打失败:', err);
- }
- });
- }
- });
复制代码
模板中可以这样写:
- <view class='contact-item' for='{{contacts}}'>
- <text>{{$item.name}} - {{$item.phone}}</text>
- <button size='mini' type='primary' data-index='{{$idx}}' bindtap='callContact'>拨打</button>
- </view>
复制代码
场景三:拨打前确认。紧急电话或收费电话等场景,有些产品会希望先弹确认框。不过 ASCF 拉起系统拨号界面时本身就会让用户确认,所以是否额外加确认,要看产品需求。
把输入拨号、快捷号码、拨打历史整合起来,可以得到一个较完整的 Demo:
- Page({
- data: {
- phoneNumber: '',
- callHistory: [],
- quickNumbers: [
- { name: '客服热线', phone: '400-123-4567' },
- { name: '技术支持', phone: '400-789-1234' },
- { name: '投诉建议', phone: '400-567-8901' }
- ]
- },
- onInput(e) {
- this.setData({ phoneNumber: e.detail.value });
- },
- dialNumber() {
- const phone = this.data.phoneNumber.trim();
- if (!phone) return;
- this.makeCall(phone);
- },
- dialQuick(e) {
- const index = e.currentTarget.dataset.index;
- const item = this.data.quickNumbers[index];
- this.makeCall(item.phone);
- },
- makeCall(phoneNumber) {
- let that = this;
- has.makePhoneCall({
- phoneNumber: phoneNumber,
- success: () => {
- console.info('拨号成功:', phoneNumber);
- that.addCallHistory(phoneNumber);
- },
- fail: (err) => {
- console.error('拨号失败:', err);
- },
- complete: () => {
- console.info('拨号接口调用完成');
- }
- });
- },
- addCallHistory(phone) {
- let history = this.data.callHistory;
- history = history.filter(item => item !== phone);
- history.unshift(phone);
- if (history.length > 10) {
- history.pop();
- }
- this.setData({ callHistory: history });
- },
- dialHistory(e) {
- const index = e.currentTarget.dataset.index;
- const phone = this.data.callHistory[index];
- this.makeCall(phone);
- }
- });
复制代码
三、回调行为与真机排障
号码格式方面,phoneNumber 直接传字符串即可,不需要特殊格式。带横线、带加号、带空格都可以,系统拨号界面会自动处理,例如 +86 138-0013-8001 和 13800138001 都能正常拨打。
fail 回调的触发条件容易误解。用户在系统拨号界面取消返回时,不会触发 fail,success 仍然会触发。fail 只在接口本身调用失败时触发,比如参数错误、系统不支持等。
complete 会在 success 或 fail 之后执行,适合做清理工作。但要注意,它是在拉起拨号界面后就触发,不是等用户打完电话才触发。也就是说,通过这个 API 无法知道用户到底有没有真的拨出去。
模拟器上这个 API 基本没法工作,因为它依赖系统的拨号能力,调试时需要真机验证。
如果页面上有输入框让用户输入号码,拨打完成后要记得清理输入框,或者做防重复点击处理,否则用户连点两下可能拉起两次拨号界面。
版本方面,这个 API 起始版本是 1.0.0,基本不用担心兼容性问题。如果元服务同时需要拨打电话和发送短信,ASCF 目前没有短信 API,需要借助系统能力或其他方式实现。
四、与联系人 API 配合
ASCF 还有联系人相关能力,has.addPhoneContact 可以添加联系人。如果需要“拨打 + 保存联系人”的完整流程,可以把两个 API 结合起来。例如拨打成功后提示用户是否保存到通讯录:
- has.makePhoneCall({
- phoneNumber: '13800138001',
- success: () => {
- console.info('是否需要保存到通讯录?');
- }
- });
复制代码
五、小结
has.makePhoneCall 的调用门槛很低,但真正落地时,success、fail、complete 的语义、模拟器限制、真机调试、重复点击处理都值得注意。业务上不要把它当成通话结果回调;需要保存联系人时结合 has.addPhoneContact;短信能力则要另找方案。 |