Initial commit: queue workspace

Made-with: Cursor
This commit is contained in:
apple
2026-03-21 02:55:24 +08:00
commit 78de918c37
12388 changed files with 1840126 additions and 0 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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]);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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'];
}
}