| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- <?php
- namespace common\components;
- use bizGhs\custom\classes\CustomClass;
- use yii\db\ActiveRecord;
- use Yii;
- class push
- {
- // 消息类型
- const MSG_TYPE_ORDER = 'order'; // 订单消息
- const MSG_TYPE_LOGISTICS = 'logistics'; // 物流消息
- const MSG_TYPE_ACCOUNT = 'account'; // 账户消息
- const MSG_TYPE_WORK = 'work'; // 工作事项提醒
- const MSG_TYPE_SUBSCRIPTION = 'subscription'; // 订阅消息
- const SECRET = 'RIVATE_KEY_S^@VJDy7'; // 👈 与云函数中保持一致
- const GHS_URL = 'https://fc-mp-42d1a66f-2aec-4fc5-9d92-4d176bf3d337.next.bspapp.com/ghs/push'; // 配置地点--(服务空间ghs-uni-admin):云函数/云对象--函数/对象列表/uni-pushProxy
- const HD_URL = 'https://fc-mp-027cce01-d39a-4ed2-8b09-1f4ff43ec945.next.bspapp.com/hd/push'; // 配置地点--(服务空间hd-uni-admin):云函数/云对象--函数/对象列表/uni-pushProxy
- // 私有属性
- private $url = '';
- private $client = '';
- private $msgType = '';
- public function __construct($client, $msgType)
- {
- $this->client = $client;
- if ($client == 'ghs') {
- $this->url = self::GHS_URL;
- } else if ($client == 'hd') {
- $this->url = self::HD_URL;
- } else {
- throw new \Exception('client not found');
- }
- $this->msgType = $msgType;
- }
- /**
- * 实现部分厂商特定功能,包括仅部分厂商支持、不常用或厂商临时新增的功能(不依赖 uni-push,厂商文档支持的参数可直接使用)。
- * 例如:推送渠道 ID、消息分类(部分厂商未配置时可能被限量推送或静默推送,即静音且需下拉系统通知栏才可见通知内容)、通知栏富文本
- */
- public function getOptions($client)
- {
- if ($client == 'ghs') {
- return $this->initGhsOptions();
- }
- return $this->initHdOptions();
- }
- /**
- * 花店的厂商options
- * @return array
- */
- public function initHdOptions()
- {
- $optionsArr = [];
- switch ($this->msgType) {
- case self::MSG_TYPE_ORDER:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "142737" //小米后台申请的通知类别id -- https://admin.xmpush.xiaomi.com/zh_CN/channel/list?appId=2882303761520146676
- ],
- "HW" => [
- "/message/android/category" => "EXPRESS"
- ],
- "VV" => [
- "/category" => "ORDER"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_LOGISTICS:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "142737"
- ],
- "HW" => [
- "/message/android/category" => "EXPRESS"
- ],
- "VV" => [
- "/category" => "ORDER"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_ACCOUNT:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "143019"
- ],
- "HW" => [
- "/message/android/category" => "ACCOUNT"
- ],
- "VV" => [
- "/category" => "ACCOUNT"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_WORK:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "143018"
- ],
- "HW" => [
- "/message/android/category" => "WORK"
- ],
- "VV" => [
- "/category" => "TODO"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_SUBSCRIPTION:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "0" // TODO 暂无
- ],
- "HW" => [
- "/message/android/category" => "SUBSCRIPTION"
- ],
- "VV" => [
- "/category" => "SUBSCRIPTION"
- ],
- ]
- ];
- break;
- }
- // 【荣耀】
- $optionsArr["android"]["HO"] = [
- "/android/notification/importance" => "NORMAL"
- ];
- return $optionsArr;
- }
- /**
- * 批发商的厂商options
- * @return array
- */
- public function initGhsOptions()
- {
- $optionsArr = [];
- switch ($this->msgType) {
- case self::MSG_TYPE_ORDER:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "142743" //小米后台申请的通知类别id -- https://admin.xmpush.xiaomi.com/zh_CN/channel/list?appId=2882303761520146676
- ],
- "HW" => [
- "/message/android/category" => "EXPRESS"
- ],
- "VV" => [
- "/category" => "ORDER"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_LOGISTICS:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "142744"
- ],
- "HW" => [
- "/message/android/category" => "EXPRESS"
- ],
- "VV" => [
- "/category" => "ORDER"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_ACCOUNT:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "142895"
- ],
- "HW" => [
- "/message/android/category" => "ACCOUNT"
- ],
- "VV" => [
- "/category" => "ACCOUNT"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_WORK:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "142892"
- ],
- "HW" => [
- "/message/android/category" => "WORK"
- ],
- "VV" => [
- "/category" => "TODO"
- ],
- ]
- ];
- break;
- case self::MSG_TYPE_SUBSCRIPTION:
- $optionsArr = ["android" =>
- [
- "XM" => [
- "/extra.channel_id" => "0" // TODO 暂无
- ],
- "HW" => [
- "/message/android/category" => "SUBSCRIPTION"
- ],
- "VV" => [
- "/category" => "SUBSCRIPTION"
- ],
- ]
- ];
- break;
- }
- return $optionsArr;
- }
- /**
- * 向设备端发送通知
- * @param array $cids 设备ID
- * @param string $title 通知标题
- * @param string $content 通知内容
- * @param array $payload 通知的附加数据
- * @return bool|string 返回设备的响应
- * @throws \Exception 抛出异常
- */
- public function pushByCloud($cids, $title, $content, $payload = [])
- {
- $sign = md5($title . $content . self::SECRET);
- $optionsArr = $this->getOptions($this->client);
- // 测试环境的特殊处理
- if (getenv('YII_ENV') == 'dev') {
- $optionsArr["android"]["HW"]["/message/android/target_user_type"] = 1; //华为 -- 值为int 类型。1 表示华为测试消息,华为每个应用每日可发送该测试消息500条,此target_user_type 参数请勿发布至线上。
- $optionsArr["android"]["VV"]["/pushMode"] = 1; //VIVO -- 值为int 类型。0 表示正式推送;1 表示测试推送,不填默认为0。线上请勿使用测试推送
- $optionsArr["android"]["HO"]["/android/targetUserType"] = 1; //荣耀 -- 值为int 类型。1 表示测试推送,不填默认为0。荣耀每个应用每日可发送该测试消息1000条。此测试参数请勿发布至线上。
- }
- $data = [
- 'cid' => is_array($cids) ? $cids : [$cids],
- 'title' => $title,
- 'content' => $content,
- 'payload' => $payload,
- 'force_notification' => true, // true: 无论是离线推送还是在线推送,都自创建通知栏消息
- // 'force_notification' => false, // false: 客户端在线时不自动创建通知栏消息,需客户端自行处理(如弹窗或存入消息中心);离线时尝试厂商通道通知
- 'sign' => $sign,
- 'options' => $optionsArr
- ];
- $ch = curl_init($this->url);
- if ($ch === false) {
- throw new \Exception('Failed to initialize curl');
- }
- try {
- curl_setopt_array($ch, [
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_POST => true,
- CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
- CURLOPT_POSTFIELDS => json_encode($data),
- CURLOPT_TIMEOUT => 10,
- CURLOPT_CONNECTTIMEOUT => 10,
- ]);
- $response = curl_exec($ch);
- if ($response === false) {
- throw new \Exception('CURL Error: ' . curl_error($ch));
- }
- return $response;
- } finally {
- curl_close($ch);
- }
- }
- /**
- * 向供货商 APP 发送新订单通知
- * @param ActiveRecord $shop 供货商门店
- * @param ActiveRecord $cgShop 采购花店门店
- * @param ActiveRecord $order xhGhsOrder
- * @throws \Exception
- */
- public function ghsOrderMessage($shop, $cgShop, $order)
- {
- $appNotice = dict::getDict('appNotice');
- //app禁止通知
- if($appNotice == 0) {
- return [];
- }
- try {
- $allDevices = \bizGhs\device\classes\GhsDeviceClass::getAllByCondition(['shopId' => $shop->id, 'status' => 1]);
- $cids = array_column($allDevices, 'clientId');
- $title = '你有新的订单';
- $customId = $order->customId ?? 0;
- $custom = CustomClass::getById($customId, true);
- $customName = $custom->name ?? '';
- $actPrice = $order->actPrice ? floatval($order->actPrice) : 0;
- $content = $customName . ' ¥' . $actPrice;
- $payload = [
- "page" => "pagesOrder/detail",
- "params" => ["id" => $order->id]
- ];
- $this->pushByCloud($cids, $title, $content, $payload);
- } catch (\Exception $e) {
- Yii::error('向供货商 APP 发送新订单通知失败: ' . $e->getMessage());
- }
- }
- }
|