// +---------------------------------------------------------------------- namespace app\services\order\supplier; use app\services\message\notice\NoticeSmsService; use app\services\order\StoreOrderRefundServices; use think\facade\Log; use app\webscoket\SocketPush; use app\services\BaseServices; use crmeb\traits\ServicesTrait; use app\dao\order\StoreOrderDao; use crmeb\services\CacheService; use think\exception\ValidateException; use app\services\order\StoreOrderCartInfoServices; /** * 供应商订单 * Class SupplierOrderServices * @package app\sservices\order\supplier * @mixin StoreOrderDao */ class SupplierOrderServices extends BaseServices { use ServicesTrait; /** * 支付类型 * @var string[] */ public $pay_type = ['weixin' => '微信支付', 'yue' => '余额支付', 'offline' => '线下支付', 'alipay' => '支付宝支付', 'cash' => '现金支付', 'automatic' => '自动转账', 'store' => '微信支付']; /** * SupplierOrderServices constructor. * @param StoreOrderDao $dao */ public function __construct(StoreOrderDao $dao) { $this->dao = $dao; } /** * 配货单信息 * @param array $id * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getDistribution(array $id): array { $orderList = $this->dao->getList(['id' => $id], ['id', 'order_id', 'store_id', 'supplier_id', 'trade_no', 'real_name', 'user_phone', 'user_address', 'pay_time', 'pay_type', 'pay_postage as freight_price', 'coupon_price', 'deduction_price', 'use_integral', 'pay_price', 'mark']); if (!$orderList) { throw new ValidateException('订单不存在'); } /** @var StoreOrderCartInfoServices $services */ $cartServices = app()->make(StoreOrderCartInfoServices::class); foreach ($orderList as &$order) { $order['pay_type_name'] = $this->pay_type[$order['pay_type']] ?? '其他方式'; $order['pay_time'] = $order['pay_time'] ? date('Y-m-d H:i:s', (int)$order['pay_time']) : ''; $cartInfos = $cartServices->getCartColunm(['oid' => $order['id']], 'cart_num,is_writeoff,surplus_num,cart_info,refund_num,product_type,is_support_refund,is_gift,promotions_id', 'unique'); $i = 1; $list = []; //核算优惠金额 $vipTruePrice = 0; foreach ($cartInfos as $cartInfo) { $cart = json_decode($cartInfo['cart_info'], true); $vipTruePrice = bcadd((string)$vipTruePrice, bcmul($cart['vip_truePrice'], $cart['cart_num'] ?: 1, 2), 2); $list[] = [ 'index' => $i++, 'store_name' => $cart['productInfo']['store_name'], 'suk' => $cart['productInfo']['attrInfo']['suk'], 'bar_code' => $cart['productInfo']['attrInfo']['bar_code'], 'code' => $cart['productInfo']['attrInfo']['code'], 'truePrice' => sprintf("%.2f", $cart['sum_price']), 'cart_num' => $cart['cart_num'], 'subtotal' => bcmul((string)$cart['sum_price'], (string)$cart['cart_num'], 2) ]; } $order['user_address'] = str_replace(' ', '', $order['user_address']); $order['vip_true_price'] = $vipTruePrice; $order['list'] = $list; } return $orderList; } /** * 供应商首页头部统计 * @param int $supplierId * @param array $time * @return array */ public function homeStatics(int $supplierId, array $time): array { $data = []; $where = ['time' => $time, 'supplier_id' => $supplierId]; if ($supplierId < 1) { $where['supplier_id'] = -1; } $orderWhere = ['paid' => 1, 'is_system_del' => 0, 'refund_status' => 0]; $refundWhere = ['refund_type' => 6]; // 订单金额 $data['pay_price'] = $this->dao->sum($where + $orderWhere, 'pay_price', true); // 订单量 $data['pay_count'] = $this->dao->count($where + $orderWhere); /** @var StoreOrderRefundServices $orderRefundServices */ $orderRefundServices = app()->make(StoreOrderRefundServices::class); // 退款金额 $data['refund_price'] = $orderRefundServices->sum($where + $refundWhere, 'refund_price', true); // 退款订单数 $data['refund_count'] = $orderRefundServices->count($where + $refundWhere); return $data; } /** * 订单图表 * @param int $supplierId * @param array $time * @return array */ public function orderCharts(int $supplierId, array $time): array { if (is_int($time[0]) && is_int($time[1])) { $dayCount = (strtotime(date('Y/m/d', $time[1])) - strtotime(date('Y/m/d', $time[0]))) / 86400 + 1; } else { $time[0] = strtotime($time[0]); $time[1] = strtotime($time[1]); $dayCount = ($time[1] - $time[0]) / 86400 + 1; } if ($dayCount == 1) { $num = 0; } elseif ($dayCount > 1 && $dayCount <= 31) { $num = 1; } elseif ($dayCount > 31 && $dayCount <= 92) { $num = 3; } elseif ($dayCount > 92) { $num = 30; } if ($supplierId) { $where = ['supplier_id' => $supplierId]; } else { $where = [['supplier_id', '>', 0]]; } $data = $xAxis = $series = []; if ($num == 0) { $xAxis = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23']; $timeType = '%H'; } elseif ($num != 0) { $dt_start = $time[0]; $dt_end = $time[1]; while ($dt_start <= $dt_end) { if ($num == 30) { $xAxis[] = date('Y-m', $dt_start); $dt_start = strtotime("+1 month", $dt_start); $timeType = '%Y-%m'; } else { $xAxis[] = date('m-d', $dt_start); $dt_start = strtotime("+$num day", $dt_start); $timeType = '%m-%d'; } } } $pay_price = array_column($this->dao->getOrderStatistics($where, $time, $timeType, 'add_time', 'sum(pay_price)', 'pay'), 'num', 'days'); $pay_count = array_column($this->dao->getOrderStatistics($where, $time, $timeType, 'add_time', 'count(id)', 'pay'), 'num', 'days'); $refund_price = array_column($this->dao->getOrderStatistics($where, $time, $timeType, 'add_time', 'sum(refund_price)', 'refund'), 'num', 'days'); $refund_count = array_column($this->dao->getOrderStatistics($where, $time, $timeType, 'add_time', 'count(id)', 'refund'), 'num', 'days'); foreach ($xAxis as $item) { $data['订单金额'][] = isset($pay_price[$item]) ? floatval($pay_price[$item]) : 0; $data['订单量'][] = isset($pay_count[$item]) ? floatval($pay_count[$item]) : 0; $data['退款金额'][] = isset($refund_price[$item]) ? floatval($refund_price[$item]) : 0; $data['退款订单量'][] = isset($refund_count[$item]) ? floatval($refund_count[$item]) : 0; } foreach ($data as $key => $item) { $series[] = [ 'name' => $key, 'data' => $item, 'type' => 'line', ]; } return compact('xAxis', 'series'); } /** * 订单来源 * @param int $supplierId * @param array string * @return array */ public function getOrderChannel(int $supplierId, array $time): array { $bing_xdata = ['公众号', '小程序', 'H5', 'PC', 'APP']; $color = ['#6DD230', '#FFAB2B', '#4BCAD5', '#1890FF', '#B37FEB']; $bing_data = []; if ($supplierId) { $where = ['supplier_id' => $supplierId]; } else { $where = ['supplier_id' => -1]; } foreach ($bing_xdata as $key => $item) { $bing_data[] = [ 'name' => $item, 'value' => $this->dao->count(['paid' => 1, 'pid' => 0, 'is_channel' => $key, 'time' => $time] + $where), 'itemStyle' => ['color' => $color[$key]] ]; } $list = []; $count = array_sum(array_column($bing_data, 'value')); foreach ($bing_data as $item) { $list[] = [ 'name' => $item['name'], 'value' => $item['value'], 'percent' => $count != 0 ? floatval(bcmul((string)bcdiv((string)$item['value'], (string)$count, 4), '100', 2)) : 0, ]; } array_multisort(array_column($list, 'value'), SORT_DESC, $list); return compact('bing_xdata', 'bing_data', 'list'); } /** * 订单类型 * @param int $supplierId * @param array string * @return array */ public function getOrderType(int $supplierId, array $time): array { $bing_xdata = [0 => '普通订单', 1 => '秒杀订单', 2 => '砍价订单', 3 => '拼团订单', 4 => '', 5 => '套餐订单', 6 => '', 7 => '新人专享']; $order_type = [0 => '0', 1 => '1', 2 => '2', 3 => '3', 4 => '', 5 => '4', 6 => '6' , 7 => '9']; $color = ['#64a1f4', '#3edeb5', '#70869f', '#ffc653', '', '#fc7d6a', '#fc7d2a', '']; $bing_data = []; if ($supplierId) { $where = ['supplier_id' => $supplierId]; } else { $where = ['supplier_id' => -1]; } foreach ($bing_xdata as $key => $item) { if (empty($item)) continue; $bing_data[] = [ 'name' => $item, 'value' => $this->dao->together(['paid' => 1, 'pid' => 0, 'type' => $order_type[$key] ?? 0, 'time' => $time] + $where, 'pay_price', 'sum'), 'itemStyle' => ['color' => $color[$key]] ]; } $list = []; $count = array_sum(array_column($bing_data, 'value')); foreach ($bing_data as $item) { $list[] = [ 'name' => $item['name'], 'value' => $item['value'], 'percent' => $count != 0 ? floatval(bcmul((string)bcdiv((string)$item['value'], (string)$count, 4), '100', 2)) : 0, ]; } unset($bing_xdata[4]); $bing_xdata = array_values($bing_xdata); array_multisort(array_column($list, 'value'), SORT_DESC, $list); return compact('bing_xdata', 'bing_data', 'list'); } /** * 提醒发货 * @param int $supplierId * @param int $id * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ public function deliverRemind(int $supplierId, int $id) { $expire = 600; $val = time() + $expire; $order = $this->dao->get($id); if (!$order) { throw new ValidateException('订单不存在'); } $order = $order->toArray(); $cacheName = 'order_deliver_remind_' . $id; if (CacheService::has($cacheName)) { $interval = CacheService::get($cacheName); $remain = $interval - time(); if ($remain > 0) { throw new ValidateException('请' . ceil($remain / 60) . '分钟后再次提醒'); } CacheService::delete($cacheName); } else { CacheService::set($cacheName, $val, $expire); } //向供应商后台发送待发货订单消息 try { /** @var NoticeSmsService $NoticeSms */ $NoticeSms = app()->make(NoticeSmsService::class); $mark = 'admin_pay_success_code'; $NoticeSms->setEvent($mark)->sendAdminPaySuccess($order); SocketPush::instance()->setUserType('supplier')->to($supplierId)->type('WAIT_DELIVER_ORDER')->data(['order_id' => $order['order_id']])->push(); } catch (\Throwable $e) { Log::error('向供应商发送提醒发货消息失败,失败原因:' . $e->getMessage()); } return true; } }