Merge branch 'v5.0.0dev' of https://gitee.com/ZhongBangKeJi/CRMEB into v5.0.0dev

This commit is contained in:
From-wh 2023-05-16 10:49:10 +08:00
commit 94709409db
14 changed files with 358 additions and 24 deletions

View File

@ -766,4 +766,41 @@ class StoreOrder extends AuthController
return app('json')->success(400121);
}
/**
* 获取快递信息
* @param ServeServices $services
* @return \think\Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function getKuaidiComs(ServeServices $services)
{
return app('json')->success($services->express()->getKuaidiComs());
}
/**
* 取消商家寄件
* @param $id
* @return \think\Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function shipmentCancelOrder($id)
{
if (!$id) {
return app('json')->fail('缺少参数');
}
$msg = $this->request->post('msg', '');
if (!$msg) {
return app('json')->fail('请填写取消寄件原因');
}
if ($this->services->shipmentCancelOrder((int)$id, $msg)) {
return app('json')->success('取消成功');
} else {
return app('json')->fail('取消失败');
}
}
}

View File

@ -80,4 +80,21 @@ class Export extends AuthController
}
return app('json')->success(['isOpen' => $res]);
}
/**
* @param ServeServices $services
* @return \think\Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function getShipmentOrderList(ServeServices $services)
{
$where = $this->request->getMore([
['page', 1],
['limit', 10],
]);
return app('json')->success($services->express()->getShipmentOrderList($where));
}
}

View File

@ -14,6 +14,10 @@ use think\facade\Route;
* 订单路由
*/
Route::group('order', function () {
//获取快递信息
Route::get('kuaidi_coms', 'v1.order.StoreOrder/getKuaidiComs')->option(['real_name' => '获取快递信息']);
//取消商家寄件
Route::post('shipment_cancel_order/:id', 'v1.order.StoreOrder/shipmentCancelOrder')->option(['real_name' => '取消商家寄件']);
//打印订单
Route::get('print/:id', 'v1.order.StoreOrder/order_print')->name('StoreOrderPrint')->option(['real_name' => '打印订单']);
//订单列表

View File

@ -977,4 +977,9 @@ class StoreOrderDao extends BaseDao
$query->page($page, $limit);
})->field(['uid', 'order_id', 'real_name', 'status', 'pay_price', 'total_num', 'add_time', 'pay_time', 'paid'])->order('add_time desc')->select()->toArray();
}
public function getSubOrderNotSend(int $pid, int $order_id)
{
return $this->getModel()->where('id', $pid)->where('status', '0')->where('id', '<>', $order_id)->count();
}
}

View File

@ -39,6 +39,7 @@ return [
'NoticeListener' => [\app\listener\notice\NoticeListener::class], //通知->消息事件
'NotifyListener' => [\app\listener\pay\NotifyListener::class],//支付异步回调
'CrontabListener' => [\app\listener\crontab\SystemCrontabListener::class],//定时任务事件
'OrderShipping' => [\app\listener\order\OrderShippingListener::class],//定时任务事件
],
];

View File

@ -0,0 +1,71 @@
<?php
namespace app\listener\order;
use app\model\order\StoreOrder;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use app\services\wechat\WechatUserServices;
use crmeb\exceptions\AdminException;
use crmeb\interfaces\ListenerInterface;
use crmeb\services\easywechat\orderShipping\MiniOrderService;
class OrderShippingListener implements ListenerInterface
{
public function handle($event): void
{
/** @var StoreOrder $order */
[$order, $delivery_type, $delivery_id, $delivery_name] = $event;
$order_shipping_open = sys_config('order_shipping_open', 0); // 小程序发货信息管理服务开关
if ($order && $order_shipping_open) {
if ($order['channel_type'] = 'routine') {
$out_trade_no = $order['order_id'];
//判断订单是否拆单
$delivery_mode = 1;
$is_all_delivered = true;
if ($order['pid'] > 0) {
$order = '';
$delivery_mode = 2;
// 判断订单是否全部发货
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$is_all_delivered = $orderServices->checkSubOrderNotSend((int)$order['pid'], (int)$order['id']);
}
// 整理商品信息
/** @var StoreOrderCartInfoServices $orderInfoServices */
$orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
$item_desc = $orderInfoServices->getCarIdByProductTitle((int)$order['id'], true);
$shipping_list = [
['item_desc' => $item_desc]
];
//判断订单物流模式
if ($order['shipping_type'] == 1) {
if ($delivery_type == 1) {
$shipping_list = [
[
'tracking_no' => $delivery_id ?? '',
'express_company' => $delivery_name ?? '',
'item_desc' => $item_desc,
'contact' => [
'receiver_contact' => $order['user_phone']
]
]
];
}
$logistics_type = $delivery_type;
} else {
$logistics_type = 4;
}
//查找支付者openid
/** @var WechatUserServices $wechatUserService */
$wechatUserService = app()->make(WechatUserServices::class);
$payer_openid = $wechatUserService->uidToOpenid($order['pay_uid'], 'routine');
if (empty($payer_openid)) {
throw new AdminException('订单支付人异常');
}
MiniOrderService::shippingByTradeNo($out_trade_no, $logistics_type, $shipping_list, $payer_openid, $delivery_mode, $is_all_delivered);
}
}
}
}

