diff --git a/app/Constants/v3/SsdbKeys.php b/app/Constants/v3/SsdbKeys.php index c2b85bd..e6f6eca 100644 --- a/app/Constants/v3/SsdbKeys.php +++ b/app/Constants/v3/SsdbKeys.php @@ -29,7 +29,12 @@ class SsdbKeys extends AbstractConstants * @Message("用户新订单统计") */ const USER_ORDER_BADGE = 'user_order_badge_'; - + + /** + * @Message("店铺新订单统计") + */ + const STORE_ORDER_BADGE = 'store_order_badge_'; + /** * @Message("收藏店铺") */ diff --git a/app/Controller/v3/BalanceStatementController.php b/app/Controller/v3/BalanceStatementController.php index 9e19de9..b8c0829 100644 --- a/app/Controller/v3/BalanceStatementController.php +++ b/app/Controller/v3/BalanceStatementController.php @@ -27,6 +27,10 @@ class BalanceStatementController extends BaseController $pagesize = $this->request->input('pagesize',0); $startTime = $this->request->input('start_time',''); $endTime = $this->request->input('end_time',''); + if(!empty($startTime) && !empty($endTime)){ + $startTime = strtotime(date($startTime.' 00:00:00')); + $endTime = strtotime(date($endTime.' 23:59:59')); + } return $this->success($this->revenueListService->getListByUser($userId, $page, $pagesize ,$startTime,$endTime)); } @@ -37,6 +41,10 @@ class BalanceStatementController extends BaseController $pagesize = $this->request->input('pagesize',0); $startTime = $this->request->input('start_time',''); $endTime = $this->request->input('end_time',''); + if(!empty($startTime) && !empty($endTime)){ + $startTime = strtotime(date($startTime.' 00:00:00')); + $endTime = strtotime(date($endTime.' 23:59:59')); + } $res = $this->withdrawalListService->getListByStore($storeId,$page,$pagesize,$startTime,$endTime); return $this->success($res); } diff --git a/app/Controller/v3/HomeController.php b/app/Controller/v3/HomeController.php index 80ce4de..ce46208 100644 --- a/app/Controller/v3/HomeController.php +++ b/app/Controller/v3/HomeController.php @@ -4,9 +4,12 @@ namespace App\Controller\v3; use App\Constants\v3\ActivityType; use App\Constants\v3\Banner; +use App\Constants\v3\OrderState; +use App\Constants\v3\OrderType; use App\Constants\v3\SsdbKeys; use App\Constants\v3\Tabs; use App\Controller\BaseController; +use App\Model\v3\FinancialRecord; use App\Request\v3\StoreIndexRequest; use App\Request\v3\UserIndexRequest; use App\Service\v3\Interfaces\ActivityServiceInterface; @@ -14,6 +17,9 @@ use App\Service\v3\Interfaces\BannerServiceInterface; use App\Service\v3\Interfaces\CategoryServiceInterface; use App\Service\v3\Interfaces\CollectStoreServiceInterface; use App\Service\v3\Interfaces\CouponServiceInterface; +use App\Service\v3\Interfaces\OrderOnlineServiceInterface; +use App\Service\v3\Interfaces\OrderStatisticsServiceInterface; +use App\Service\v3\Interfaces\RevenueListServiceInterface; use App\Service\v3\Interfaces\StoreServiceInterface; use App\Service\v3\Interfaces\TabsServiceInterface; use App\Service\v3\Interfaces\UserCenterBlockServiceInterface; @@ -85,6 +91,17 @@ class HomeController extends BaseController */ protected $tabsService; + /** + * @Inject + * @var OrderStatisticsServiceInterface + */ + protected $orderStatisticsService; + + /** + * @Inject + * @var RevenueListServiceInterface + */ + protected $revenueListService; /** * 小程序首页,根据market_id * 1.banner数据 @@ -178,21 +195,56 @@ class HomeController extends BaseController public function storeIndex(StoreIndexRequest $request) { $params = $request->validated(); + //每日 每周 每月 开始结束时间 + $dayStartTime = strtotime(date('Y-m-d'.' 00:00:00')); + $dayEndTime = strtotime(date('Y-m-d'.' 23:59:59')); + $weekStartTime = mktime(0,0,0,date('m'),date('d')-date('N')+1,date('y')); + //$weekEndTime = mktime(23,59,59,date('m'),date('d')-date('N')+7,date('Y')); + $monthStartTime = mktime(0,0,0,date('m'),1,date('Y')); + //$monthEndTime = mktime(23,59,59,date('m'),date('t'),date('Y')); $data['detail'] = $this->storeService->detail($params['store_id']); - $data['order_online'] = [ - 'count' => 6549, - 'total' => 12654.12 - ]; - $data['order_offline'] = [ - 'count' => 3639, - 'total' => 89563.12 + //当面付 and 线上订单个数统计 + $data['order_online']['count'] = $this->orderStatisticsService->countOrder($params['store_id'],OrderType::ONLINE,$dayStartTime,$dayEndTime); + $data['order_offline']['count'] = $this->orderStatisticsService->countOrder($params['store_id'],OrderType::OFFLINE,$dayStartTime,$dayEndTime); + //统计订单金额 + $type = [ + FinancialRecord::MONEY_TYPE_STORE_OL_ORDER_COMP, + FinancialRecord::MONEY_TYPE_STORE_OFL_ORDER_COMP ]; + $data['order_online']['total'] = 0; + $data['order_offline']['total'] = 0; + $revenueByOrder = $this->revenueListService->getRevenueByUser($params['user_id'],$type,$dayStartTime,$dayEndTime); + foreach ($revenueByOrder as $order){ + if($order['money_type'] == FinancialRecord::MONEY_TYPE_STORE_OL_ORDER_COMP){ + //线上订单 + $data['order_online']['total'] = bcadd($data['order_online']['total'],$order['money'],2); + }else if($order->money_type == FinancialRecord::MONEY_TYPE_STORE_OFL_ORDER_COMP){ + //线下订单 + $data['order_offline']['total'] = bcadd($data['order_online']['total'],$order['money'],2); + } + } + //统计新增用户 无法筛选时间 所以和订单分开查询 + $revenueByNewUsers = $this->revenueListService->getRevenueByUser($params['user_id'],[FinancialRecord::MONEY_TYPE_STORE_PLAT_NEW_USER]); $data['new_user'] = [ - 'day' => 10, - 'week' => 15, - 'month' => 25, - 'all' => 50 + 'day' => 0, + 'week' => 0, + 'month' => 0, + 'all' => 0 ]; + foreach ($revenueByNewUsers as $newUser) + { + if($newUser['created_at'] > $dayStartTime){ + $data['new_user']['day']++; + } + if($newUser['created_at'] > $weekStartTime){ + $data['new_user']['week']++; + } + if($newUser['created_at'] > $monthStartTime){ + $data['new_user']['month']++; + } + $data['new_user']['all']++; + } + $data['badge'] = [ 'unpaid' => 0, 'receiving' => 0, diff --git a/app/Controller/v3/OrderOnlineController.php b/app/Controller/v3/OrderOnlineController.php index 7f90422..4924fad 100644 --- a/app/Controller/v3/OrderOnlineController.php +++ b/app/Controller/v3/OrderOnlineController.php @@ -87,10 +87,9 @@ class OrderOnlineController extends BaseController throw new ErrorCodeException(ErrorCode::NOT_BIND_TEL_ERROR); } //获取用户收货地址 - $address = UserAddress::query()->where([ - ['user_id','=',$userId], - ['is_default','=',1], - ]) + $address = UserAddress::query()->where('user_id',$userId) + ->orderByDesc('is_default') + ->orderByDesc('updated_at') ->first(); $res['location'] = [ 'address' => $address, diff --git a/app/JsonRpc/OrderService.php b/app/JsonRpc/OrderService.php index 530d09e..ff94798 100644 --- a/app/JsonRpc/OrderService.php +++ b/app/JsonRpc/OrderService.php @@ -8,10 +8,14 @@ use App\Constants\v3\LogLabel; use App\Constants\v3\OrderState; use App\Exception\ErrorCodeException; use App\Model\v3\Order; +use App\Model\v3\OrderGoods; use App\Model\v3\OrderMain; use App\Service\v3\Interfaces\OrderOnlineServiceInterface; use App\Service\v3\Interfaces\SeparateAccountsServiceInterface; +use EasyWeChat\Factory; +use EasyWeChat\Kernel\Exceptions\InvalidConfigException; use Hyperf\DbConnection\Db; +use Hyperf\Guzzle\CoroutineHandler; use Hyperf\RpcServer\Annotation\RpcService; use Hyperf\Di\Annotation\Inject; use function AlibabaCloud\Client\json; @@ -105,53 +109,142 @@ class OrderService implements OrderServiceInterface * 退2元商品时,退款金额为 * 红包 :(2/(98+2))*10 = 0.2 * 退款:2-0.2=1.8元 - * @param $user_id *用户ID + * @param $user_id *用户ID * @param $global_order_id *全局总订单ID - * @param $child_order_id *主订单ID, - * @param $order_goods_id *订单商品ID + * @param $order_child_id *主订单ID, + * @param $order_goods_id *订单商品ID * @param $note + * @throws InvalidConfigException */ - public function onlineSingleRefund($user_id, $note, $global_order_id, $child_order_id = null, $order_goods_id = null) + public function onlineSingleRefund($user_id, $note, $global_order_id, $order_child_id=null, $order_goods_id=null) { + + $params = [ + 'user_id' => $user_id, + 'note' => $note, + 'global_order_id' => $global_order_id, + 'order_child_id' => $order_child_id, + 'order_goods_id' => $order_goods_id, + ]; + if (!$user_id || !$global_order_id || !$note) { $this->log->event(LogLabel::ORDER_REFUND_LOG, [ 'jsonrpc_order_service_exception_onlineSingleRefund' => '参数不对', - 'params' => json([$global_order_id, $user_id, $note]) + 'params' => json_encode($params) ]); throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); } // 主订单 $orderMain = OrderMain::query() - ->where(['global_order_id' => $global_order_id]) + ->where(['global_order_id' => $global_order_id, 'user_id' => $user_id]) ->whereIn('state', OrderState::CAN_REFUND_DIRECT) ->first(); - if (empty($orderMain)) { + if (is_null($orderMain)) { $this->log->event(LogLabel::ORDER_REFUND_LOG, [ 'jsonrpc_order_service_exception_onlineSingleRefund' => '订单不存在', - 'params' => json([$global_order_id, $user_id, $note]) + 'params' => json_encode($params) ]); throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); } // 子订单 - if ($child_order_id) { - $orderChild = Order::query()->where(['order_main_id' => $orderMain->global_order_id])->first(); + $orderChild = null; + if ($order_child_id) { + $orderChild = Order::query()->where(['order_main_id' => $orderMain->global_order_id, 'id' => $order_child_id])->first(); } - // 单商品退 + // 订单商品 + $orderGoods = null; if ($order_goods_id) { - if (!$child_order_id) { + if (!$order_child_id || is_null($orderChild)) { $this->log->event(LogLabel::ORDER_REFUND_LOG, [ - 'jsonrpc_order_service_exception_onlineSingleRefund' => '参数不对[单品]', - 'params' => json([$global_order_id, $user_id, $note, $child_order_id]) + 'jsonrpc_order_service_exception_onlineSingleRefund' => '子订单参数异常[单品]', + 'params' => json_encode($params) ]); throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); } + $orderGoods = OrderGoods::query()->where(['order_id' => $orderChild->id, 'id' => $order_goods_id])->first(); + + if (is_null($orderGoods)) { + $this->log->event(LogLabel::ORDER_REFUND_LOG, [ + 'jsonrpc_order_service_exception_onlineSingleRefund' => '订单商品参数异常[单品]', + 'params' => json_encode($params) + ]); + throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); + } + + } + + $totalAmount = $orderMain->total_money; // 订单可退款金额,总订单金额不含配送费和服务费 + $preRefundAmount = 0; // 预退款金额 + $refundAmount = 0; // 实际退款金额 + $refundType = 'Main'; // 退款类型, Main整单 Sub子单 Goods单品 + if ($orderGoods) { // 1. 如果订单商品存在则说明要退单品 + $preRefundAmount = bcmul($orderGoods->price, $orderGoods->number, 2); + $refundType = 'Goods'; + } elseif ($orderChild) { // 2. 否则如果存在子订单说明退子订单 + $preRefundAmount = $orderChild->money; + $refundType = 'Sub'; + } else { // 3. 再则如果存在主订单说明退主订单 + $preRefundAmount = $orderMain->total_money; + $refundType = 'Main'; + } + + // 占订单金额的比例 + $rate = bcdiv($preRefundAmount, $totalAmount, 6); + // 计算优惠券所占金额 + $couponMoney = bcmul($orderMain->coupon_money, $rate, 6); + // 计算本次退款实际退款金额 + $refundAmount = bcsub($preRefundAmount, $couponMoney, 2); + + if ($refundAmount <= 0) { + $this->log->event(LogLabel::ORDER_REFUND_LOG, [ + 'jsonrpc_order_service_exception_onlineSingleRefund' => '没有可退款金额[实际退款金额]', + 'params' => json_encode($params) + ]); + throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); + } + // 开始退款 + $config = config('wxpay'); + $app = Factory::payment($config); + $app['guzzle_handler'] = CoroutineHandler::class; + $result = $app->refund->byOutTradeNumber( + $orderMain->global_order_id, + $orderMain->global_order_id, + bcmul($orderMain->money, 100, 0), + bcmul($refundAmount, 100, 0), + [ + 'refund_desc' => '订单协商退款['.$refundType.']', + 'notify_url' => config('wechat.notify_url.refund_single'), + ] + ); + + if ($result['return_code'] == 'FAIL') { + $this->log->event(LogLabel::ORDER_REFUND_LOG, [ + 'jsonrpc_order_service_exception_onlineSingleRefund' => $result['return_msg'].'[微信退款失败]', + 'params' => json_encode($result) + ]); + throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); } + if ($result['result_code'] == 'FAIL') { + $this->log->event(LogLabel::ORDER_REFUND_LOG, [ + 'jsonrpc_order_service_exception_onlineSingleRefund' => $result['err_code_des'].'[微信退款失败]'.$result['err_code'], + 'params' => json_encode($result) + ]); + throw new ErrorCodeException(ErrorCode::ORDER_REFUND_FAIL); + } + + // 退款申请成功,查询退款状态 + $refundResult = $app->refund->queryByRefundId($result['refund_id']); + $this->log->event(LogLabel::ORDER_REFUND_LOG, [ + 'jsonrpc_order_service_exception_onlineSingleRefund' => '[微信退款查询]', + 'params' => json_encode($refundResult) + ]); + } } \ No newline at end of file diff --git a/app/Model/v3/OrderMain.php b/app/Model/v3/OrderMain.php index 01134a4..c3abfc8 100644 --- a/app/Model/v3/OrderMain.php +++ b/app/Model/v3/OrderMain.php @@ -72,6 +72,12 @@ class OrderMain extends Model public function getStateTextAttribute() { + if ($this->attributes['state'] == 3) { + if (!$this->attributes['horseman_id']) { + return '已接单'; + } + } + return OrderState::getMessage($this->attributes['state']); } diff --git a/app/Service/v3/Implementations/DistributionPriceService.php b/app/Service/v3/Implementations/DistributionPriceService.php index 0e4fffe..5075b57 100644 --- a/app/Service/v3/Implementations/DistributionPriceService.php +++ b/app/Service/v3/Implementations/DistributionPriceService.php @@ -3,6 +3,8 @@ namespace App\Service\v3\Implementations; +use App\Constants\v3\ErrorCode; +use App\Exception\ErrorCodeException; use Hyperf\Di\Annotation\Inject; use App\Service\v3\Interfaces\DistributionPriceServiceInterface; @@ -22,8 +24,7 @@ class DistributionPriceService implements DistributionPriceServiceInterface $distributionRrice = bcmul(1.50,($km-3),2); break; case ($km >= 10) : - $distributionRrice = bcmul(1.50,($km-3),2); - // throw new ErrorCodeException(ErrorCode::LOCATION_LONG_DISTANCE); + throw new ErrorCodeException(ErrorCode::LOCATION_LONG_DISTANCE); break; default: $distributionRrice = 0; diff --git a/app/Service/v3/Implementations/OrderListService.php b/app/Service/v3/Implementations/OrderListService.php index 7f60c5a..db7f6c7 100644 --- a/app/Service/v3/Implementations/OrderListService.php +++ b/app/Service/v3/Implementations/OrderListService.php @@ -68,7 +68,7 @@ class OrderListService implements OrderListServiceInterface public function onlineByStore($storeId, $tab, $page=1, $pagesize=10) { - $builder = Order::join('lanzu_order_main','lanzu_order.order_main_id','lanzu_order_main.id') + $builder = Order::join('lanzu_order_main','lanzu_order.order_main_id','lanzu_order_main.global_order_id') ->select( 'lanzu_order.*', 'lanzu_order_main.state', @@ -141,7 +141,7 @@ class OrderListService implements OrderListServiceInterface public function offlineByStore($storeId, $page=1, $pagesize=10 ,$start_time = '',$end_time = '') { - $builder = Order::join('lanzu_order_main','lanzu_order.order_main_id','lanzu_order_main.id') + $builder = Order::join('lanzu_order_main','lanzu_order.order_main_id','lanzu_order_main.global_order_id') ->where('store_id', $storeId) ->where('lanzu_order_main.type',4) ->with('user'); diff --git a/app/Service/v3/Implementations/OrderOnlineService.php b/app/Service/v3/Implementations/OrderOnlineService.php index 0e65411..7ee6c7a 100644 --- a/app/Service/v3/Implementations/OrderOnlineService.php +++ b/app/Service/v3/Implementations/OrderOnlineService.php @@ -472,6 +472,12 @@ class OrderOnlineService implements OrderOnlineServiceInterface // 记录用户中心的badge $ssdb->exec('hincr', SsdbKeys::USER_ORDER_BADGE.$orderMain->user_id, 'receiving', 1); + //记录商家中心的badge + $storeIds = array_values(array_column($orders, 'store_id')); + foreach ($storeIds as $storeId){ + $ssdb->exec('hincr', SsdbKeys::STORE_ORDER_BADGE . $storeId, 'paid', 1); + } + return true; } catch (Exception $e) { @@ -556,9 +562,4 @@ class OrderOnlineService implements OrderOnlineServiceInterface return $this->paymentService->undo($orderMain->global_order_id, $userId); } } - - public function countByStore($storeId) - { - $res['count'] = Order::query()->find(); - } } \ No newline at end of file diff --git a/app/Service/v3/Implementations/OrderStatisticsService.php b/app/Service/v3/Implementations/OrderStatisticsService.php new file mode 100644 index 0000000..99b14bb --- /dev/null +++ b/app/Service/v3/Implementations/OrderStatisticsService.php @@ -0,0 +1,39 @@ +where('lanzu_order.store_id',$storeId); + if(!empty($startTime) && !empty($endTime)){ + $builder->whereBetween('lanzu_order_main.created_at',[$startTime,$endTime]); + } + $count = $builder->whereIn('lanzu_order_main.state', OrderState::FINISH) + ->where('type',$type) + ->count(); + return $count; + } +} \ No newline at end of file diff --git a/app/Service/v3/Implementations/RevenueListService.php b/app/Service/v3/Implementations/RevenueListService.php index 6154e1f..d427b5f 100644 --- a/app/Service/v3/Implementations/RevenueListService.php +++ b/app/Service/v3/Implementations/RevenueListService.php @@ -36,4 +36,18 @@ class RevenueListService implements RevenueListServiceInterface $revenues = $paginate->toArray(); return ['has_more_pages' => $paginate->hasMorePages(), 'revenue_list' => $revenues['data']]; } + + public function getRevenueByUser($userId,$type = [],$startTime = '',$endTime = '') + { + $financialRecord = new FinancialRecord(); + $mod = bcmod((string)$userId, '5', 0); + $financialRecord->suffix($mod); + $builder = $financialRecord->where('user_id',$userId) + ->whereIn('money_type',$type); + if(!empty($startTime) && !empty($endTime)){ + $builder->whereBetween('created_at',[$startTime,$endTime]); + } + $revenue = $builder->select('money','money_type','created_at')->get()->toArray(); + return $revenue; + } } \ No newline at end of file diff --git a/app/Service/v3/Implementations/WithdrawalListService.php b/app/Service/v3/Implementations/WithdrawalListService.php index 1170a36..7ed2c9d 100644 --- a/app/Service/v3/Implementations/WithdrawalListService.php +++ b/app/Service/v3/Implementations/WithdrawalListService.php @@ -25,7 +25,7 @@ class WithdrawalListService implements WithdrawalListServiceInterface { $builder = StoreWithdrawal::query()->where('store_id',$storeId); if(!empty($startTime) && !empty($endTime)){ - $builder->whereBetween('created_at',[strtotime($startTime.' 23:59:59'),strtotime($endTime.' 23:59:59')]); + $builder->whereBetween('created_at',[$startTime,$endTime]); } $paginate = $builder->paginate($pagesize); $orders = $paginate->toArray(); diff --git a/app/Service/v3/Interfaces/OrderOnlineServiceInterface.php b/app/Service/v3/Interfaces/OrderOnlineServiceInterface.php index dfecb21..d396b1a 100644 --- a/app/Service/v3/Interfaces/OrderOnlineServiceInterface.php +++ b/app/Service/v3/Interfaces/OrderOnlineServiceInterface.php @@ -70,11 +70,4 @@ interface OrderOnlineServiceInterface * @return mixed */ public function doRefund($globalOrderId, $userId); - - /** - * 统计商户线上订单 - * @param $storeId - * @return mixed - */ - public function countByStore($storeId); } \ No newline at end of file diff --git a/app/Service/v3/Interfaces/OrderStatisticsServiceInterface.php b/app/Service/v3/Interfaces/OrderStatisticsServiceInterface.php new file mode 100644 index 0000000..b7a2227 --- /dev/null +++ b/app/Service/v3/Interfaces/OrderStatisticsServiceInterface.php @@ -0,0 +1,13 @@ + \App\Service\v3\Implementations\AttachmentService::class, \App\JsonRpc\PrintServiceInterface::class => \App\JsonRpc\FeieService::class, \App\JsonRpc\LocationServiceInterface::class => \App\JsonRpc\LocationService::class, + \App\Service\v3\Interfaces\OrderStatisticsServiceInterface::class => \App\Service\v3\Implementations\OrderStatisticsService::class, ];