Kaynağa Gözat

推送集成

liyuan 2 hafta önce
ebeveyn
işleme
b96d4bd564

+ 3 - 1
.gitignore

@@ -11,7 +11,6 @@ yarn-error.log*
 tests/**/coverage/
 tests/e2e/reports
 selenium-debug.log
-unpackage/release/apk/
 # Editor directories and files
 .idea
 .vscode
@@ -25,3 +24,6 @@ unpackage/release/apk/
 yarn.lock
 
 /unpackage/cache/
+/unpackage/release/
+/unpackage/debug/
+/unpackage/dist/

+ 7 - 6
common/setting.js

@@ -9,12 +9,13 @@ module.exports = {
 	// 版本号
 	version: '1.0.0',
 	// 开发环境接口Url
-	// devUrl: 'http://192.168.8.118:1080',
-	devUrl: 'http://121.37.83.47:10004',
+	devUrl: 'http://192.168.8.103:1080',
+	// devUrl: 'https://lt.echepei.com/api',
+	// devUrl: 'http://localhost:1080',
 	// devUrl:'http://192.168.8.107:8099',
-	// 线上环境接口Url
-	prodUrl: 'http://121.37.83.47:10004',
-	// prodUrl: 'http://192.168.8.108:1080',
+	// 线上环境接口Url
+	prodUrl: 'https://lt.echepei.com/api',
+	// prodUrl: 'http://192.168.8.103:1080',
 	// 后端数据的接收方式application/json;charset=UTF-8或者application/x-www-form-urlencoded;charset=UTF-8
 	contentType: 'application/json;charset=UTF-8',
 	// 后端返回状态码
@@ -27,4 +28,4 @@ module.exports = {
 	clientId: 'saber',
 	// 客户端密钥
 	clientSecret: 'saber_secret'
-}
+}

+ 6 - 2
main.js

@@ -14,13 +14,17 @@ Vue.use(uView)
 const vuexStore = require("@/store/$u.mixin.js");
 Vue.mixin(vuexStore);
 
-import '@/common/bluetooth.js';
+import pushUtil from './utils/push'
+
+Vue.prototype.$push = pushUtil;
+
+import '@/common/bluetooth.js';
 //全局数据状态管理 vuex
 // import store from '@/store/index.js';
 // Vue.prototype.$store = store;
 //全局公用静态数据
 import Mock from '@/common/mock/index.js';
-Vue.prototype.$Mock = Mock;
+Vue.prototype.$Mock = Mock;
 App.mpType = 'app'
 
 // 创建对象

+ 11 - 2
manifest.json

@@ -2,7 +2,7 @@
     "name" : "途宝即时配",
     "appid" : "__UNI__218FCF0",
     "description" : "",
-    "versionName" : "1.1.06",
+    "versionName" : "1.1.08",
     "versionCode" : 106,
     "transformPx" : false,
     "sassImplementationName" : "node-sass",
@@ -29,7 +29,8 @@
         "modules" : {
             "Maps" : {},
             "Bluetooth" : {},
-            "Camera" : {}
+            "Camera" : {},
+            "Push" : {}
         },
         /* 应用发布信息 */
         "distribute" : {
@@ -84,6 +85,14 @@
                         "appkey_ios" : "dd1af6068bd4db430b7eb17fd0213cb1",
                         "appkey_android" : "196959dbdb3fb268d1a6cae7e05a0dd3"
                     }
