Order.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. namespace app\api\controller\inspection;
  3. use app\api\controller\inspection\Base;
  4. use app\common\Service\OrderService;
  5. use app\common\Enum\OrderEnum;
  6. use app\common\Service\OrderActionService;
  7. use app\common\Enum\OrderActionEnum;
  8. use app\common\Service\Order\OrderShipService;
  9. /**
  10. * 验货端订单接口
  11. *
  12. * 包含功能:
  13. * - 订单详情查询
  14. * - 订单列表查询
  15. * - 订单发货确认
  16. * - 订单统计功能(按日/月/年统计)
  17. * - 订单趋势数据
  18. *
  19. * 统计功能说明:
  20. * - 验收订单:已验货通过的订单
  21. * - 退回订单:验货不通过的订单
  22. * - 售后订单:退款相关的订单
  23. */
  24. class Order extends Base
  25. {
  26. protected $noNeedLogin = [];
  27. //订单详情
  28. public function detail()
  29. {
  30. // 验证请求参数
  31. $validate = new \app\api\validate\Order();
  32. $orderId = $this->request->get('orderId');
  33. $params = ['orderId' => $orderId];
  34. if (!$validate->scene('detail')->check($params)) {
  35. $this->error($validate->getError());
  36. }
  37. // 获取当前验货员所属的供应商ID
  38. $supplierId = $this->application->supplier_id;
  39. if (!$supplierId) {
  40. $this->error('您未绑定供应商');
  41. }
  42. // 使用供应商订单详情方法,只获取该供应商的商品
  43. $order = OrderService::getSupplierOrderDetail($orderId, $supplierId, $this->auth->id);
  44. if (empty($order)) {
  45. $this->error('未找到订单或该订单不包含您供应商的商品');
  46. }
  47. /** @var \app\common\model\Order $order */
  48. //$order->append(['order_status_text']);
  49. $address = OrderService::getAddressInfo($orderId);
  50. $order->address = $address;
  51. // $order->append(['status_text']);
  52. // $order->hidden(explode(',', 'method,transactionid,updatetime,deletetime'));
  53. // $order->expiretime = $order->expiretime - time();
  54. $order->order_status_text = OrderEnum::STATUS_TEXT_MAP_INSPECTION[$order->order_status];
  55. $this->success('', $order);
  56. }
  57. //订单列表
  58. public function index()
  59. {
  60. // 验证请求参数
  61. $validate = new \app\api\validate\inspection\Order();
  62. $param = $this->request->param();
  63. $param['time_range'] = '1'; // 添加触发时间范围验证的字段
  64. if (!$validate->scene('lists')->check($param)) {
  65. $this->error($validate->getError());
  66. }
  67. // 设置默认值
  68. $userId = 0;
  69. $param['page'] = $param['page'] ?? 1;
  70. $param['page_size'] = $param['page_size'] ?? 10;
  71. $status = $param['status'] ?? 0; // 默认为0(全部订单)
  72. $param['keywords'] = $param['keywords'] ?? '';
  73. $status = OrderEnum::SHOW_INSPECTION_TYPE_STATUS_MAP[$status];
  74. // 查询对应的工厂 信息
  75. $supplierId = $this->application->supplier_id;
  76. $list = OrderService::getSupplierOrderList($supplierId ,$userId, $param, $status);
  77. foreach ($list as $item) {
  78. // $item->append(['order_status_text']);
  79. $field = 'id,order_sn,amount,goods_price,order_amount,express_name,express_no,order_goods,order_status_text,order_status';
  80. $item->visible(explode(',', $field));
  81. $item->order_status_text = OrderEnum::STATUS_TEXT_MAP_INSPECTION[$item->order_status];
  82. }
  83. $this->success('获取成功', $list);
  84. }
  85. //确认发货
  86. public function send()
  87. {
  88. // 验证请求参数
  89. $userId = $this->auth->id;
  90. $validate = new \app\api\validate\inspection\Order();
  91. $params = [
  92. 'order_id' => $this->request->post('order_id'),
  93. 'order_goods_id' => $this->request->post('order_goods_id'),
  94. 'express_name' => $this->request->post('express_name'),
  95. 'express_no' => $this->request->post('express_no'),
  96. 'express_image' => $this->request->post('express_image/a', [])
  97. ];
  98. if (!$validate->scene('send')->check($params)) {
  99. $this->error($validate->getError());
  100. }
  101. $orderId = intval($params['order_id'] ?? 0);
  102. $orderGoodsId = intval($params['order_goods_id'] ?? 0);
  103. if (empty($orderId)) {
  104. $this->error('订单ID不能为空');
  105. }
  106. if (empty($orderGoodsId)) {
  107. $this->error('订单商品ID不能为空');
  108. }
  109. // 验证订单商品是否可以发货
  110. $orderData = OrderService::validateOrderGoodsForDelivery($orderId, $orderGoodsId);
  111. if (!$orderData) {
  112. $this->error('订单或订单商品不存在,或不允许发货');
  113. }
  114. $order = $orderData['order'];
  115. $orderGoods = $orderData['order_goods'];
  116. // 验证权限(根据业务需求,这里可能需要验证供应商权限而不是用户权限)
  117. if ($order->user_id != $this->auth->id) {
  118. $this->error('该订单不属于当前用户');
  119. }
  120. $expressName = trim($params['express_name'] ?? '');
  121. $expressNo = trim($params['express_no'] ?? '');
  122. $expressImage = $params['express_image'] ?? [];
  123. // 1. 更新订单商品发货状态
  124. $result = OrderService::updateOrderGoodsDeliveryStatus($orderGoodsId, $expressName, $expressNo, $expressImage);
  125. if (!$result) {
  126. $this->error('更新订单商品发货状态失败');
  127. }
  128. // 2. 检查并更新订单状态
  129. OrderService::updateOrderStatusByDeliveryResult($orderId, $userId);
  130. // 3. 记录操作日志
  131. $orderActionService = new OrderActionService();
  132. $orderActionService->addInspectionAction(
  133. $order->order_sn,
  134. OrderActionEnum::ACTION_SHIP,
  135. $userId,
  136. '订单商品发货,商品:' . $orderGoods->goods_title . ',快递公司:' . $expressName . ',快递单号:' . $expressNo,
  137. $userId,
  138. [
  139. 'order_goods_id' => $orderGoodsId,
  140. 'goods_title' => $orderGoods->goods_title,
  141. 'express_name' => $expressName,
  142. 'express_no' => $expressNo,
  143. ]
  144. );
  145. $this->success('发货成功');
  146. }
  147. // 统计订单
  148. public function statistics()
  149. {
  150. // 验证请求参数
  151. $validate = new \app\api\validate\Order();
  152. $params = [
  153. 'type' => $this->request->param('type', 'day'),
  154. 'date' => $this->request->param('date', date('Y-m-d'))
  155. ];
  156. if (!$validate->scene('statistics')->check($params)) {
  157. $this->error($validate->getError());
  158. }
  159. // 获取验证后的参数
  160. $type = $params['type'];
  161. $date = $params['date'];
  162. // 根据类型处理日期和时间范围
  163. switch ($type) {
  164. case 'day':
  165. $startTime = strtotime($date . ' 00:00:00');
  166. $endTime = strtotime($date . ' 23:59:59');
  167. $displayDate = date('m-d', $startTime);
  168. // 前一天
  169. $prevStartTime = strtotime($date . ' 00:00:00') - 86400;
  170. $prevEndTime = strtotime($date . ' 23:59:59') - 86400;
  171. break;
  172. case 'month':
  173. $startTime = strtotime(date('Y-m-01 00:00:00', strtotime($date)));
  174. $endTime = strtotime(date('Y-m-t 23:59:59', strtotime($date)));
  175. $displayDate = date('Y-m', $startTime);
  176. // 前一个月
  177. $prevStartTime = strtotime(date('Y-m-01 00:00:00', strtotime($date . ' -1 month')));
  178. $prevEndTime = strtotime(date('Y-m-t 23:59:59', strtotime($date . ' -1 month')));
  179. break;
  180. case 'year':
  181. $startTime = strtotime(date('Y-01-01 00:00:00', strtotime($date)));
  182. $endTime = strtotime(date('Y-12-31 23:59:59', strtotime($date)));
  183. $displayDate = date('Y', $startTime) . '年';
  184. // 前一年
  185. $prevStartTime = strtotime(date('Y-01-01 00:00:00', strtotime($date . ' -1 year')));
  186. $prevEndTime = strtotime(date('Y-12-31 23:59:59', strtotime($date . ' -1 year')));
  187. break;
  188. }
  189. // 获取当前用户ID
  190. $userId = $this->auth->id;
  191. // 如果需要根据工厂统计,可以在这里添加工厂相关逻辑
  192. // 目前先按用户统计,后续可以根据实际的工厂关联字段进行调整
  193. // 当前期间统计
  194. $currentStats = $this->getOrderStatistics($userId, $startTime, $endTime);
  195. // 上期统计(用于对比)
  196. $prevStats = $this->getOrderStatistics($userId, $prevStartTime, $prevEndTime);
  197. // 计算增长率
  198. $growthRate = [
  199. 'inspection_rate' => $this->calculateGrowthRate($prevStats['inspection_count'], $currentStats['inspection_count']),
  200. 'return_rate' => $this->calculateGrowthRate($prevStats['return_count'], $currentStats['return_count']),
  201. 'aftersale_rate' => $this->calculateGrowthRate($prevStats['aftersale_count'], $currentStats['aftersale_count'])
  202. ];
  203. // 返回统计数据
  204. $data = [
  205. 'date' => $displayDate,
  206. 'type' => $type,
  207. 'current_period' => $currentStats,
  208. 'previous_period' => $prevStats,
  209. 'growth_rate' => $growthRate,
  210. 'statistics' => [
  211. 'inspection_count' => $currentStats['inspection_count'],
  212. 'return_count' => $currentStats['return_count'],
  213. 'aftersale_count' => $currentStats['aftersale_count']
  214. ]
  215. ];
  216. $this->success('统计数据获取成功', $data);
  217. }
  218. /**
  219. * 获取订单统计数据
  220. */
  221. private function getOrderStatistics($userId, $startTime, $endTime)
  222. {
  223. // 统计验收订单(验货通过)
  224. $inspectionCount = \app\common\model\Order::where('user_id', $userId)
  225. ->where('order_status', OrderEnum::STATUS_INSPECTION_PASS)
  226. ->where('createtime', '>=', $startTime)
  227. ->where('createtime', '<=', $endTime)
  228. ->count();
  229. // 统计退回订单(验货不通过)
  230. $returnCount = \app\common\model\Order::where('user_id', $userId)
  231. ->where('order_status', OrderEnum::STATUS_INSPECTION_FAIL)
  232. ->where('createtime', '>=', $startTime)
  233. ->where('createtime', '<=', $endTime)
  234. ->count();
  235. // 统计待验收订单
  236. $aftersaleCount = \app\common\model\Order::where('user_id', $userId)
  237. ->whereIn('order_status', [OrderEnum::STATUS_PAY])
  238. ->where('createtime', '>=', $startTime)
  239. ->where('createtime', '<=', $endTime)
  240. ->count();
  241. return [
  242. 'inspection_count' => $inspectionCount,
  243. 'return_count' => $returnCount,
  244. 'aftersale_count' => $aftersaleCount
  245. ];
  246. }
  247. /**
  248. * 计算增长率
  249. */
  250. private function calculateGrowthRate($prevValue, $currentValue)
  251. {
  252. if ($prevValue == 0) {
  253. return $currentValue > 0 ? 100 : 0;
  254. }
  255. return round((($currentValue - $prevValue) / $prevValue) * 100, 2);
  256. }
  257. /**
  258. * 获取统计数据的时间范围选择
  259. */
  260. public function getStatisticsDateRange()
  261. {
  262. // 获取最早和最晚的订单时间
  263. $userId = $this->auth->id;
  264. $earliest = \app\common\model\Order::where('user_id', $userId)
  265. ->order('createtime', 'asc')
  266. ->value('createtime');
  267. $latest = \app\common\model\Order::where('user_id', $userId)
  268. ->order('createtime', 'desc')
  269. ->value('createtime');
  270. $data = [
  271. 'earliest_date' => $earliest ? date('Y-m-d', $earliest) : date('Y-m-d'),
  272. 'latest_date' => $latest ? date('Y-m-d', $latest) : date('Y-m-d'),
  273. 'current_date' => date('Y-m-d'),
  274. 'current_month' => date('Y-m'),
  275. 'current_year' => date('Y')
  276. ];
  277. $this->success('日期范围获取成功', $data);
  278. }
  279. /**
  280. * 获取历史趋势数据
  281. */
  282. public function getTrendData()
  283. {
  284. // 验证请求参数
  285. $validate = new \app\api\validate\Order();
  286. $params = [
  287. 'type' => $this->request->param('type', 'day'),
  288. 'days' => $this->request->param('days', 7)
  289. ];
  290. if (!$validate->scene('trend')->check($params)) {
  291. $this->error($validate->getError());
  292. }
  293. // 获取验证后的参数
  294. $type = $params['type'];
  295. $days = $params['days'];
  296. $userId = $this->auth->id;
  297. $trendData = [];
  298. for ($i = $days - 1; $i >= 0; $i--) {
  299. $date = date('Y-m-d', strtotime("-{$i} days"));
  300. $startTime = strtotime($date . ' 00:00:00');
  301. $endTime = strtotime($date . ' 23:59:59');
  302. $stats = $this->getOrderStatistics($userId, $startTime, $endTime);
  303. $trendData[] = [
  304. 'date' => $date,
  305. 'display_date' => date('m-d', $startTime),
  306. 'inspection_count' => $stats['inspection_count'],
  307. 'return_count' => $stats['return_count'],
  308. 'aftersale_count' => $stats['aftersale_count']
  309. ];
  310. }
  311. $this->success('趋势数据获取成功', $trendData);
  312. }
  313. // 获取快递公司列表
  314. public function getExpressCompany(){
  315. $list = OrderShipService::getExpressCompany();
  316. $this->success('快递公司列表获取成功', $list);
  317. }
  318. }