徐总多门店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

648 lines
20 KiB

2 months ago
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace crmeb\services\wechat;
use crmeb\services\wechat\config\MiniProgramConfig;
use crmeb\services\wechat\live\LiveClient;
use crmeb\services\wechat\orderShipping\OrderClient;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\DecryptException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use EasyWeChat\MiniProgram\Application;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Request;
use think\facade\Cache;
use think\Response;
use Yurun\Util\Swoole\Guzzle\SwooleHandler;
use crmeb\services\wechat\live\ServiceProvider as LiveServiceProvider;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use crmeb\services\wechat\orderShipping\ServiceProvider as OrderShippingServiceProvider;
/**
* 小程序服务
* Class MiniProgram
* @package crmeb\services\wechat
* @method \EasyWeChat\OfficialAccount\CustomerService\Client staffService() 客服
* @method \EasyWeChat\BasicService\Media\Client mediaService() 临时素材
* @method \EasyWeChat\MiniProgram\Encryptor encryptor() 解密
* @method \EasyWeChat\MiniProgram\AppCode\Client qrcodeService() 小程序码
* @method \EasyWeChat\MiniProgram\SubscribeMessage\Client subscribenoticeService() 订阅消息
* @method LiveClient liveService() 直播
* @method OrderClient orderShippingService() 订单管理
*/
class MiniProgram extends BaseApplication
{
/**
* @var MiniProgramConfig
*/
protected $config;
/**
* @var Application
*/
protected $application;
/**
* @var string[]
*/
protected static $property = [
'mediaService' => 'media',
'staffService' => 'customer_service',
'encryptor' => 'encryptor',
'qrcodeService' => 'app_code',
'subscribenoticeService' => 'subscribe_message',
'liveService' => 'live',
'orderShippingService' => 'orderShipping',
];
/**
* MiniProgram constructor.
*/
public function __construct()
{
$this->config = app(MiniProgramConfig::class);
$this->debug = DefaultConfig::value('logger');
}
/**
* 初始化
* @return Application
*/
public function application()
{
if (!$this->application) {
$this->application = Factory::miniProgram($this->config->all());
$request = request();
$this->application['guzzle_handler'] = SwooleHandler::class;
$this->application->rebind('request', new Request($request->get(), $request->post(), [], [], [], $request->server(), $request->getContent()));
$this->application->register(new LiveServiceProvider());
$this->application->register(new OrderShippingServiceProvider());
$this->application->rebind('cache', new RedisAdapter(Cache::store('redis')->handler()));
}
return $this->application;
}
public static function serve(): Response
{
$make = self::instance();
$make->application()->server->push($make->pushMessageHandler);
$response = $make->application()->server->serve();
return response($response->getContent());
}
/**
* @return MiniProgram
*/
public static function instance()
{
return app()->make(self::class);
}
/**
* 获得用户信息 根据code 获取session_key
* @param string $code
* @return array|Collection|object|ResponseInterface|string
*/
public static function getUserInfo(string $code)
{
try {
$response = self::instance()->application()->auth->session($code);
self::logger('获得用户信息 根据code 获取session_key', compact('code'), $response);
return $response;
} catch (\Throwable $e) {
throw new WechatException($e->getMessage());
}
}
/**
* 解密数据
* @param string $sessionKey
* @param string $iv
* @param string $encryptData
* @return array
* @throws DecryptException
*/
public static function decryptData(string $sessionKey, string $iv, string $encryptData)
{
$response = self::encryptor()->decryptData($sessionKey, $iv, $encryptData);
self::logger('解密数据', compact('sessionKey', 'iv', 'encryptData'), $response);
return $response;
}
/**
* 获取小程序码:适用于需要的码数量极多,或仅临时使用的业务场景
* @param string $scene
* @param string $path
* @param int $width
* @return array|Collection|object|ResponseInterface|string
*/
public static function appCodeUnlimit(string $scene, string $path = '', int $width = 0)
{
$optional = [
'page' => $path,
'width' => $width
];
if (!$optional['page']) {
unset($optional['page']);
}
if (!$optional['width']) {
unset($optional['width']);
}
$response = self::qrcodeService()->getUnlimit($scene, $optional);
self::logger('获取小程序码', compact('scene', 'optional'), $response);
return $response;
}
/**
* 发送订阅消息
* @param string $touser
* @param string $templateId
* @param array $data
* @param string $link
* @return array|Collection|object|ResponseInterface|string
* @throws InvalidArgumentException
* @throws InvalidConfigException
* @throws GuzzleException
*/
public static function sendSubscribeTemlate(string $touser, string $templateId, array $data, string $link = '')
{
$response = self::subscribenoticeService()->send([
'template_id' => $templateId,
'touser' => $touser,
'page' => $link,
'data' => $data
]);
self::logger('发送订阅消息', compact('templateId', 'touser', 'link', 'data'), $response);
return $response;
}
/**
* 添加订阅消息模版
* @param string $tid
* @param array $kidList
* @param string $sceneDesc
* @return mixed
*/
public static function addSubscribeTemplate(string $tid, array $kidList, string $sceneDesc = '')
{
try {
$res = self::subscribenoticeService()->addTemplate($tid, $kidList, $sceneDesc);
self::logger('添加订阅消息模版', compact('tid', 'kidList', 'sceneDesc'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['priTmplId'])) {
return $res['priTmplId'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException($e);
}
}
/**
* 删除订阅消息
* @param string $templateId
* @return array|Collection|object|ResponseInterface|string
*/
public static function delSubscribeTemplate(string $templateId)
{
try {
$response = self::subscribenoticeService()->deleteTemplate($templateId);
self::logger('删除订阅消息', compact('templateId'), $response);
return $response;
} catch (\Throwable $e) {
throw new WechatException($e->getMessage());
}
}
/**
* 获取模版标题的关键词列表
* @param string $tid
* @return mixed
*/
public static function getSubscribeTemplateKeyWords(string $tid)
{
try {
$res = self::subscribenoticeService()->getTemplateKeywords($tid);
self::logger('获取模版标题的关键词列表', compact('tid'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['data'])) {
return $res['data'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException($e);
}
}
/**
* 获取直播列表
* @param int $page
* @param int $limit
* @return array
*/
public static function getLiveInfo(int $page = 1, int $limit = 10)
{
try {
$res = self::liveService()->getRooms($page, $limit);
self::logger('获取直播列表', compact('page', 'limit'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['room_info']) && $res['room_info']) {
return $res['room_info'];
} else {
return [];
}
} catch (\Throwable $e) {
return [];
}
}
/**
* 获取直播回放
* @param int $room_id
* @param int $page
* @param int $limit
* @return mixed
*/
public static function getLivePlayback(int $room_id, int $page = 1, int $limit = 10)
{
try {
$res = self::liveService()->getPlaybacks($room_id, $page, $limit);
self::logger('获取直播回放', compact('room_id', 'page', 'limit'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['live_replay'])) {
return $res['live_replay'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 创建直播间
* @param array $data
* @return mixed
*/
public static function createLiveRoom(array $data)
{
try {
$res = self::liveService()->createRoom($data);
self::logger('创建直播间', compact('data'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['roomId'])) {
unset($res['errcode']);
return $res;
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 直播间添加商品
* @param int $roomId
* @param $ids
* @return bool
*/
public static function roomAddGoods(int $roomId, $ids)
{
try {
$res = self::liveService()->roomAddGoods($roomId, $ids);
self::logger('直播间添加商品', compact('roomId', 'ids'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0) {
return true;
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 获取商品列表
* @param int $status
* @param int $page
* @param int $limit
* @return mixed
*/
public static function getGoodsList(int $status = 2, int $page = 1, int $limit = 10)
{
try {
$res = self::liveService()->getGoodsList($status, $page, $limit);
self::logger('获取商品列表', compact('status', 'page', 'limit'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['goods'])) {
return $res['goods'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 获取商品详情
* @param $goods_ids
* @return mixed
*/
public static function getGooodsInfo($goods_ids)
{
try {
$res = self::liveService()->getGooodsInfo($goods_ids);
self::logger('获取商品详情', compact('goods_ids'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['goods'])) {
return $res['goods'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 添加商品
* @param string $coverImgUrl
* @param string $name
* @param int $priceType
* @param string $url
* @param $price
* @param string $price2
* @return mixed
*/
public static function addGoods(string $coverImgUrl, string $name, int $priceType, string $url, $price, $price2 = '')
{
try {
$res = self::liveService()->addGoods($coverImgUrl, $name, $priceType, $url, $price, $price2);
self::logger('添加商品', compact('coverImgUrl', 'name', 'priceType', 'url', 'price', 'price2'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['goodsId'])) {
unset($res['errcode']);
return $res;
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 商品撤回审核
* @param int $goodsId
* @param $auditId
* @return bool
*/
public static function resetauditGoods(int $goodsId, $auditId)
{
try {
$res = self::liveService()->resetauditGoods($goodsId, $auditId);
self::logger('商品撤回审核', compact('goodsId', 'auditId'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0) {
return true;
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 商品重新提交审核
* @param int $goodsId
* @return mixed
*/
public static function auditGoods(int $goodsId)
{
try {
$res = self::liveService()->auditGoods($goodsId);
self::logger('商品重新提交审核', compact('goodsId'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['auditId'])) {
return $res['auditId'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 删除商品
* @param int $goodsId
* @return bool
*/
public static function deleteGoods(int $goodsId)
{
try {
$res = self::liveService()->deleteGoods($goodsId);
self::logger('删除商品', compact('goodsId'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0) {
return true;
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 更新商品
* @param int $goodsId
* @param string $coverImgUrl
* @param string $name
* @param int $priceType
* @param string $url
* @param $price
* @param string $price2
* @return bool
*/
public static function updateGoods(int $goodsId, string $coverImgUrl, string $name, int $priceType, string $url, $price, $price2 = '')
{
try {
$res = self::liveService()->updateGoods($goodsId, $coverImgUrl, $name, $priceType, $url, $price, $price2);
self::logger('更新商品', compact('goodsId', 'coverImgUrl', 'name', 'priceType', 'url', 'price', 'price2'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0) {
return true;
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 获取成员列表
* @param int $role
* @param int $page
* @param int $limit
* @param string $keyword
* @return mixed
*/
public static function getRoleList($role = 2, int $page = 0, int $limit = 30, $keyword = '')
{
try {
$res = self::liveService()->getRoleList($role, $page, $limit, $keyword);
self::logger('获取成员列表', compact('role', 'page', 'limit', 'keyword'), $res);
if (isset($res['errcode']) && $res['errcode'] == 0 && isset($res['list'])) {
return $res['list'];
} else {
throw new WechatException($res['errmsg']);
}
} catch (\Throwable $e) {
throw new WechatException(ErrorMessage::getValidMessgae($e));
}
}
/**
* 小程序临时素材上传
* @param string $path
* @param string $type
* @return WechatResponse
* @throws GuzzleException
* @throws InvalidArgumentException
* @throws InvalidConfigException
*/
public static function temporaryUpload(string $path, string $type = 'image')
{
$response = self::mediaService()->upload($type, $path);
self::logger('小程序-临时素材上传', compact('path', 'type'), $response);
return new WechatResponse($response);
}
/**
* 上传订单
* @param string $out_trade_no 订单号(商城订单好)
* @param int $logistics_type 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
* @param array $shipping_list 物流信息列表,发货物流单列表,支持统一发货(单个物流单)和分拆发货(多个物流单)两种模式,多重性: [1, 10]
* @param string $payer_openid 支付者,支付者信息
* @param int $delivery_mode 发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY
* @param bool $is_all_delivered 分拆发货模式时必填,用于标识分拆发货模式下是否已全部发货完成,只有全部发货完成的情况下才会向用户推送发货完成通知。示例值: true/false
* @return array
*
* @throws HttpException
*
*/
public static function shippingByTradeNo(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, string $path, int $delivery_mode = 1, bool $is_all_delivered = true)
{
return self::orderShippingService()->shippingByTradeNo($out_trade_no, $logistics_type, $shipping_list, $payer_openid, $path, $delivery_mode, $is_all_delivered);
}
/**
* 合单
* @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 array
* @throws HttpException
*
*
*/
public static function combinedShippingByTradeNo(string $out_trade_no, int $logistics_type, array $sub_orders, string $payer_openid, int $delivery_mode = 2, bool $is_all_delivered = false)
{
return self::orderShippingService()->combinedShippingByTradeNo($out_trade_no, $logistics_type, $sub_orders, $payer_openid, $delivery_mode, $is_all_delivered);
}
/**
* 签收通知
* @param string $merchant_trade_no
* @param string $received_time
* @return array
*
*
*/
public static function notifyConfirmByTradeNo(string $merchant_trade_no, string $received_time)
{
return self::orderShippingService()->notifyConfirmByTradeNo($merchant_trade_no, $received_time);
}
/**
* 判断是否开通
* @return bool
* @throws HttpException
*
* @date 2023/05/17
* @author yyw
*/
public static function isManaged()
{
return self::orderShippingService()->checkManaged();
}
/**
* 设置小修跳转路径
* @param $path
* @return array
* @throws HttpException
*
*
*/
public static function setMesJumpPathAndCheck($path)
{
return self::orderShippingService()->setMesJumpPathAndCheck($path);
}
}