View File

@ -473,6 +473,7 @@ class StoreOrderDeliveryServices extends BaseServices
if (!$data['delivery_name']) {
throw new AdminException(400007);
}
$dump = [];
$data['delivery_type'] = 'express';
if ($data['express_record_type'] == 2) {//电子面单
if (!$data['delivery_code']) {
@ -522,6 +523,52 @@ class StoreOrderDeliveryServices extends BaseServices
if (!empty($dump['label'])) {
$data['kuaidi_label'] = $dump['label'];
}
} else if ($data['express_record_type'] == 3) {
//商家寄件
if (!$data['delivery_code']) {
throw new AdminException(400476);
}
if (!$data['express_temp_id']) {
throw new AdminException(400527);
}
if (!$data['to_name']) {
throw new AdminException(400008);
}
if (!$data['to_tel']) {
throw new AdminException(400477);
}
if (!$data['to_addr']) {
throw new AdminException(400478);
}
/** @var ServeServices $expressService */
$expressService = app()->make(ServeServices::class);
$expData['kuaidicom'] = $data['delivery_code'];
$expData['man_name'] = $orderInfo->real_name;
$expData['phone'] = $orderInfo->user_phone;
$expData['address'] = $orderInfo->user_address;
$expData['send_real_name'] = $data['to_name'];
$expData['send_phone'] = $data['to_tel'];
$expData['send_address'] = $data['to_addr'];
$expData['temp_id'] = $data['express_temp_id'];
$expData['weight'] = $this->getOrderSumWeight($id);
$expData['cargo'] = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo->id, true);
if (!sys_config('config_shippment_open', 0)) {
throw new AdminException('商家寄件未开启无法寄件');
}
$dump = $expressService->express()->shippmentCreateOrder($expData);
$orderInfo->delivery_id = $dump['kuaidinum'] ?? '';
$data['express_dump'] = json_encode([
'com' => $expData['com'],
'from_name' => $expData['from_name'],
'from_tel' => $expData['from_tel'],
'from_addr' => $expData['from_addr'],
'temp_id' => $expData['temp_id'],
'cargo' => $expData['cargo'],
]);
$data['delivery_id'] = $dump['kuaidinum'] ?? '';
$data['kuaidi_label'] = $dump['label'] ?? '';
$data['kuaidi_task_id'] = $dump['taskId'] ?? '';
$data['kuaidi_order_id'] = $dump['orderId'] ?? '';
} else {
if (!$data['delivery_id']) {
throw new AdminException(400531);

View File

@ -20,6 +20,7 @@ use app\services\other\PosterServices;
use app\services\pay\OrderPayServices;
use app\services\pay\PayServices;
use app\services\product\product\StoreProductLogServices;
use app\services\serve\ServeServices;
use app\services\system\attachment\SystemAttachmentServices;
use app\services\system\store\SystemStoreServices;
use app\services\user\UserInvoiceServices;
@ -38,6 +39,7 @@ use crmeb\services\FormBuilder as Form;
use crmeb\services\printer\Printer;
use crmeb\services\SystemConfigService;
use crmeb\utils\Arr;
use think\exception\ValidateException;
use think\facade\Log;
/**
@ -2643,4 +2645,66 @@ HTML;
return $data;
}
/**
* 取消商家寄件
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
* @param int $id
* @param string $msg
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function shipmentCancelOrder(int $id, string $msg)
{
$orderInfo = $this->dao->get($id);
if (!$orderInfo) {
throw new ValidateException('取消的订单不存在');
}
if (!$orderInfo->kuaidi_task_id || !$orderInfo->kuaidi_order_id) {
throw new ValidateException('商家寄件订单信息不存在,无法取消');
}
if ($orderInfo->status != 1) {
throw new ValidateException('订单状态不正确,无法取消寄件');
}
//发起取消商家寄件
$res = app()->make(ServeServices::class)->express()->shipmentCancelOrder([
'task_id' => $orderInfo->kuaidi_task_id,
'order_id' => $orderInfo->kuaidi_order_id,
'cancel_msg' => $msg,
]);
if ($res['status'] != 200) {
throw new ValidateException($res['msg'] ?? '一号通:取消失败');
}
//订单返回原状态
$this->transaction(function () use ($id, $msg, $orderInfo) {
app()->make(StoreOrderStatusServices::class)->save([
'oid' => $id,
'change_time' => time(),
'change_type' => 'delivery_goods_cancel',
'change_message' => '已取消发货,取消原因:' . $msg
]);
$orderInfo->status = 0;
$orderInfo->save();
});
return $res;
}
public function checkSubOrderNotSend(int $pid, int $order_id)
{
$order_count = $this->dao->getSubOrderNotSend($pid, $order_id);
if ($order_count > 0) {
return false;
} else {
return true;
}
}
}

View File

@ -94,7 +94,7 @@ class BaseOrder extends AbstractAPI
public function isManaged()
{
$params = [
'appid' => $this->config['config']['order_shipping']['appid']
'appid' => $this->config['config']['mini_program']['app_id']
];
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'notify_confirm_receive', json_encode($params)]));
}

View File

@ -4,6 +4,7 @@ namespace crmeb\services\easywechat\orderShipping;
use crmeb\services\easywechat\Application;
use crmeb\services\SystemConfigService;
use EasyWeChat\Core\Exceptions\HttpException;
class MiniOrderService
{
@ -24,8 +25,8 @@ class MiniOrderService
{
$payment = SystemConfigService::more(['routine_appId', 'routine_appsecret', 'pay_weixin_mchid', 'pay_new_weixin_open', 'pay_new_weixin_mchid']);
return [
'order_shipping' => [
'appid' => $payment['routine_appId'] ?? '',
'mini_program' => [
'app_id' => $payment['routine_appId'] ?? '',
'secret' => $payment['routine_appsecret'] ?? '',
'merchant_id' => empty($payment['pay_new_weixin_open']) ? trim($payment['pay_weixin_mchid']) : trim($payment['pay_new_weixin_mchid']),
]
@ -51,14 +52,15 @@ class MiniOrderService
/**
* 上传订单
* @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
* @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
* @date 2023/05/09
* @author yyw
*/
@ -76,7 +78,7 @@ class MiniOrderService
* @param int $delivery_mode
* @param bool $is_all_delivered
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
@ -103,7 +105,7 @@ class MiniOrderService
/**
* 判断是否开通
* @return bool
* @throws \EasyWeChat\Core\Exceptions\HttpException
* @throws HttpException
* @throws \Psr\SimpleCache\InvalidArgumentException
*
* @date 2023/05/09
@ -119,7 +121,7 @@ class MiniOrderService
* 设置小修跳转路径
* @param $path
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
* @throws HttpException
*
* @date 2023/05/10
* @author yyw

View File

@ -14,11 +14,6 @@ class OrderClient extends BaseOrder
const redis_prefix = 'mimi_order';
public function __construct(AccessToken $accessToken, $config)
{
parent::__construct($accessToken, $config);
}
/**
* @var \Redis
*/
@ -83,7 +78,7 @@ class OrderClient extends BaseOrder
$params = [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['config']['order_shipping']['merchant_id'],
'mchid' => $this->config['config']['mini_program']['merchant_id'],
'out_trade_no' => $out_trade_no,
],
'logistics_type' => $logistics_type,
@ -132,7 +127,7 @@ class OrderClient extends BaseOrder
$params = [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['order_shipping']['merchant_id'],
'mchid' => $this->config['mini_program']['merchant_id'],
'out_trade_no' => $out_trade_no,
],
'upload_time' => date(DATE_RFC3339),
@ -145,7 +140,7 @@ class OrderClient extends BaseOrder
$sub_order = [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['order_shipping']['merchant_id'],
'mchid' => $this->config['mini_program']['merchant_id'],
'out_trade_no' => $order['out_trade_no'],
'logistics_type' => $logistics_type,
],
@ -264,12 +259,15 @@ class OrderClient extends BaseOrder
if (!$this->getRedis()->exists($key)) {
$date = $this->setDeliveryList();
if (!isset($date[$company_name])) {
throw new AdminException('物流公司异常');
throw new AdminException('物流公司异常1');
}
$express_company = $date[$company_name];
} else {
$express_company = $this->getRedis()->hMGet($key, $company_name);
}
if (empty($express_company)) {
throw new AdminException('物流公司异常2');
}
return $express_company;
}

View File

@ -46,6 +46,15 @@ class Express extends BaseExpress
*/
const EXPRESS_DUMP = 'expr/dump';
//获取物流公司信息
const SHIPMENT_KUAIDI_NUMS = 'shipment/get_kuaidi_coms';
//创建商家寄件订单
const SHIPMENT_CREATE_ORDER = 'shipment/create_order';
//取消商家寄件
const SHIPMENT_CANCEL_ORDER = 'shipment/cancel_order';
//获取商家寄件订单列表
const SHIPMENT_INDEX = 'shipment/index';
/** 初始化
* @param array $config
* @return mixed|void
@ -56,6 +65,85 @@ class Express extends BaseExpress
parent::initialize($config); // TODO: Change the autogenerated stub
}
/**
* 商家寄件获取快递公司
* @return array|mixed
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function getKuaidiComs()
{
return $this->accessToken->httpRequest(self::SHIPMENT_KUAIDI_NUMS, [], 'GET');
}
/**
* 商家寄件创建订单
* @param array $data
* @return array|mixed
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function shippmentCreateOrder(array $data)
{
$siid = sys_config('config_export_siid');
$param = [
'kuaidicom' => $data['kuaidicom'],
'man_name' => $data['man_name'],
'phone' => $data['phone'],
'address' => $data['address'],
'send_real_name' => $data['send_real_name'],
'send_phone' => $data['send_phone'],
'send_address' => $data['send_address'],
'call_back_url' => sys_config(''),
'return_type' => $siid ? '10' : '20',
'siid' => $siid,
'tempid' => $data['tempid'],
'cargo' => $data['cargo'],
'weight' => $data['weight'],
];
return $this->accessToken->httpRequest(self::SHIPMENT_CREATE_ORDER, $param);
}
/**
* 取消商家寄件订单
* @param array $data
* @return array|mixed
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function shipmentCancelOrder(array $data)
{
$param = [
'task_id' => $data['task_id'],//快递100商家寄件任务id
'order_id' => $data['order_id'],//快递100商家寄件发起的订单号。并不是系统中的订单号
'cancel_msg' => $data['cancel_msg'],//取消原因
];
return $this->accessToken->httpRequest(self::SHIPMENT_CANCEL_ORDER, $param);
}
/**
* 获取商家寄件订单列表
* @param array $data
* @return array|mixed
* @author 等风来
* @email 136327134@qq.com
* @date 2023/5/15
*/
public function getShipmentOrderList(array $data)
{
$param = [
'kuaidi_num' => $data['kuaidi_num'] ?? '',
'courier_name' => $data['courier_name'] ?? '',
'page' => $data['page'] ?? 1,
'limit' => $data['limit'] ?? 10,
];
return $this->accessToken->httpRequest(self::SHIPMENT_INDEX, $param, 'GET');
}
/**
* 开通物流服务
* @return bool|mixed

View File

@ -369,7 +369,7 @@ abstract class BaseUpload extends BaseStorage
* 文件流上传
* @return mixed
*/
abstract public function stream(string $fileContent, string $key = null);
abstract public function stream($fileContent, string $key = null);
/**
* 删除文件

View File

@ -27495,7 +27495,7 @@ CREATE TABLE IF NOT EXISTS `eb_message_system` (
`uid` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '用户ID',
`title` varchar(256) NOT NULL DEFAULT '' COMMENT '通知标题',
`content` varchar(512) NOT NULL DEFAULT '' COMMENT '通知内容',
`data` varchar(1000) NOT NULL DEFAULT '' COMMENT '站内信参数',
`data` varchar(5000) NOT NULL DEFAULT '' COMMENT '站内信参数',
`look` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否查看',
`type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1:普通用户,2:管理员',
`add_time` int(11) NOT NULL DEFAULT '0' COMMENT '通知时间',
@ -33726,6 +33726,7 @@ INSERT INTO `eb_system_config` (`id`, `menu_name`, `type`, `input_type`, `config
(388, 'customer_corpId', 'text', 'input', 69, '', 1, '', 0, 0, '\"\"', '企业ID', '如果客服链接填写企业微信客服,小程序需要跳转企业微信客服的话需要配置此项,并且在小程序客服中绑定企业ID', 0, 1),
(389, 'create_wechat_user', 'radio', 'input', 2, '1=>开启\r\n0=>关闭', 1, '', 0, 0, '0', '关注公众号是否生成用户', '关注公众号是否生成用户', 0, 1),
(390, 'friend_pay_status', 'radio', 'input', 109, '1=>开启\r\n0=>关闭', 1, '', 0, 0, '1', '好友代付', '好友代付开关,关闭后付款类型不显示好友代付', 0, 1),
(391, 'division_status', 'radio', 'input', 72, '1=>开启\r\n0=>关闭', 1, '', 0, 0, '0', '事业部开关', '事业部开关,关闭后不不计算事业部佣金', 0, 1),
(392, 'brokerage_level', 'radio', 'input', 72, '1=>一级分销\r\n2=>二级分销', 1, '', 0, 0, '2', '分销层级', '分销层级,一级是只返上级一层的佣金,二级是返上级和上上级的佣金', 98, 1),
(393, 'sms_type', 'radio', 'input', 97, '0=>一号通\r\n1=>阿里云\r\n2=>腾讯云', 1, '', 0, 0, '0', '短信类型', '短信类型,选择发送的短信类型', 0, 1),
(394, 'aliyun_AccessKeyId', 'text', 'input', 98, '', 1, '', 0, 0, '\"\"', '阿里云AccessKeyId', '阿里云AccessKeyId', 100, 1),
@ -33760,7 +33761,6 @@ INSERT INTO `eb_system_config` (`id`, `menu_name`, `type`, `input_type`, `config
(431, 'member_brokerage', 'radio', 'input', 73, '1=>开启\n0=>关闭', 1, '', 0, 0, '\"0\"', '购买付费会员返佣', '购买付费会员是否按照设置的佣金比例进行返佣', 98, 1),
(432, 'user_brokerage_type', 'radio', 'input', 73, '0=>按照商品价格返佣\n1=>按照实际支付价格返佣', 1, '', 0, 0, '\"0\"', '返佣类型', '选择返佣类型,按照商品价格返佣(按照商品售价计算返佣金额)以及按照实际支付价格返佣(按照商品的实际支付价格计算返佣 )', 97, 1),
(433, 'network_security', 'text', 'input', 26, '', 1, '', 0, 0, '\"\\u4eac\\u516c\\u7f51\\u5b89\\u5907xxxxxx\\u53f7\"', '网安备案', '公安部门登记的备案信息,显示在pc底部', 8, 1),
(434, 'cert_crmeb', 'text', 'input', 1, '', 1, '', 0, 0, '\",\\u5f00\\u6e90\\u7248\"', '授权密钥', '', 0, 2),
(435, 'icp_url', 'text', 'input', 26, '', 1, '', 0, 0, '\"https:\\/\\/beian.miit.gov.cn\"', 'ICP备案链接', 'H5和PC底部显示的ICP备案号点击跳转的链接', 9, 1),
(436, 'network_security_url', 'text', 'input', 26, '', 1, '', 0, 0, '\"https:\\/\\/www.beian.gov.cn\"', '网安备案链接', 'H5和PC底部显示的网安备案号点击跳转的链接', 7, 1),
(437, 'agent_apply_open', 'radio', 'input', 72, '1=>开启\n0=>关闭', 1, '', 0, 0, '1', '代理商申请开关', '控制移动端我的推广页面的代理商申请按钮是否显示', 0, 1);