Initial commit: queue workspace
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services\wechat\client\miniprogram;
|
||||
|
||||
|
||||
use crmeb\services\wechat\client\BaseClient;
|
||||
use crmeb\services\wechat\config\MiniProgramConfig;
|
||||
use crmeb\services\wechat\util\AES;
|
||||
use crmeb\services\wechat\WechatException;
|
||||
use EasyWeChat\Kernel\HttpClient\AccessTokenAwareClient;
|
||||
use EasyWeChat\Kernel\HttpClient\Response;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
use think\annotation\Inject;
|
||||
|
||||
/**
|
||||
* 授权
|
||||
* Class AuthClient
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
* @package crmeb\services\wechat\client\miniprogram
|
||||
*/
|
||||
class AuthClient extends BaseClient
|
||||
{
|
||||
|
||||
/**
|
||||
* @var MiniProgramConfig
|
||||
*/
|
||||
protected MiniProgramConfig $config;
|
||||
|
||||
/**
|
||||
* AuthClient constructor.
|
||||
* @param AccessTokenAwareClient $api
|
||||
*/
|
||||
public function __construct(AccessTokenAwareClient $api)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->config = app()->make(MiniProgramConfig::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用code换取用户信息
|
||||
* @param string $code
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function session(string $code): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'appid' => $this->config->appId,
|
||||
'secret' => $this->config->secret,
|
||||
'js_code' => $code,
|
||||
'grant_type' => 'authorization_code',
|
||||
];
|
||||
|
||||
return $this->api->get('sns/jscode2session', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密数据
|
||||
* @param string $sessionKey
|
||||
* @param string $iv
|
||||
* @param string $encrypted
|
||||
* @return array
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function decryptData(string $sessionKey, string $iv, string $encrypted): array
|
||||
{
|
||||
$decrypted = AES::decrypt(
|
||||
base64_decode($encrypted, false),
|
||||
base64_decode($sessionKey, false),
|
||||
base64_decode($iv, false)
|
||||
);
|
||||
|
||||
$decrypted = json_decode($decrypted, true);
|
||||
|
||||
if (!$decrypted) {
|
||||
throw new WechatException('The given payload is invalid.');
|
||||
}
|
||||
|
||||
return $decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序码:适用于需要的码数量极多,或仅临时使用的业务场景
|
||||
* @param string $scene
|
||||
* @param array $optional
|
||||
* @return Response
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getUnlimit(string $scene, array $optional = []): Response
|
||||
{
|
||||
$params = array_merge([
|
||||
'scene' => $scene,
|
||||
], $optional);
|
||||
|
||||
return $this->getStream('wxa/getwxacodeunlimit', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流文件
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @return Response
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
protected function getStream(string $endpoint, array $params): Response
|
||||
{
|
||||
return $this->api->request('POST', $endpoint, ['json' => $params]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序短链
|
||||
* @param string $path 通过 URL Link 进入的小程序页面路径,必须是已经发布的小程序存在的页面,不可携带 query 。path 为空时会跳转小程序主页
|
||||
* @param string $query 通过 URL Link 进入小程序时的query,最大1024个字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~%
|
||||
* @param int $expire_type 默认值0.小程序 URL Link 失效类型,失效时间:0,失效间隔天数:1
|
||||
* @param int $expire_time 到期失效的 URL Link 的失效时间,为 Unix 时间戳。生成的到期失效 URL Link 在该时间前有效。最长有效期为30天。expire_type 为 0 必填
|
||||
* @param int $expire_interval 到期失效的URL Link的失效间隔天数。生成的到期失效URL Link在该间隔时间到达前有效。最长间隔天数为30天。expire_type 为 1 必填
|
||||
* @throws TransportExceptionInterface User: liusl
|
||||
* DateTime: 2024/11/23 下午2:46
|
||||
*/
|
||||
public function generateUrlLink(string $path, string $query, int $expire_type = 0, int $expire_time = 30 * 24 * 3600, int $expire_interval = 29)
|
||||
{
|
||||
$params = [
|
||||
'path' => $path,
|
||||
'query' => $query,
|
||||
'expire_type' => $expire_type,
|
||||
];
|
||||
if ($expire_type == 0) {
|
||||
$params['expire_time'] = time() + $expire_time;
|
||||
} else {
|
||||
$params['expire_interval'] = $expire_interval;
|
||||
}
|
||||
return $this->api->postJson('wxa/generate_urllink', $params);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services\wechat\client\miniprogram;
|
||||
|
||||
|
||||
use crmeb\services\wechat\client\BaseClient;
|
||||
use EasyWeChat\Kernel\HttpClient\Response;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
|
||||
/**
|
||||
* 直播
|
||||
* Class LiveClient
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
* @package crmeb\services\wechat\client\miniprogram
|
||||
*/
|
||||
class LiveClient extends BaseClient
|
||||
{
|
||||
/**
|
||||
* 添加直播间参数
|
||||
* @var array
|
||||
*/
|
||||
protected array $createData = [
|
||||
'name' => '', // 房间名字
|
||||
'coverImg' => '', // 通过 uploadfile 上传,填写 mediaID
|
||||
'startTime' => 0, // 开始时间
|
||||
'endTime' => 0, // 结束时间
|
||||
'anchorName' => '', // 主播昵称
|
||||
'anchorWechat' => '', // 主播微信号
|
||||
'shareImg' => '', //通过 uploadfile 上传,填写 mediaID
|
||||
'feedsImg' => '', //通过 uploadfile 上传,填写 mediaID
|
||||
'isFeedsPublic' => 1, // 是否开启官方收录,1 开启,0 关闭
|
||||
'type' => 1, // 直播类型,1 推流 0 手机直播
|
||||
'screenType' => 0, // 1:横屏 0:竖屏
|
||||
'closeLike' => 0, // 是否 关闭点赞 1 关闭
|
||||
'closeGoods' => 0, // 是否 关闭商品货架,1:关闭
|
||||
'closeComment' => 0, // 是否开启评论,1:关闭
|
||||
'closeReplay' => 1, // 是否关闭回放 1 关闭
|
||||
'closeShare' => 0, // 是否关闭分享 1 关闭
|
||||
'closeKf' => 0 // 是否关闭客服,1 关闭
|
||||
];
|
||||
|
||||
/**
|
||||
* 获取直播房间
|
||||
* @param int $start
|
||||
* @param int $limit
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getRooms(int $start = 0, int $limit = 10): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'start' => $start,
|
||||
'limit' => $limit,
|
||||
];
|
||||
|
||||
return $this->api->postJson('wxa/business/getliveinfo', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取直播回放
|
||||
* @param int $roomId
|
||||
* @param int $start
|
||||
* @param int $limit
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getPlaybacks(int $roomId, int $start = 0, int $limit = 10): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'action' => 'get_replay',
|
||||
'room_id' => $roomId,
|
||||
'start' => $start,
|
||||
'limit' => $limit,
|
||||
];
|
||||
|
||||
return $this->api->postJson('wxa/business/getliveinfo', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建直播间
|
||||
* @param array $data
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function createRoom(array $data): ResponseInterface|Response
|
||||
{
|
||||
$params = array_merge($this->createData, $data);
|
||||
return $this->api->postJson('wxaapi/broadcast/room/create', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直播间导入商品
|
||||
* @param int $room_id
|
||||
* @param $ids
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function roomAddGoods(int $room_id, $ids): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'ids' => $ids,
|
||||
'roomId' => $room_id
|
||||
];
|
||||
return $this->api->postJson('wxaapi/broadcast/room/addgoods', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品列表信息
|
||||
* @param int $status
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getGoodsList(int $status, int $page = 0, int $limit = 30): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'offset' => $page * $limit,
|
||||
'limit' => $limit,
|
||||
'status' => $status
|
||||
];
|
||||
return $this->api->get('wxaapi/broadcast/goods/getapproved', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品详情
|
||||
* @param array $ids
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getGooodsInfo(array $ids): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'goods_ids' => $ids
|
||||
];
|
||||
return $this->api->get('wxa/business/getgoodswarehouse', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品添加并审核
|
||||
* @param string $coverImgUrl
|
||||
* @param string $name
|
||||
* @param int $priceType
|
||||
* @param string $url
|
||||
* @param string $price
|
||||
* @param string $price2
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function addGoods(string $coverImgUrl, string $name, int $priceType, string $url, string $price, string $price2 = ''): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'goodsInfo' => [
|
||||
'coverImgUrl' => $coverImgUrl,
|
||||
'name' => $name,
|
||||
'priceType' => $priceType,
|
||||
'price' => $price,
|
||||
'url' => $url
|
||||
]
|
||||
];
|
||||
if ($priceType != 1) $params['goodsInfo']['price2'] = $price2;
|
||||
return $this->api->postJson('wxaapi/broadcast/goods/add', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回审核
|
||||
* @param int $goodsId
|
||||
* @param int $auditId
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function resetauditGoods(int $goodsId, int $auditId): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'goodsId' => $goodsId,
|
||||
'auditId' => $auditId
|
||||
];
|
||||
return $this->api->postJson('wxaapi/broadcast/goods/resetaudit', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新提交审核
|
||||
* @param int $goodsId
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function auditGoods(int $goodsId): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'goodsId' => $goodsId
|
||||
];
|
||||
return $this->api->postJson('wxaapi/broadcast/goods/autdit', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
* @param int $goodsId
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function deleteGoods(int $goodsId): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'goodsId' => $goodsId
|
||||
];
|
||||
return $this->api->postJson('wxaapi/broadcast/goods/delete', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品
|
||||
* @param int $goodsId
|
||||
* @param string $coverImgUrl
|
||||
* @param string $name
|
||||
* @param int $priceType
|
||||
* @param string $url
|
||||
* @param string $price
|
||||
* @param string $price2
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function updateGoods(int $goodsId, string $coverImgUrl, string $name, int $priceType, string $url, string $price, string $price2 = ''): ResponseInterface|Response
|
||||
{
|
||||
$params = ['goodsInfo' => [
|
||||
'goodsId' => $goodsId,
|
||||
'coverImgUrl' => $coverImgUrl,
|
||||
'name' => $name,
|
||||
'priceType' => $priceType,
|
||||
'price' => $price,
|
||||
'url' => $url
|
||||
]];
|
||||
if ($priceType != 1) $params['goodsInfo']['price2'] = $price2;
|
||||
return $this->api->postJson('wxaapi/broadcast/goods/update', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员列表
|
||||
* @param int $role
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @param string $keyword
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getRoleList(int $role = 2, int $page = 0, int $limit = 30, string $keyword = ''): ResponseInterface|Response
|
||||
{
|
||||
$params = [
|
||||
'role' => $role,
|
||||
'offset' => $page * $limit,
|
||||
'limit' => $limit,
|
||||
'keyword' => $keyword
|
||||
];
|
||||
return $this->api->get('wxaapi/broadcast/role/getrolelist', $params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services\wechat\client\miniprogram;
|
||||
|
||||
|
||||
use crmeb\services\wechat\client\BaseClient;
|
||||
use crmeb\services\wechat\WechatException;
|
||||
use EasyWeChat\Kernel\HttpClient\Response;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
|
||||
/**
|
||||
* 附件
|
||||
* Class MaterialClient
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/26
|
||||
* @package crmeb\services\wechat\client\miniprogram
|
||||
*/
|
||||
class MaterialClient extends BaseClient
|
||||
{
|
||||
|
||||
/**
|
||||
* 附件类型
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $allowTypes = ['image', 'voice', 'video', 'thumb'];
|
||||
|
||||
/**
|
||||
* 上传
|
||||
* @param string $type
|
||||
* @param string $path
|
||||
* @return Response
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function upload(string $type, string $path): Response
|
||||
{
|
||||
if (!file_exists($path) || !is_readable($path)) {
|
||||
throw new WechatException(sprintf("File does not exist, or the file is unreadable: '%s'", $path));
|
||||
}
|
||||
|
||||
if (!in_array($type, $this->allowTypes, true)) {
|
||||
throw new WechatException(sprintf("Unsupported media type: '%s'", $type));
|
||||
}
|
||||
|
||||
return $this->httpUpload('cgi-bin/media/upload', ['media' => $path], ['type' => $type]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services\wechat\client\miniprogram;
|
||||
|
||||
|
||||
use crmeb\services\wechat\client\BaseClient;
|
||||
use crmeb\services\wechat\config\MiniProgramConfig;
|
||||
use crmeb\services\wechat\util\AES;
|
||||
use crmeb\services\wechat\WechatException;
|
||||
use EasyWeChat\Kernel\HttpClient\AccessTokenAwareClient;
|
||||
use EasyWeChat\Kernel\HttpClient\Response;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
use think\annotation\Inject;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
|
||||
class MediaCheckClient extends BaseClient
|
||||
{
|
||||
|
||||
const MSG_API = 'wxa/msg_sec_check';
|
||||
const MEDIA_API = 'wxa/media_check_async';
|
||||
const LABEL = [
|
||||
100 => '正常',
|
||||
10001 => '广告',
|
||||
20001 => '时政',
|
||||
20002 => '色情',
|
||||
20003 => '辱骂',
|
||||
20006 => '违法犯罪',
|
||||
20008 => '欺诈',
|
||||
20012 => '低俗',
|
||||
20013 => '版权',
|
||||
21000 => '其他'
|
||||
];
|
||||
//scene 场景枚举值(1 资料;2 评论;3 论坛;4 社交日志)
|
||||
|
||||
/**
|
||||
* 文本敏感词检测
|
||||
* @param $content
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* User: liusl
|
||||
* DateTime: 2024/11/26 下午5:28
|
||||
*/
|
||||
public function msgSecCheck($content)
|
||||
{
|
||||
$params = [
|
||||
'content' => $content
|
||||
];
|
||||
return $this->api->postJson(self::MSG_API, $params);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services\wechat\client\miniprogram;
|
||||
|
||||
|
||||
use Redis;
|
||||
use crmeb\exceptions\AdminException;
|
||||
use crmeb\services\wechat\config\MiniProgramConfig;
|
||||
use crmeb\services\wechat\config\PaymentConfig;
|
||||
use crmeb\services\wechat\util\Helper;
|
||||
use crmeb\services\wechat\WechatException;
|
||||
use crmeb\services\wechat\WechatResponse;
|
||||
use EasyWeChat\Kernel\HttpClient\AccessTokenAwareClient;
|
||||
use EasyWeChat\Kernel\HttpClient\Response;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface as ResponseInterfaceAlias;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 订单管理
|
||||
* Class OrderClient
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
* @package crmeb\services\wechat\client\miniprogram
|
||||
*/
|
||||
class OrderClient
|
||||
{
|
||||
const redis_prefix = 'mini_order';
|
||||
|
||||
const express_company = 'ZTO'; // 默认发货快递公司为(中通快递)
|
||||
|
||||
/**
|
||||
* @var PaymentConfig
|
||||
*/
|
||||
protected PaymentConfig $config;
|
||||
|
||||
/**
|
||||
* @var MiniProgramConfig
|
||||
*/
|
||||
protected MiniProgramConfig $miniProgramConfig;
|
||||
|
||||
/**
|
||||
* @var Redis
|
||||
*/
|
||||
protected Redis $redis;
|
||||
|
||||
/**
|
||||
* UserClient constructor.
|
||||
* @param AccessTokenAwareClient $api
|
||||
*/
|
||||
public function __construct(protected AccessTokenAwareClient $api)
|
||||
{
|
||||
$this->config = app()->make(PaymentConfig::class);
|
||||
$this->miniProgramConfig = app()->make(MiniProgramConfig::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理联系人
|
||||
* @param array $contact
|
||||
* @return array
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
protected function handleContact(array $contact = []): array
|
||||
{
|
||||
if (isset($contact)) {
|
||||
if (isset($contact['consignor_contact']) && $contact['consignor_contact']) {
|
||||
$contact['consignor_contact'] = Helper::encryptTel($contact['consignor_contact']);
|
||||
}
|
||||
if (isset($contact['receiver_contact']) && $contact['receiver_contact']) {
|
||||
$contact['receiver_contact'] = Helper::encryptTel($contact['receiver_contact']);
|
||||
}
|
||||
}
|
||||
return $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传订单
|
||||
* @param string $out_trade_no
|
||||
* @param int $logistics_type
|
||||
* @param array $shipping_list
|
||||
* @param string $payer_openid
|
||||
* @param $path
|
||||
* @param int $delivery_mode
|
||||
* @param bool $is_all_delivered
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function shippingByTradeNo(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, $path, int $delivery_mode = 1, bool $is_all_delivered = true)
|
||||
{
|
||||
if (!$this->checkManaged()) {
|
||||
throw new AdminException('开通小程序订单管理服务后重试');
|
||||
}
|
||||
$params = [
|
||||
'order_key' => [
|
||||
'order_number_type' => 2,
|
||||
'mchid' => $this->config->mchId,
|
||||
'transaction_id' => $out_trade_no
|
||||
],
|
||||
'logistics_type' => $logistics_type,
|
||||
'delivery_mode' => $delivery_mode,
|
||||
'upload_time' => date(DATE_RFC3339),
|
||||
'payer' => [
|
||||
'openid' => $payer_openid
|
||||
]
|
||||
];
|
||||
|
||||
if ($delivery_mode == 2) {
|
||||
$params['is_all_delivered'] = $is_all_delivered;
|
||||
}
|
||||
|
||||
foreach ($shipping_list as $shipping) {
|
||||
$contact = $this->handleContact($shipping['contact'] ?? []);
|
||||
$params['shipping_list'][] = [
|
||||
'tracking_no' => $shipping['tracking_no'] ?? '',
|
||||
'express_company' => $shipping['express_company'] ?? '',
|
||||
'item_desc' => $shipping['item_desc'],
|
||||
'contact' => $contact
|
||||
];
|
||||
}
|
||||
return $this->shipping($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合单
|
||||
* @param string $out_trade_no
|
||||
* @param int $logistics_type
|
||||
* @param array $sub_orders
|
||||
* @param string $payer_openid
|
||||
* @param int $delivery_mode
|
||||
* @param bool $is_all_delivered
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function combinedShippingByTradeNo(string $out_trade_no, int $logistics_type, array $sub_orders, string $payer_openid, int $delivery_mode = 2, bool $is_all_delivered = false)
|
||||
{
|
||||
if (!$this->checkManaged()) {
|
||||
throw new WechatException('开通小程序订单管理服务后重试');
|
||||
}
|
||||
$params = [
|
||||
'order_key' => [
|
||||
'order_number_type' => 1,
|
||||
'mchid' => $this->config->mchId,
|
||||
'out_trade_no' => $out_trade_no,
|
||||
],
|
||||
'upload_time' => date(DATE_RFC3339),
|
||||
'payer' => [
|
||||
'openid' => $payer_openid
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($sub_orders as $order) {
|
||||
$sub_order = [
|
||||
'order_key' => [
|
||||
'order_number_type' => 1,
|
||||
'mchid' => $this->config->mchId,
|
||||
'out_trade_no' => $order['out_trade_no'],
|
||||
'logistics_type' => $logistics_type,
|
||||
],
|
||||
'delivery_mode' => $delivery_mode,
|
||||
'is_all_delivered' => $is_all_delivered
|
||||
];
|
||||
foreach ($sub_orders['shipping_list'] as $shipping) {
|
||||
$contact = $this->handleContact($shipping['contact'] ?? []);
|
||||
$sub_order['shipping_list'][] = [
|
||||
'tracking_no' => $shipping['tracking_no'] ?? '',
|
||||
'express_company' => isset($shipping['express_company']) ? $this->getDelivery($shipping['express_company']) : '',
|
||||
'item_desc' => $shipping['item_desc'],
|
||||
'contact' => $contact
|
||||
];
|
||||
}
|
||||
$params['sub_orders'][] = $sub_order;
|
||||
}
|
||||
|
||||
return $this->resultHandle($this->api->postJson('wxa/sec/order/upload_combined_shipping_info', $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 签收通知
|
||||
* @param string $merchant_trade_no
|
||||
* @param string $received_time
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function notifyConfirmByTradeNo(string $merchant_trade_no, string $received_time)
|
||||
{
|
||||
$params = [
|
||||
'merchant_id' => $this->config->mchId,
|
||||
'merchant_trade_no' => $merchant_trade_no,
|
||||
'received_time' => $received_time
|
||||
];
|
||||
return $this->resultHandle($this->api->postJson('wxa/sec/order/notify_confirm_receive', $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置小修跳转路径
|
||||
* @param $path
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function setMesJumpPathAndCheck($path)
|
||||
{
|
||||
if (!$this->checkManaged()) {
|
||||
throw new WechatException('开通小程序订单管理服务后重试');
|
||||
}
|
||||
|
||||
$params = [
|
||||
'path' => $path
|
||||
];
|
||||
return $this->resultHandle($this->api->postJson('wxa/sec/order/set_msg_jump_path', $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function shipping($params)
|
||||
{
|
||||
return $this->resultHandle($this->api->postJson('wxa/sec/order/upload_shipping_info', $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object|Redis|null
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
protected function getRedis()
|
||||
{
|
||||
if (empty($this->redis)) {
|
||||
$this->redis = Cache::store('redis')->handler();
|
||||
}
|
||||
return $this->redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小程序是否已开通发货信息管理服务
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function isManaged()
|
||||
{
|
||||
$params = [
|
||||
'appid' => $this->miniProgramConfig->appId
|
||||
];
|
||||
return $this->resultHandle($this->api->postJson('wxa/sec/order/is_trade_managed', $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Response|ResponseInterfaceAlias $result
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
private function resultHandle(Response|ResponseInterfaceAlias $result)
|
||||
{
|
||||
return new WechatResponse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运力id列表get_delivery_list
|
||||
* @return mixed
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getDeliveryList()
|
||||
{
|
||||
return $this->resultHandle($this->api->postJson('cgi-bin/express/delivery/open_msg/get_delivery_list', []));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置物流列表
|
||||
* @return array
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function setDeliveryList()
|
||||
{
|
||||
$list = $this->getDeliveryList();
|
||||
if ($list) {
|
||||
$key = self::redis_prefix . '_delivery_list';
|
||||
$date = array_column($list['delivery_list'], 'delivery_id', 'delivery_name');
|
||||
// 创建缓存
|
||||
$this->getRedis()->hMSet($key, $date);
|
||||
|
||||
return $date;
|
||||
} else {
|
||||
throw new WechatException('物流公司列表异常');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function checkManaged()
|
||||
{
|
||||
$key = self::redis_prefix . '_is_trade_managed';
|
||||
if ($this->getRedis()->exists($key)) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->setManaged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function setManaged()
|
||||
{
|
||||
try {
|
||||
$res = $this->isManaged();
|
||||
if ($res['is_trade_managed']) {
|
||||
$key = self::redis_prefix . '_is_trade_managed';
|
||||
$this->getRedis()->set($key, $res['is_trade_managed']);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物流列表
|
||||
* @param $company_name
|
||||
* @return mixed|string
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function getDelivery($company_name)
|
||||
{
|
||||
$key = self::redis_prefix . '_delivery_list';
|
||||
if (!$this->getRedis()->exists($key)) {
|
||||
$date = $this->setDeliveryList();
|
||||
$express_company = $date[$company_name] ?? '';
|
||||
} else {
|
||||
$express_company = $this->getRedis()->hMGet($key, [$company_name])[$company_name] ?? '';
|
||||
}
|
||||
if (empty($express_company)) {
|
||||
$express_company = self::express_company;
|
||||
}
|
||||
|
||||
return $express_company;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/**
|
||||
* +----------------------------------------------------------------------
|
||||
* | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: CRMEB Team <admin@crmeb.com>
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace crmeb\services\wechat\client\miniprogram;
|
||||
|
||||
|
||||
use crmeb\services\wechat\client\BaseClient;
|
||||
use crmeb\services\wechat\WechatException;
|
||||
use EasyWeChat\Kernel\HttpClient\Response;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
|
||||
class SubscribeClient extends BaseClient
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected array $message = [
|
||||
'touser' => '',
|
||||
'template_id' => '',
|
||||
'page' => '',
|
||||
'data' => [],
|
||||
'miniprogram_state' => 'formal',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected array $required = ['touser', 'template_id', 'data'];
|
||||
|
||||
/**
|
||||
* 添加订阅消息模版
|
||||
* @param string $tid
|
||||
* @param array $kidList
|
||||
* @param string|null $sceneDesc
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function addTemplate(string $tid, array $kidList, string $sceneDesc = null): ResponseInterface|Response
|
||||
{
|
||||
$sceneDesc = $sceneDesc ?? '';
|
||||
$data = compact('tid', 'kidList', 'sceneDesc');
|
||||
|
||||
return $this->api->post('wxaapi/newtmpl/addtemplate', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板消息
|
||||
* @param string $id
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function deleteTemplate(string $id): ResponseInterface|Response
|
||||
{
|
||||
return $this->api->post('wxaapi/newtmpl/deltemplate', ['priTmplId' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模版标题的关键词列表
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
* @param string $tid
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
*/
|
||||
public function getTemplateKeywords(string $tid): ResponseInterface|Response
|
||||
{
|
||||
return $this->api->get('wxaapi/newtmpl/getpubtemplatekeywords', compact('tid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
* @param array $data
|
||||
* @return Response|ResponseInterface
|
||||
* @throws TransportExceptionInterface
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
public function send(array $data = []): ResponseInterface|Response
|
||||
{
|
||||
$params = $this->formatMessage($data);
|
||||
|
||||
$this->restoreMessage();
|
||||
|
||||
return $this->api->postJson('cgi-bin/message/subscribe/send', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @author 等风来
|
||||
* @email 136327134@qq.com
|
||||
* @date 2023/9/15
|
||||
*/
|
||||
protected function formatMessage(array $data = []): array
|
||||
{
|
||||
$params = array_merge($this->message, $data);
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
if (in_array($key, $this->required, true) && empty($value) && empty($this->message[$key])) {
|
||||
throw new WechatException(sprintf('Attribute "%s" can not be empty!', $key));
|
||||
}
|
||||
|
||||
$params[$key] = empty($value) ? $this->message[$key] : $value;
|
||||
}
|
||||
|
||||
foreach ($params['data'] as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
if (\array_key_exists('value', $value)) {
|
||||
$params['data'][$key] = ['value' => $value['value']];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count($value) >= 1) {
|
||||
$value = [
|
||||
'value' => $value[0],
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$value = [
|
||||
'value' => strval($value),
|
||||
];
|
||||
}
|
||||
|
||||
$params['data'][$key] = $value;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore message.
|
||||
*/
|
||||
protected function restoreMessage()
|
||||
{
|
||||
$this->message = (new \ReflectionClass(static::class))->getDefaultProperties()['message'];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user