diff --git a/crmeb/crmeb/services/easywechat/Application.php b/crmeb/crmeb/services/easywechat/Application.php index d5a976b1e..b96ba8dae 100644 --- a/crmeb/crmeb/services/easywechat/Application.php +++ b/crmeb/crmeb/services/easywechat/Application.php @@ -14,10 +14,12 @@ namespace crmeb\services\easywechat; use crmeb\services\easywechat\miniPayment\ServiceProvider; use crmeb\services\easywechat\oauth2\wechat\WechatOauth2Provider; +use crmeb\services\easywechat\orderShipping\OrderClient; use crmeb\services\easywechat\subscribe\ProgramProvider; use crmeb\services\easywechat\v3pay\PayClient; use crmeb\services\easywechat\wechatlive\ProgramProvider as LiveProgramProvider; use crmeb\services\easywechat\v3pay\ServiceProvider as V3PayServiceProvider; +use crmeb\services\easywechat\orderShipping\ServiceProvider as OrderServiceProvider; /** @@ -26,6 +28,7 @@ use crmeb\services\easywechat\v3pay\ServiceProvider as V3PayServiceProvider; * @property LiveProgramProvider $wechat_live * @property WechatOauth2Provider $oauth2 * @property PayClient $v3pay + * @property OrderClient $order_ship */ class Application extends \EasyWeChat\Foundation\Application { @@ -40,6 +43,7 @@ class Application extends \EasyWeChat\Foundation\Application ProgramProvider::class, V3PayServiceProvider::class, \crmeb\services\easywechat\Open3rd\ProgramProvider::class, + OrderServiceProvider::class ]; /** diff --git a/crmeb/crmeb/services/easywechat/orderShipping/BaseOrder.php b/crmeb/crmeb/services/easywechat/orderShipping/BaseOrder.php new file mode 100644 index 000000000..83daba646 --- /dev/null +++ b/crmeb/crmeb/services/easywechat/orderShipping/BaseOrder.php @@ -0,0 +1,131 @@ +config = $config; + } + + private function resultHandle(Collection $result) + { + if (empty($result)) { + throw new AdminException('微信接口返回异常'); + } + $res = $result->toArray(); + if ($res['errcode'] == 0) { + return $res; + } else { + throw new AdminException("微信接口异常:code = {$res['errcode']} msg = {$res['errmsg']}"); + } + } + + /** + * 发货 + * @param $params + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/09 + * @author yyw + */ + public function shipping($params) + { + return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'upload_shipping_info', json_encode($params)])); + + } + + /** + * 合单 + * @param $params + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/09 + * @author yyw + */ + public function combinedShipping($params) + { + return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'upload_combined_shipping_info', json_encode($params)])); + } + + + /** + * 签收消息提醒 + * @param $params + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/09 + * @author yyw + */ + public function notifyConfirm($params) + { + return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'notify_confirm_receive', json_encode($params)])); + } + + + /** + * 查询小程序是否已开通发货信息管理服务 + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/09 + * @author yyw + */ + public function isManaged() + { + $params = [ + 'appid' => $this->config['order_shipping']['appid'] + ]; + return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'notify_confirm_receive', json_encode($params)])); + } + + /** + * 设置跳转连接 + * @param $path + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public function setMesJumpPath($path) + { + $params = [ + 'path' => $path + ]; + return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'set_msg_jump_path', json_encode($params)])); + } + + /** + * 获取运力id列表get_delivery_list + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/09 + * @author yyw + */ + public function getDeliveryList() + { + return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::EXPRESS . 'get_delivery_list'])); + } +} diff --git a/crmeb/crmeb/services/easywechat/orderShipping/MiniOrderService.php b/crmeb/crmeb/services/easywechat/orderShipping/MiniOrderService.php new file mode 100644 index 000000000..b588ef45e --- /dev/null +++ b/crmeb/crmeb/services/easywechat/orderShipping/MiniOrderService.php @@ -0,0 +1,130 @@ + [ + 'appid' => sys_config('routine_appId'), + 'merchant_id' => sys_config('pay_new_weixin_open') ? sys_config('pay_weixin_mchid') : sys_config('pay_new_weixin_mchid'), + ] + ]; + } + + /** + * 初始化 + * @param bool $cache + * @return Application + */ + protected static function application($cache = false) + { + (self::$instance === null || $cache === true) && (self::$instance = new Application(self::options())); + return self::$instance; + } + + protected static function order() + { + return self::application()->order_ship; + } + + + /** + * 上传订单 + * @param string $out_trade_no + * @param int $logistics_type + * @param array $shipping_list + * @param string $payer_openid + * @param int $delivery_mode + * @param bool $is_all_delivered + * @return array + * + * @date 2023/05/09 + * @author yyw + */ + public static function shippingByTradeNo(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, int $delivery_mode = 1, bool $is_all_delivered = true) + { + return self::order()->shippingByTradeNo($out_trade_no, $logistics_type, $shipping_list, $payer_openid, $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 \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/10 + * @author yyw + */ + 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::order()->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 + * + * @date 2023/05/09 + * @author yyw + */ + public static function notifyConfirmByTradeNo(string $merchant_trade_no, string $received_time) + { + return self::order()->notifyConfirmByTradeNo($merchant_trade_no, $received_time); + } + + /** + * 判断是否开通 + * @return bool + * @throws \EasyWeChat\Core\Exceptions\HttpException + * @throws \Psr\SimpleCache\InvalidArgumentException + * + * @date 2023/05/09 + * @author yyw + */ + public static function isManaged() + { + return self::order()->checkManaged(); + } + + + /** + * 设置小修跳转路径 + * @param $path + * @return array + * @throws \EasyWeChat\Core\Exceptions\HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public static function setMesJumpPath($path) + { + return self::order()->setMesJumpPath($path); + } + + +} diff --git a/crmeb/crmeb/services/easywechat/orderShipping/OrderClient.php b/crmeb/crmeb/services/easywechat/orderShipping/OrderClient.php new file mode 100644 index 000000000..dd1ce730c --- /dev/null +++ b/crmeb/crmeb/services/easywechat/orderShipping/OrderClient.php @@ -0,0 +1,257 @@ +redis)) { + $this->redis = Cache::store('redis')->handler(); + } + return $this->redis; + } + + /** + * 发货 + * @param string $out_trade_no + * @param int $logistics_type + * @param array $shipping_list + * @param string $payer_openid + * @param int $delivery_mode + * @param bool $is_all_delivered + * @return array + * @throws HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public function shippingByTradeNo(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, int $delivery_mode = 1, bool $is_all_delivered = true) + { + if (!$this->checkManaged()) { + throw new AdminException('开通小程序订单管理服务后重试'); + } + + + $params = [ + 'order_key' => [ + 'order_number_type' => 1, + 'mchid' => $this->config['order_shipping']['merchant_id'], + 'out_trade_no' => $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) { + $params['shipping_list'][] = [ + 'tracking_no' => $shipping['tracking_no'], + 'express_company' => $this->getDelivery($shipping['express_company']), + 'item_desc' => $shipping['item_desc'], + 'contact' => $shipping['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 array + * @throws HttpException + * + * @date 2023/05/10 + * @author yyw + */ + 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 AdminException('开通小程序订单管理服务后重试'); + } + $params = [ + 'order_key' => [ + 'order_number_type' => 1, + 'mchid' => $this->config['order_shipping']['merchant_id'], + 'out_trade_no' => $out_trade_no, + ], + 'sub_orders' => [ + 'order_key' => [ + 'order_number_type' => 1, + 'mchid' => $this->config['order_shipping']['merchant_id'], + 'out_trade_no' => '', + 'logistics_type' => '', + ], + 'delivery_mode' => $delivery_mode, + 'is_all_delivered' => $is_all_delivered + ], + '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['order_shipping']['merchant_id'], + '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) { + $sub_order['shipping_list'][] = [ + 'tracking_no' => $shipping['tracking_no'], + 'express_company' => $this->getDelivery($shipping['express_company']), + 'item_desc' => $shipping['item_desc'], + 'contact' => $shipping['contact'] ?? [] + ]; + } + $params['sub_orders'][] = $sub_order; + } + + return $this->combinedShipping($params); + } + + + /** + * 签收通知 + * @param string $merchant_trade_no + * @param string $received_time + * @return array + * @throws HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public function notifyConfirmByTradeNo(string $merchant_trade_no, string $received_time) + { + $params = [ + 'merchant_id' => $this->config['payment']['merchant_id'], + 'merchant_trade_no' => $merchant_trade_no, + 'received_time' => $received_time + ]; + return $this->notifyConfirm($params); + } + + /** + * 设置小程序管理服务开通状态 + * @return bool + * @throws HttpException + * + * @date 2023/05/09 + * @author yyw + */ + public function setManaged() + { + $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; + } + + } + + /** + * @return bool + * @throws HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public function checkManaged() + { + $key = self::redis_prefix . '_is_trade_managed'; + if ($this->getRedis()->exists($key)) { + return true; + } else { + return $this->setManaged(); + } + } + + /** + * 同步去微信物流列表 + * @return array + * @throws HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public function setDeliveryList() + { + $list = $this->getDeliveryList(); + if ($list) { + $key = self::redis_prefix . '_delivery_list'; + $date = array_column($list, 'delivery_id', 'delivery_name'); + // 创建缓存 + $this->getRedis()->hMSet($key, $date); + + return $date; + } else { + throw new AdminException('物流公司列表异常'); + } + } + + /** + * 获取物流公司编码 + * @param $company_name + * @return array|mixed + * @throws HttpException + * + * @date 2023/05/10 + * @author yyw + */ + public function getDelivery($company_name) + { + $key = self::redis_prefix . '_delivery_list'; + if (!$this->getRedis()->exists($key)) { + $date = $this->setDeliveryList(); + if (!isset($date[$company_name])) { + throw new AdminException('物流公司异常'); + } + $express_company = $date[$company_name]; + } else { + $express_company = $this->getRedis()->hMGet($key, $company_name); + } + + return $express_company; + } +} diff --git a/crmeb/crmeb/services/easywechat/orderShipping/ServiceProvider.php b/crmeb/crmeb/services/easywechat/orderShipping/ServiceProvider.php new file mode 100644 index 000000000..17d11dffe --- /dev/null +++ b/crmeb/crmeb/services/easywechat/orderShipping/ServiceProvider.php @@ -0,0 +1,36 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace crmeb\services\easywechat\orderShipping; + +use EasyWeChat\Payment\Merchant; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use EasyWeChat\MiniProgram\AccessToken; + +/** + * Class ServiceProvider. + * + * @package crmeb\services\easywechat\order_ship + * @package crmeb\services\easywechat\mini_express + */ +class ServiceProvider implements ServiceProviderInterface +{ + /** + * {@inheritdoc}. + */ + public function register(Container $pimple) + { + $pimple['order_ship'] = function ($pimple) { + return new OrderClient($pimple['access_token'], $pimple); + }; + } +}