From 9312eceb94a581b82d681666036ab6883e2a9b43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=9D=E5=BF=83?= <13773726377@163.com>
Date: Thu, 2 Apr 2026 11:37:09 +0800
Subject: [PATCH] 1
---
src/components/ContactSelectModal.vue | 284 ++++++++++++++++++++++---
src/components/petOrder/call-modal.vue | 222 +++++++++++++++++--
2 files changed, 457 insertions(+), 49 deletions(-)
diff --git a/src/components/ContactSelectModal.vue b/src/components/ContactSelectModal.vue
index db3a6e8..440101c 100644
--- a/src/components/ContactSelectModal.vue
+++ b/src/components/ContactSelectModal.vue
@@ -7,7 +7,7 @@
-
+
+
+
+
+
+ 隐私保护提示
+
+ 请阅读并同意
+ 《用户隐私保护协议》
+ 后,方可使用拨打电话功能
+
+
+
+
+
@@ -80,19 +102,37 @@ export default {
}
},
emits: ['close', 'phoneCall', 'imSuccess', 'imError', 'onlineConsult'],
+ data() {
+ return {
+ showPrivacyModal: false, // 隐私协议弹窗显示状态
+ pendingPhoneNumber: null // 暂存的待拨打的号码
+ }
+ },
+ watch: {
+ // 监听弹窗关闭,重置隐私弹窗状态
+ visible(newVal) {
+ if (!newVal) {
+ this.showPrivacyModal = false
+ this.pendingPhoneNumber = null
+ }
+ }
+ },
methods: {
handleClose() {
this.$emit('close')
},
+
handleOnlineConsult() {
this.$emit('onlineConsult')
this.$emit('close')
},
+
imCallback(e) {
console.log('跳转IM客服成功', e.detail)
this.$emit('imSuccess', e)
this.$emit('close')
},
+
onimError(e) {
console.log('拉起IM客服失败', e.detail)
this.$emit('imError', e)
@@ -101,47 +141,153 @@ export default {
icon: 'none'
})
},
- handlePhoneCall() {
- this.$emit('phoneCall', this.servicePhone)
- this.$emit('close')
+
+ // ========== 隐私协议相关方法 ==========
+
+ // 打开隐私协议详情
+ openPrivacyContract() {
+ // #ifdef MP-TOUTIAO
+ tt.openPrivacyContract({
+ fail: (err) => {
+ console.error('打开隐私协议失败', err)
+ uni.showToast({
+ title: '无法打开协议',
+ icon: 'none'
+ })
+ }
+ })
+ // #endif
- if (this.servicePhone) {
- // 抖音小程序拨打电话
- uni.makePhoneCall({
- phoneNumber: this.servicePhone,
- success: () => {
- console.log('拨打电话成功')
- },
- fail: (err) => {
- console.error('拨打电话失败', err)
- // 失败时显示客服电话供用户手动拨打
- uni.showModal({
- title: '客服电话',
- content: this.servicePhone,
- confirmText: '复制',
- cancelText: '知道了',
- success: (res) => {
- if (res.confirm) {
- uni.setClipboardData({
- data: this.servicePhone,
- success: () => {
- uni.showToast({
- title: '电话已复制',
- icon: 'success'
- })
- }
- })
- }
- }
- })
+ // #ifndef MP-TOUTIAO
+ uni.showToast({
+ title: '请在设置中查看隐私协议',
+ icon: 'none'
+ })
+ // #endif
+ },
+
+ // 用户同意隐私协议
+ onAgreePrivacy(e) {
+ console.log('用户已同意隐私协议', e)
+ this.showPrivacyModal = false
+ uni.showToast({
+ title: '已授权',
+ icon: 'success'
+ })
+ // 同意后,执行之前暂存的拨号请求
+ if (this.pendingPhoneNumber) {
+ this.doMakePhoneCall(this.pendingPhoneNumber)
+ this.pendingPhoneNumber = null
+ }
+ },
+
+ // 用户拒绝隐私协议
+ onDisagreePrivacy() {
+ this.showPrivacyModal = false
+ this.pendingPhoneNumber = null
+ uni.showToast({
+ title: '未授权,无法使用拨号功能',
+ icon: 'none'
+ })
+ },
+
+ // 检查隐私授权状态(抖音专用)
+ checkPrivacyAuthorization(phoneNumber, callback) {
+ // #ifdef MP-TOUTIAO
+ tt.getPrivacySetting({
+ success: (res) => {
+ console.log('隐私授权状态:', res)
+ if (res.needAuthorization) {
+ // 未授权,显示隐私弹窗,并暂存电话号码
+ this.pendingPhoneNumber = phoneNumber
+ this.showPrivacyModal = true
+ callback && callback(false)
+ } else {
+ // 已授权,直接拨号
+ callback && callback(true)
}
- })
- } else {
+ },
+ fail: (err) => {
+ console.error('获取隐私设置失败', err)
+ // 获取失败时,直接尝试拨号(降级处理)
+ callback && callback(true)
+ }
+ })
+ // #endif
+
+ // #ifndef MP-TOUTIAO
+ // 非抖音平台,直接拨号
+ callback && callback(true)
+ // #endif
+ },
+
+ // 实际拨号方法
+ doMakePhoneCall(phoneNumber) {
+ if (!phoneNumber) {
uni.showToast({
title: '客服电话暂未设置',
icon: 'none'
})
+ return
}
+
+ uni.makePhoneCall({
+ phoneNumber: phoneNumber,
+ success: () => {
+ console.log('拨打电话成功')
+ },
+ fail: (err) => {
+ console.error('拨打电话失败', err)
+ // 失败时显示客服电话供用户手动拨打
+ uni.showModal({
+ title: '客服电话',
+ content: phoneNumber,
+ confirmText: '复制',
+ cancelText: '知道了',
+ success: (res) => {
+ if (res.confirm) {
+ uni.setClipboardData({
+ data: phoneNumber,
+ success: () => {
+ uni.showToast({
+ title: '电话已复制',
+ icon: 'success'
+ })
+ }
+ })
+ }
+ }
+ })
+ }
+ })
+ },
+
+ // ========== 修改后的拨号入口 ==========
+
+ handlePhoneCall() {
+ const phoneNumber = this.servicePhone
+
+ // 先触发父组件的 phoneCall 事件
+ this.$emit('phoneCall', phoneNumber)
+
+ if (!phoneNumber) {
+ uni.showToast({
+ title: '客服电话暂未设置',
+ icon: 'none'
+ })
+ return
+ }
+
+ // 检查隐私授权状态后再拨号
+ this.checkPrivacyAuthorization(phoneNumber, (authorized) => {
+ if (authorized) {
+ this.doMakePhoneCall(phoneNumber)
+ }
+ // 未授权时,checkPrivacyAuthorization 已经显示了隐私弹窗
+ })
+
+ // 关闭选择弹窗
+ this.$emit('close')
}
}
}
@@ -271,4 +417,72 @@ export default {
}
}
}
+
+// ========== 隐私协议弹窗样式(新增) ==========
+.privacy-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10000;
+}
+
+.privacy-modal-content {
+ width: 560rpx;
+ background-color: #fff;
+ border-radius: 24rpx;
+ padding: 48rpx 32rpx 32rpx;
+ text-align: center;
+}
+
+.privacy-modal-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 24rpx;
+}
+
+.privacy-modal-text {
+ font-size: 28rpx;
+ color: #666;
+ line-height: 1.5;
+ margin-bottom: 40rpx;
+}
+
+.privacy-link {
+ color: #007aff;
+ text-decoration: underline;
+}
+
+.privacy-agree-btn {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: #fff;
+ border-radius: 48rpx;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 32rpx;
+ margin-bottom: 20rpx;
+
+ &::after {
+ border: none;
+ }
+}
+
+.privacy-cancel-btn {
+ background-color: #f5f5f5;
+ color: #666;
+ border-radius: 48rpx;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 32rpx;
+
+ &::after {
+ border: none;
+ }
+}
\ No newline at end of file
diff --git a/src/components/petOrder/call-modal.vue b/src/components/petOrder/call-modal.vue
index 4e6bf75..fb1a7d1 100644
--- a/src/components/petOrder/call-modal.vue
+++ b/src/components/petOrder/call-modal.vue
@@ -15,6 +15,28 @@
+
+
+
+
+ 隐私保护提示
+
+ 请阅读并同意
+ 《用户隐私保护协议》
+ 后,方可使用拨打电话功能
+
+
+
+
+
@@ -27,30 +49,134 @@ export default {
}
},
data() {
- return {};
+ return {
+ showPrivacyModal: false, // 隐私协议弹窗
+ pendingCall: false // 是否有待执行的拨号请求
+ };
},
methods: {
closeAction() {
+ this.showPrivacyModal = false
this.$emit('close');
},
- callAction() {
- if (this.phoneNumber) {
- uni.makePhoneCall({
- phoneNumber: this.phoneNumber,
- success: (res) => {
- console.log(res);
- this.$emit('close');
- },
- fail: (err) => {
- console.log(err);
+
+ // 打开隐私协议详情(供用户查看)
+ openPrivacyContract() {
+ // #ifdef MP-TOUTIAO
+ tt.openPrivacyContract({
+ fail: (err) => {
+ console.error('打开隐私协议失败', err)
+ uni.showToast({
+ title: '无法打开协议',
+ icon: 'none'
+ })
+ }
+ })
+ // #endif
+ },
+
+ // 用户同意隐私协议
+ onAgreePrivacy() {
+ console.log('用户已同意隐私协议')
+ this.showPrivacyModal = false
+ uni.showToast({
+ title: '已授权',
+ icon: 'success'
+ })
+ // 同意后执行拨号
+ this.doMakePhoneCall()
+ },
+
+ // 用户拒绝隐私协议
+ onDisagreePrivacy() {
+ this.showPrivacyModal = false
+ uni.showToast({
+ title: '未授权,无法拨号',
+ icon: 'none'
+ })
+ },
+
+ // 检查隐私授权状态
+ checkPrivacyAndCall() {
+ // #ifdef MP-TOUTIAO
+ tt.getPrivacySetting({
+ success: (res) => {
+ console.log('隐私授权状态:', res)
+ if (res.needAuthorization) {
+ // 未授权,显示隐私弹窗
+ this.showPrivacyModal = true
+ } else {
+ // 已授权,直接拨号
+ this.doMakePhoneCall()
}
- })
- } else {
+ },
+ fail: (err) => {
+ console.error('获取隐私设置失败', err)
+ // 降级处理:直接拨号
+ this.doMakePhoneCall()
+ }
+ })
+ // #endif
+
+ // #ifndef MP-TOUTIAO
+ // 非抖音平台直接拨号
+ this.doMakePhoneCall()
+ // #endif
+ },
+
+ // 实际拨号方法
+ doMakePhoneCall() {
+ if (!this.phoneNumber) {
uni.showToast({
title: '电话号码为空',
icon: 'none'
})
+ return;
}
+
+ uni.makePhoneCall({
+ phoneNumber: this.phoneNumber,
+ success: (res) => {
+ console.log('拨号成功', res);
+ this.$emit('close');
+ },
+ fail: (err) => {
+ console.error('拨号失败', err);
+ // 拨号失败时,让用户手动复制
+ uni.showModal({
+ title: '客服电话',
+ content: this.phoneNumber,
+ confirmText: '复制',
+ cancelText: '取消',
+ success: (res) => {
+ if (res.confirm) {
+ uni.setClipboardData({
+ data: this.phoneNumber,
+ success: () => {
+ uni.showToast({
+ title: '电话已复制',
+ icon: 'success'
+ })
+ }
+ })
+ }
+ }
+ })
+ }
+ });
+ },
+
+ callAction() {
+ if (!this.phoneNumber) {
+ uni.showToast({
+ title: '电话号码为空',
+ icon: 'none'
+ })
+ return;
+ }
+
+ // 检查隐私授权并拨号
+ this.checkPrivacyAndCall()
}
},
}
@@ -115,4 +241,72 @@ export default {
}
}
}
-
+
+// 隐私协议弹窗样式
+.privacy-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.6);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10000;
+}
+
+.privacy-modal-content {
+ width: 560rpx;
+ background-color: #fff;
+ border-radius: 24rpx;
+ padding: 48rpx 32rpx 32rpx;
+ text-align: center;
+}
+
+.privacy-modal-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 24rpx;
+}
+
+.privacy-modal-text {
+ font-size: 28rpx;
+ color: #666;
+ line-height: 1.5;
+ margin-bottom: 40rpx;
+}
+
+.privacy-link {
+ color: #007aff;
+ text-decoration: underline;
+}
+
+.privacy-agree-btn {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: #fff;
+ border-radius: 48rpx;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 32rpx;
+ margin-bottom: 20rpx;
+
+ &::after {
+ border: none;
+ }
+}
+
+.privacy-cancel-btn {
+ background-color: #f5f5f5;
+ color: #666;
+ border-radius: 48rpx;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 32rpx;
+
+ &::after {
+ border: none;
+ }
+}
+
\ No newline at end of file