| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- <?php
- /**
- * 重庆赤晓店信息科技有限公司
- * https://www.chixiaodian.com
- * Copyright (c) 2023 赤店商城 All rights reserved.
- */
- namespace app\modules\admin\models\mochat;
- use app\models\Option;
- use app\constants\OptionSetting;
- use app\models\AccountLog;
- use app\models\User;
- use app\models\SaasUser;
- use app\models\Cat;
- use app\models\Goods;
- use app\models\Supplier;
- use app\models\Attr;
- use app\models\AttrGroup;
- use app\modules\admin\models\GoodsForm;
- use app\models\GoodsCat;
- use app\models\Order;
- use app\models\OrderDetail;
- use app\models\Store;
- use app\models\common\CommonOrder;
- use app\modules\client\models\v1\BindForm;
- use app\modules\client\models\v1\ShareMoneyForm;
- use app\modules\client\models\OrderComplete;
- use app\models\UserShareLog;
- use app\models\Share;
- use app\models\UserShareMoney;
- use app\models\UserBindLog;
- use app\models\Level;
- use zmoyi\JuShuiTan\Auth\Auth;
- use zmoyi\JuShuiTan\Api\ApiRequest;
- use zmoyi\JuShuiTan\Api\Common\ServeHttp;
- use zmoyi\JuShuiTan\Api\Common\Util;
- use zmoyi\JuShuiTan\Api\Common\Client;
- use app\models\Coupon;
- use GuzzleHttp\Client as Clients;
- use GuzzleHttp\Exception\RequestException;
- use GuzzleHttp\Promise\PromiseInterface;
- use Psr\Http\Message\ResponseInterface;
- use app\modules\admin\models\WechatThirdForm;
- use app\jobs\MochatJob;
- use app\modules\admin\models\OrderListForm;
- class MochatForm extends Model
- {
- const MSG_TYPE_CLICK_STORE = 1;
- const MSG_TYPE_VIEW_GOODS = 2;
- const MSG_TYPE_SUBMIT_ORDER = 3;
- const MSG_TYPE_PAY_ORDER = 4;
- const MSG_TYPE_VIEW_COUPON = 5;
- const MSG_TYPE_GET_COUPON = 6;
-
- public static $confs = [];
- public $store_id;
-
- private static function sendRequest($type = 'get', $baseUrl = '', $url = '', array $options = []):array
- {
- $client = new Clients([
- 'timeout' => 3,
- 'base_uri' => $baseUrl,
- 'verify' => false,
- 'headers' => [
- 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
- ]
- ]);
- if($type == 'get'){
- $request = $client->requestAsync($type, $url, [
- 'query' => $options
- ]);
- }else{
- $request = $client->postAsync($url, [
- 'form_params' => $options
- ]);
- }
- $promise = $request->then(function (ResponseInterface $request) use ($url, $options) {
- $contents = $request->getBody()->getContents();
- debug_log(['ResponseInterface', $contents, $url, $options], __CLASS__ . '.log');
- return json_decode($contents, true);
- }, function (\Exception $exception) use ($url, $options) {
- if($exception instanceof RequestException){
- $contents = $exception->getResponse()->getBody()->getContents();
- debug_log(['RequestException', $contents, $url, $options], __CLASS__ . '.log');
- return json_decode($contents, true);
- }else{
- debug_log(['RequestException', 'ExceptionErr', $exception->getMessage()], __CLASS__ . '.log');
- \Yii::error([__METHOD__, __LINE__, $exception]);
- }
- });
- return $promise->wait();
- }
- public static function api($store_id = 0, $_a = '', $params = [], $action = '/cyy/auth/index', $type = 'post') {
- $config = self::conf($store_id);
- $baseUrl = $config['mochatUrl'];
- if($config['refresh_time'] < time()){
- $response = self::sendRequest('post', $baseUrl, $baseUrl . '/open-api/access_token/get', [
- 'corp_id' => $config['corp_id'],
- 'token' => $config['token'],
- ]);
- if(isset($response['code'])){
- if($response['code'] != 200){
- debug_log(['code!=200', 'access_token/get', $response, $store_id, $type], __CLASS__ . '.log');
- }else{
- $access_token = $response['data']['access_token'];
- $expires_in = $response['data']['expires_in'];
- self::setAccessToken($store_id, $access_token, $expires_in);
- $config['access_token'] = $access_token;
- }
- }else{
- return $response;
- }
- }
- $params['access_token'] || $params['access_token'] = $config['access_token'];
- $params['_a'] || $params['_a'] = $_a;
- $response = self::sendRequest($type, $baseUrl, $baseUrl . $action, $params);
- if(isset($response['code'])){
- if($response['code'] != 200){
- debug_log(['code!=200', $response, $store_id, $type, $action, $params], __CLASS__ . '.log');
- }else{
- $response['code'] = 0;
- }
- }
- return $response;
- }
- public static function conf($store_id = 0, $refresh = 0) {
- if(isset(self::$confs[$store_id]) && !$refresh){
- return self::$confs[$store_id];
- }
- $conf = Option::get(OptionSetting::MOCHAT_API, $store_id, 'store')['value'];
- if($conf){
- $conf = json_decode($conf, true);
- }else{
- $conf = [
- 'mochatUrl' => '',
- ];
- }
- self::$confs[$store_id] = $conf;
- return $conf;
- }
-
- public static function saveConf($store_id = 0, $config = []) {
- $config['refresh_time'] = $config['refresh_time'] < time() ? time() : $config['refresh_time'];
- $set = Option::set(OptionSetting::MOCHAT_API, json_encode($config), $store_id, 'store');
- self::conf($store_id, 1);
- return $set;
- }
- public static function getConf($store_id = 0, $key = '') {
- $config = self::conf($store_id);
- return $config[$key];
- }
- public static function setConf($store_id = 0, $key = '', $val = '') {
- $config = self::conf($store_id);
- if(is_string($key)){
- $key = [$key];
- $val = [$val];
- }
- foreach($key as $i => $item){
- $config[$item] = $val[$i];
- }
- return self::saveConf($store_id, $config);
- }
- public static function setConfCorpId($store_id = 0, $corp_id = '') {
- return self::setConf($store_id, 'corp_id', $corp_id);
- }
- public static function setAccessToken($store_id = 0, $access_token = '', $expires_in = '') {
- $refresh_time = time() + $expires_in;
- return self::setConf($store_id, ['access_token', 'refresh_time'], [$access_token, $refresh_time]);
- }
- public static function isopen($store_id = 0) {
- $isopen = self::getConf($store_id, 'isopen');
- return empty($isopen) ? 0 : 1;
- }
- public static function getUserByStoreSaasuser($store_id = 0, $saas_user = []) {
- $user = User::find()->where([
- 'store_id' => $store_id,
- 'binding' => $saas_user['mobile'],
- 'is_delete' => 0,
- ])->one();
- return $user;
- }
- public static function userToExternalUserid($store_id = 0, $user_id = 0) {
- if(empty($user_id)){
- return [
- 'code' => 1,
- 'msg' => '用户不存在',
- ];
- }
- $user = User::findOne($user_id);
- $saasUser = SaasUser::findOne(['mobile' => $user['binding']]);
- $phone = $saasUser ? $saasUser->mobile : '';
- $openid = $user ? $user->wechat_open_id : '';
- $unionid = $user ? $user->wechat_union_id : '';
- $contact = self::contactUnionidToExternalUserid($store_id, $phone, $openid, $unionid);
- return $contact;
- }
-
- public static function userInRoom($store_id = 317, $roomId = '', $user_id = '') {
- $contact = self::userToExternalUserid($store_id, $user_id);
- if($contact['code'] != 0){
- debug_log([__METHOD__, $contact], __CLASS__ . '.log');
- return false;
- }
- $wxExternalUserid = $contact['data']['wx_external_userid'];
- $roomMem = self::workRoomMembers($store_id, $roomId, 2);
- if($roomMem['code'] != 0){
- debug_log([__METHOD__, $roomMem], __CLASS__ . '.log');
- return false;
- }
- debug_log([__METHOD__, $wxExternalUserid, $roomMem['data']], __CLASS__ . '.log');
- // var_dump($roomMem['data'], $wxExternalUserid);die;
- foreach($roomMem['data'] as $item){
- if($item['wxExternalUserid'] == $wxExternalUserid){
- // var_dump($item);die;
- return true;
- }
- }
- return false;
- // return self::workInRoom($store_id, $roomId, $wxExternalUserid);
- }
-
-
-
- public static function sendMsg($queue = true, $store_id = 84, $type = 1, $saas_user_id = 0, $extData = []) {
- try{
- if(!self::isopen($store_id)){
- return;
- // throw new \Exception('未开启scrm功能' . $store_id);
- }
- if(!$saas_user_id){
- return;
- // throw new \Exception('$saas_user_id = 0' . $store_id);
- }
- // $queue = time();
- if($queue === 1 || $queue === true){
- $cacheK = func_get_args();
- $cacheV = cache()->get($cacheK);
- if($cacheV){
- debug_log([__FUNCTION__, '$cacheV', $cacheV], __CLASS__ . '.log');
- return;
- }
- cache()->set($cacheK, 1, 60);
-
- $queue = queue_push(new \app\jobs\mochat\SendMsgJob([
- 'queue_time' => time(),
- 'store_id' => $store_id,
- 'type' => $type,
- 'saas_user_id' => $saas_user_id,
- 'extData' => $extData,
- ]));
- debug_log(['sendMsg $queue', $queue], __CLASS__ . '.log');
- return $queue;
- }
- $queue_time = $queue;
- debug_log(['sendMsg', func_get_args()], __CLASS__ . '.log');
- $msgType = [
- self::MSG_TYPE_CLICK_STORE => '点击商城',
- self::MSG_TYPE_VIEW_GOODS => '浏览商品',
- self::MSG_TYPE_SUBMIT_ORDER => '下单商品',
- self::MSG_TYPE_PAY_ORDER => '购买商品',
- self::MSG_TYPE_VIEW_COUPON => '查看优惠券',
- self::MSG_TYPE_GET_COUPON => '领取优惠券',
- ];
- if(!isset($msgType[$type])){
- throw new \Exception('$type参数错误' . $type);
- }
- $saasUser = SaasUser::findOne($saas_user_id);
- $extData['goods_id'] && $goods = Goods::findOne($extData['goods_id']);
- $extData['coupon_id'] && $coupon = Coupon::findOne($extData['coupon_id']);
- $title = '用户' . $msgType[$type] . '提醒';
- $desc1 = [
- '客户名称:' . ($saasUser ? $saasUser->name : ''),
- $goods ? ('商品名称:' . $goods->name) : '',
- $coupon ? ('优惠券名称:' . $coupon->name) : '',
- '查看时间:' . date('Y-m-d H:i:s', $queue_time),
- ];
- $desc = '<div>' . implode('</div><div>', $desc1) . '</div>';
- $user = self::getUserByStoreSaasuser($store_id, $saasUser);
- $phone = $saasUser ? $saasUser->mobile : '';
- $openid = $user ? $user->wechat_open_id : '';
- $unionid = $user ? $user->wechat_union_id : '';
- $contact = self::contactUnionidToExternalUserid($store_id, $phone, $openid, $unionid);
- if($contact['code'] != 0){
- debug_log(['sendMsg contactUnionidToExternalUserid err', func_get_args(), $contact], __CLASS__ . '.log');
- // return $contact;
- }
- $wxExternalUserid = $contact['data']['wx_external_userid'];
- $sendMsg_wxUserId = self::getConf($store_id, 'sendMsg_wxUserId');
- $content =
- $title . "\n" .
- $desc . "\n";
- if(empty($wxExternalUserid)){
- $content =
- "【新客户提醒】\n" .
- "客户手机:" . $phone . "\n" .
- "————————\n" .
- $content;
- }else{
- $contactId = $contact['data']['contactId'];
- $agentId = self::getConf($store_id, 'agentId');
- $urlSidebar = self::getConf($store_id, 'mochatUrl_sidebar');
- $link = $urlSidebar . '/contact?agentId=' . $agentId . '&contactId=' . $contactId;
- $content .=
- "————————\n" .
- '<a href="' . $link . '">查看>></a>';
- self::contactAddFollow($store_id, $wxExternalUserid, implode(' ', $desc1), $title);
- }
- $res = self::employeeSendMsg($store_id, $content, $sendMsg_wxUserId);
-
- return $res;
- } catch (\Exception $ex) {
- \Yii::error($ex);
- return [
- 'code' => 1,
- 'msg' => $ex->getMessage(),
- ];
- }
- }
- public static function orderList($store_id, $wxExternalUserid = '', $roomId = '') {
- if($roomId){
- $cond = self::getRoomPhone($store_id, $roomId);
- }
- if($wxExternalUserid){
- $cond = self::getContactPhone($store_id, $wxExternalUserid);
- }
- if(empty($cond['mobiles']) && empty($cond['openids']) && empty($cond['unionids'])){
- return [
- 'code' => 1,
- 'msg' => '暂无数据',
- ];
- }
- $form = new OrderListForm();
- $form->setAttributes(all_params(), 0);
- $form->setAttributes($cond, 0);
- $form->store_id = $store_id;
- return $form->search();
- }
-
- public static function searchCond($details) {
- $res = [
- 'mobiles' => [],
- 'openids' => [],
- 'unionids' => [],
- ];
- foreach($details as $detail){
- if(!empty($detail['phone'])){
- $res['mobiles'][] = $detail['phone'];
- }
- if(!empty($detail['openid'])){
- $res['openids'][] = $detail['openid'];
- }
- if(!empty($detail['unionid'])){
- $res['unionids'][] = $detail['unionid'];
- }
- }
- return $res;
- }
-
- public static function getContactPhone($store_id = 317, $wxExternalUserids = []) {
- if(is_string($wxExternalUserids)){
- $wxExternalUserids = [$wxExternalUserids];
- }
- $list = [];
- foreach($wxExternalUserids as $wxExternalUserid){
- $detail = self::contactDetail($store_id, $wxExternalUserid);
- $list[] = $detail['data'];
- }
- return self::searchCond($list);
- }
-
- public static function getRoomPhone($store_id = 317, $roomId = '') {
- $res = self::workRoomMembers($store_id, $roomId);
- $list = [];
- if($res['data']){
- foreach($res['data'] as $item){
- $list[] = $item['wxExternalUserid'];
- }
- }
- return self::getContactPhone($store_id, $list);
- }
-
- public static function employeeList($store_id = 317, $name = null, $page = 1, $pageSize = 30) {
- $params = [
- 'page' => $page,
- 'pageSize' => $pageSize,
- ];
- $name && $params['name'] = $name;
- $res = self::api($store_id, '', $params, '/open-api/employee/list', 'get');
- return $res;
- }
-
- public static function contactList($store_id = 317) {
- $res = self::api($store_id, '', [], '/open-api/contact/list', 'get');
- var_dump($res);die;
- }
-
- public static function contactDetail($store_id = 317, $wxExternalUserid = '') {
- $res = self::api($store_id, '', [
- 'wxExternalUserid' => $wxExternalUserid,
- ], '/open-api/contact/detail', 'get');
- return $res;
- }
-
- public static function workRoomMembers($store_id = 317, $roomId = '', $status = 1, $type = 2) {
- $res = self::api($store_id, '', [
- 'roomId' => $roomId,
- 'status' => $status,
- 'type' => $type,
- ], '/open-api/workRoom/members', 'get');
- return $res;
- }
-
- public static function workRoomList($store_id = 317, $options = []) {
- $res = self::api($store_id, '', [
- 'page' => $options['page'] ?? 1,
- 'perPage' => $options['perPage'] ?? 30,
- ], '/open-api/workRoom/index', 'get');
- return $res;
- }
-
- public static function workInRoom($store_id = 317, $roomId = '', $wxExternalUserid = '') {
- $res = self::api($store_id, '', [
- 'wxExternalUserid' => $wxExternalUserid,
- 'roomId' => $roomId,
- ], '/open-api/contact/room', 'post');
- // var_dump($roomId, $wxExternalUserid, $res);die;
- if($res['code'] == 0){
- if($res['data'] && $res['data']['page']){
- return $res['data']['page']['total'] ? true : false;
- }
- }
- return false;
- }
-
- public static function contactUnionidToExternalUserid($store_id = 317, $phone = '', $openid = '', $unionid = '') {
- $res = self::api($store_id, '', [
- 'unionid' => $unionid,
- 'openid' => $openid,
- 'phone' => $phone,
- ], '/open-api/contact/unionidToExternalUserid', 'get');
- return $res;
- }
-
- public static function contactAddFollow($store_id = 317, $wxExternalUserid = '', $content = '', $eventName = '') {
- $res = self::api($store_id, '', [
- 'wxExternalUserid' => $wxExternalUserid,
- 'content' => $content,
- 'eventName' => $eventName,
- ], '/open-api/contact/addFollow');
- return $res;
- }
-
- public static function employeeSendMsg($store_id = 317, $content = '', $wxUserId = '', $msgType = 'text') {
- $params = [
- 'msgType' => $msgType,
- 'content' => $content,
- ];
- $wxUserId && $params['wxUserId'] = $wxUserId;
- $res = self::api($store_id, '', $params, '/open-api/employee/sendMsg');
- return $res;
- }
- }
|