+                },
+                "push" : {
+                    "unipush" : {
+                        "version" : "2",
+                        "offline" : true,
+                        "honor" : {},
+                        "hms" : {}
+                    }
                 }
             },
             "icons" : {

+ 115 - 0
uniCloud-aliyun/cloudfunctions/uni-cloud-push/index.js

@@ -0,0 +1,115 @@
+'use strict';
+const uniPush = uniCloud.getPushManager({appId: "__UNI__218FCF0"});
+
+exports.main = async (event, context) => {
+    try {
+        // 1. 兼容不同调用方式的参数解析
+        let params = {};
+
+        if (event.body) {
+            // URL化调用:解析JSON字符串
+            try {
+                params = JSON.parse(event.body);
+            } catch (e) {
+                console.error('JSON解析失败:', e);
+                return {
+                    code: 400,
+                    message: '参数格式错误,JSON解析失败',
+                    error: e.message
+                };
+            }
+        } else {
+            // 本地调试或普通调用:直接使用event
+            params = event;
+        }
+
+        // 2. 参数解构(设置默认值)
+        const {
+            title = '默认标题',
+            content = '默认内容',
+            cId,
+            payload = {},
+            requestId = Date.now().toString(), // 自动生成requestId
+            isDev = false
+        } = params;
+
+        // 3. 必填参数校验
+        if (!cId) {
+            return {
+                code: 400,
+                message: 'cId 参数不能为空'
+            };
+        }
+
+        // 4. 构建厂商配置
+        const targetUserType = isDev ? 1 : 0;
+
+        const options = {
+            android: {
+                "HW": { // 华为配置
+                    "/message/android/target_user_type": targetUserType
+                },
+                "HO": { // 荣耀配置
+                    "/android/targetUserType": targetUserType
+                },
+                "VV": { // vivo配置
+                    "/pushMode": targetUserType
+                }
+            }
+        };
+
+        const xiaomiChannelId = params.xiaomiChannelId || "请填写您的channel_id";
+        if (xiaomiChannelId !== "请填写您的channel_id") {
+            options.android["XM"] = {
+                "/extra.channel_id": xiaomiChannelId
+            };
+        }
+
+        // 6. 执行推送
+        console.log('推送参数:', {
+            cId,
+            title,
+            content,
+            requestId,
+            isDev,
+            payload
+        });
+
+        const res = await uniPush.sendMessage({
+            push_clientid: cId,
+            title: title,
+            content: content,
+            payload: payload,
+            force_notification: true,
+            request_id: requestId,
+            options: options,
+            settings: {
+                // -1表示不设离线
+                ttl: -1,
+                strategy: {
+                    // 默认策略:1-在线走个推,离线走厂商;2-只走厂商;3-只走个推;4-优先厂商
+                    default: 4,
+                    // 备用策略
+                    st: 4
+                }
+            }
+        });
+
+        console.log('推送结果:', res);
+
+        return {
+            code: 0,
+            message: '推送成功',
+            data: res
+        };
+
+    } catch (error) {
+        console.error('推送失败:', error);
+        return {
+            code: 500,
+            message: '推送失败',
+            error: error.message,
+            stack: error.stack
+        };
+    }
+};

+ 7 - 0
uniCloud-aliyun/cloudfunctions/uni-cloud-push/package.json

@@ -0,0 +1,7 @@
+{
+  "name": "uni-cloud-push",
+  "dependencies": {},
+  "extensions": {
+    "uni-cloud-push": {}
+  }
+}

+ 8 - 0
uniCloud-aliyun/cloudfunctions/uni-cloud-push/uni-cloud-push.param.json

@@ -0,0 +1,8 @@
+// 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
+// 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/rundebug.html#runparam
+{
+    "title": "测试Api通知",
+    "content": "这是内容内容1111",
+    "cId": "753b9e9c1ffd14c6cde2cff8c6072ddb",
+    "isDev": true
+}

+ 12 - 0
uniCloud-aliyun/database/JQL查询.jql

@@ -0,0 +1,12 @@
+// 本文件用于,使用JQL语法操作项目关联的uniCloud空间的数据库,方便开发调试和远程数据库管理
+// 编写clientDB的js API(也支持常规js语法,比如var),可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法
+// 可以全部运行,也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码
+// 如果文档中存在多条JQL语句,只有最后一条语句生效
+// 如果混写了普通js,最后一条语句需是数据库操作语句
+// 此处代码运行不受DB Schema的权限控制,移植代码到实际业务中注意在schema中配好permission
+// 不支持clientDB的action
+// 数据库查询有最大返回条数限制,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-database.html#limit
+// 详细JQL语法,请参考:https://uniapp.dcloud.net.cn/uniCloud/jql.html
+
+// 下面示例查询uni-id-users表的所有数据
+db.collection('uni-id-users').get();

+ 113 - 0
utils/push.js

@@ -0,0 +1,113 @@
+import http from '@/http/api.js'
+
+/**
+ * 获取推送CID及设备信息
+ * @param {Boolean} showToast 是否显示错误提示,默认 true
+ * @returns {Promise<Object>} 返回 Promise,成功时 resolve({cid, platform, brand})
+ */
+const getPushCid = (showToast = true) => {
+    return new Promise((resolve, reject) => {
+        // 获取系统信息以得到平台和品牌
+        const systemInfo = uni.getSystemInfoSync();
+        const platform = systemInfo.platform;
+        // 手机品牌
+        const brand = systemInfo.brand || 'unknown';
+
+        uni.getPushClientId({
+            success: (res) => {
+                const cid = res.cid;
+                console.log('[PushUtil] 获取CID成功:', cid, '平台:', platform, '品牌:', brand);
+
+                // 存储到本地缓存
+                uni.setStorageSync('push_cid', cid);
+                uni.setStorageSync('push_platform', platform);
+                uni.setStorageSync('push_brand', brand);
+
+                // 返回包含设备信息的对象
+                resolve({
+                    cid: cid,
+                    platform: platform,
+                    brand: brand
+                });
+            },
+            fail: (err) => {
+                console.error('[PushUtil] 获取CID失败:', err);
+                // 如果需要弹窗提示(方便调试)
+                if (showToast) {
+                    uni.showModal({
+                        title: '提示',
+                        content: '获取推送标识失败,请确认已使用自定义基座运行。错误: ' + JSON.stringify(err),
+                        showCancel: false
+                    });
+                }
+                reject(err);
+            }
+        });
+    });
+};
+
+/**
+ * 将 CID 及设备信息上传到业务服务器
+ * @param {String} cid 设备标识
+ * @param {String} platform 平台信息
+ * @param {String} brand 设备品牌
+ */
+const uploadCidToServer = (cid, platform, brand) => {
+    if (!cid) {
+        console.warn('[PushUtil] CID为空,停止上传');
+        return Promise.reject('CID为空');
+    }
+
+    return new Promise((resolve, reject) => {
+        // 使用POST请求,将设备信息一起上传
+        http.request({
+            url: '/blade-sales-part/app/push/saveUserCid',
+            method: 'post',
+            data: {
+                cid: cid,
+                platform: platform || '',
+                deviceBrand: brand || ''
+            }
+        }).then(res => {
+            resolve(res);
+        }).catch(err => {
+            reject(err);
+        });
+    });
+};
+
+/**
+ * 完整的推送初始化流程(建议在App.vue调用)
+ * 获取CID并上传到服务器,包含平台和品牌信息
+ */
+const initPushService = (showToast = true) => {
+    getPushCid(showToast)
+        .then(deviceInfo => {
+            console.log('[PushUtil] 设备信息:', deviceInfo);
+            return uploadCidToServer(deviceInfo.cid, deviceInfo.platform, deviceInfo.brand);
+        })
+        .then(res => {
+            console.log('[PushUtil] 设备信息上传成功:', res);
+        })
+        .catch(err => {
+            console.error('[PushUtil] 推送服务初始化失败:', err);
+        });
+};
+
+/**
+ * 监听推送消息 (建议在 App.vue 调用一次)
+ */
+const onPushMessage = () => {
+    uni.onPushMessage((res) => {
+        console.log('[PushUtil] 收到推送消息:', res);
+        // 您可以在这里做一些全局处理,比如播放提示音、增加角标等
+    });
+};
+
+// 导出方法
+export default {
+    getPushCid,
+    uploadCidToServer,
+    initPushService,
+    onPushMessage
+};