model = new \app\admin\model\order\Order; $this->courseModel = new \app\admin\model\course\Course; } /** * 查看 */ public function index() { //当前是否为关联查询 $this->relationSearch = true; //设置过滤方法 $this->request->filter(['strip_tags', 'trim']); $itemName = input('item_name',''); //如果发送的来源是Selectpage,则转发到Selectpage if ($this->request->request('keyField')) { return $this->selectpage(); } list($where, $sort, $order, $offset, $limit) = $this->buildparams(); $model = $this->model->where($where); if($itemName){ $model = $model->where(function ($query) use ($itemName) { $query->where(function ($query) use ($itemName) { $query->whereExists(function ($query) use ($itemName) { $itemTableName = (new \app\admin\model\order\Item())->getQuery()->getTable(); $query->table($itemTableName)->where($itemTableName . '.order_no=order.order_no') ->where('item_name', 'like', "%{$itemName}%"); }); }); }); } $list = $model ->with(['user','item','item.detail']) ->order($sort, $order) ->paginate($limit); $rows = $list->toArray(); if(!empty($rows['data'])){ foreach ($rows['data'] as &$item){ $item['source'] = strtolower($item['source']); foreach ($item['item'] as &$goods){ $goods['detail'] = json_decode($goods['snapshoot'],true); // if($item['order_type'] == 'vipcard'){ // $goods['detail'] = json_decode($goods['snapshoot'],true); // }else{ // $goods['detail'] = $this->courseModel->structrue($goods['detail'],'decode'); // } } } } $result = array("total" => $rows['total'], "rows" => $rows['data']); return $this->success("获取成功",$result); } /** * 获取详情 * @param $id * @return mixed */ public function detail($orderNo = null){ if($orderNo==null){ $orderNo = input('order_no'); } $row = $this->model ->with(['log','user','item','item.detail']) ->where([ 'order_no'=>$orderNo ]) ->find(); $row->getRelation('user')->visible(\app\admin\model\User::$listShowField); if (!$row) { $this->error(__('No Results were found')); } $row = $row->toArray(); $row['log'] = array_reverse($row['log']); foreach ($row['item'] as $key => $goods){ $row['item'][$key]['detail'] = json_decode($goods['snapshoot'],true); // if($row['order_type'] == 'vipcard' || $row['order_type'] == 'exercises'){ // $row['item'][$key]['detail'] = json_decode($goods['snapshoot'],true); // }else{ // $row['item'][$key]['detail'] = $this->courseModel->structrue($goods['detail'],'decode'); // } // $row->getRelation('user')->visible(\app\admin\model\User::$listShowField); } $row['source'] = strtolower($row['source']); if($row['source'] == 'channels' && \app\common\library\Platform::getSystemType() == 'single' && \app\admin\library\project\App::isInstall('channels')){ //获取视频号订单信息 $row['channels'] = (new \app\admin\model\app\channels\Order())->getOrderDetail($orderNo); } // 实物商品获取收货信息和物流信息 if($row['order_type'] == 'physical'){ // 收货信息 $row['address'] = \app\common\model\app\physical\OrderAddress::getByOrderId($row['id']); // 物流信息 $expressModel = \app\common\model\app\physical\OrderExpress::where([ 'order_id' => $row['id'], 'uniacid' => UNIACID ])->find(); if($expressModel){ // 更新物流信息(5分钟缓存) $this->updateExpressInfo($expressModel); // 重新获取物流信息 $expressModel = \app\common\model\app\physical\OrderExpress::where([ 'order_id' => $row['id'], 'uniacid' => UNIACID ])->find(); $row['express'] = $expressModel->toArray(); // 获取物流轨迹 $row['express']['logs'] = $expressModel->getLogs(); } } return $this->success("获取成功",$row); } /** * 编辑 * * @param $ids * @return string * @throws DbException * @throws \think\Exception */ public function edit($orderNo = null) { if($orderNo==null){ $orderNo = input('order_no'); } $row = $this->model ->where([ 'order_no'=>$orderNo ]) ->find(); if (!$row) { $this->error(__('No Results were found')); } $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) { $this->error(__('You have no permission')); } $params = $this->request->post('row/a'); if (empty($params)) { $this->error(__('Parameter %s can not be empty', '')); } $params = $this->preExcludeFields($params); $result = false; Db::startTrans(); try { //是否采用模型验证 if ($this->modelValidate) { $name = str_replace("\\model\\", "\\validate\\", get_class($this->model)); $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate; $row->validateFailException()->validate($validate); } $result = $row->allowField(true)->save($params); Db::commit(); } catch (ValidateException|PDOException|Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if (false === $result) { $this->error(__('No rows were updated')); } $this->success("提交成功"); } /** * 获取辅助参数 * @return mixed */ public function getAttr(){ $attr = []; $attr["payTypeList"] = $this->model->getPayTypeList(); $attr["sourceList"] = $this->model->getSourceList(); $attr["sendTypeList"] = $this->model->getSendTypeList(); $attr["statusList"] = $this->model->getStatusList(); $attr["typeList"] = $this->model->getTypeList(); $attr["virtualPayList"] = $this->model->getVirtualPayList(); return $this->success("获取成功",$attr); } /** * 关闭订单 * @return void */ public function closeOrder($ids){ $ids = $ids ?: $this->request->post("ids"); if (empty($ids)) { $this->error(__('Parameter %s can not be empty', 'ids')); } $pk = $this->model->getPk(); $list = $this->model->where($pk, 'in', $ids)->select(); $count = 0; Db::startTrans(); try { foreach ($list as $item) { if($item['status'] == \app\common\constant\order\Status::STATUS_CLOSE){ continue; } $this->model->where([ 'id'=>$item['id'] ])->update([ 'status'=>\app\common\constant\order\Status::STATUS_CLOSE ]); $orderNo = $item['order_no']; //作废分佣金记录 \think\Hook::exec('app\\common\\behavior\\app\\agent\\Commission','cancelOrder',$orderNo); \app\common\model\order\Log::set($item['id'],"管理员关闭订单"); $count++; } Db::commit(); } catch (PDOException|Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($count) { $this->success("已成功变更{$count}条数据"); } $this->error(__('未变更任何数据')); } protected $exportIndex = 0; /** * 导出订单 * @return void */ public function export(){ set_time_limit(0); ini_set('memory_limit', '512M'); $this->relationSearch = true; $this->request->filter(['strip_tags', 'trim']); $itemName = input('item_name',''); list($where, $sort, $order, $offset, $limit, $page, $alias, $bind, $originWhere) = $this->buildparams(); $excelTitle = '订单列表【'.date('Y-m-d H:i',time()).'】'; $objPHPExcel = new \PHPExcel(); $objPHPExcel->getProperties() ->setTitle($excelTitle); $objPHPExcel->getActiveSheet()->setCellValue('A1', '订单号'); $objPHPExcel->getActiveSheet()->setCellValue('B1', '商品名称'); $objPHPExcel->getActiveSheet()->setCellValue('C1', '单价'); $objPHPExcel->getActiveSheet()->setCellValue('D1', '数量'); $objPHPExcel->getActiveSheet()->setCellValue('E1', '实收金额'); $objPHPExcel->getActiveSheet()->setCellValue('F1', '状态'); $objPHPExcel->getActiveSheet()->setCellValue('G1', '用户名'); $objPHPExcel->getActiveSheet()->setCellValue('H1', '手机号'); $objPHPExcel->getActiveSheet()->setCellValue('I1', '订单类型'); $objPHPExcel->getActiveSheet()->setCellValue('J1', '来源'); $objPHPExcel->getActiveSheet()->setCellValue('K1', '评级'); $objPHPExcel->getActiveSheet()->setCellValue('L1', '买家留言'); $objPHPExcel->getActiveSheet()->setCellValue('M1', '商家备注'); $objPHPExcel->getActiveSheet()->setCellValue('N1', '收货人'); $objPHPExcel->getActiveSheet()->setCellValue('O1', '收货手机'); $objPHPExcel->getActiveSheet()->setCellValue('P1', '收货地址'); $objPHPExcel->getActiveSheet()->setCellValue('Q1', '快递公司'); $objPHPExcel->getActiveSheet()->setCellValue('R1', '快递单号'); $objPHPExcel->getActiveSheet()->setCellValue('S1', '视频号信息'); $objPHPExcel->getActiveSheet()->setCellValue('T1', '下单时间'); $objPHPExcel->getActiveSheet()->setCellValue('U1', '付款时间'); $statusList = $this->model->getStatusList(); $typeList = $this->model->getTypeList(); $sourceList = $this->model->getSourceList(); $isChannelsInstalled = \app\admin\library\project\App::isInstall('channels'); $systemType = \app\common\library\Platform::getSystemType(); $orderWhere = []; $userWhere = []; if(!empty($originWhere)){ foreach ($originWhere as $w) { if(is_array($w) && isset($w[0])){ $field = $w[0]; if(strpos($field, 'user.') === 0){ $userField = substr($field, 5); $userWhere[] = [$userField, $w[1], $w[2]]; }else{ $orderWhere[] = $w; } }else{ $orderWhere[] = $w; } } } if(!empty($userWhere)){ $userQuery = \app\admin\model\User::where(function($query) use ($userWhere) { foreach ($userWhere as $w) { if(is_array($w)){ call_user_func_array([$query, 'where'], $w); } } }); $userIds = $userQuery->column('id'); if(empty($userIds)){ $userIds = [0]; } $orderWhere[] = ['user_id', 'in', $userIds]; } $query = $this->model->where(function($query) use ($orderWhere) { foreach ($orderWhere as $w) { if(is_array($w)){ call_user_func_array([$query, 'where'], $w); } } }); if($itemName){ $query = $query->where(function ($query) use ($itemName) { $query->where(function ($query) use ($itemName) { $query->whereExists(function ($query) use ($itemName) { $itemTableName = (new \app\admin\model\order\Item())->getQuery()->getTable(); $query->table($itemTableName)->where($itemTableName . '.order_no=order.order_no') ->where('item_name', 'like', "%{$itemName}%"); }); }); }); } $query->chunk(100, function($list) use ($objPHPExcel, $statusList, $typeList, $sourceList, $isChannelsInstalled, $systemType) { if(!$list) return; $userIds = []; $orderNos = []; $orderIds = []; $physicalOrderIds = []; $channelsOrderNos = []; foreach ($list as $item) { $userIds[] = $item['user_id']; $orderNos[] = $item['order_no']; $orderIds[] = $item['id']; if($item['order_type'] == 'physical'){ $physicalOrderIds[] = $item['id']; } if(strtolower($item['source']) == 'channels'){ $channelsOrderNos[] = $item['order_no']; } } $userIds = array_unique($userIds); $userList = \app\admin\model\User::where('id', 'in', $userIds)->field('id,username,mobile')->select(); $userMap = []; foreach ($userList as $u) { $userMap[$u['id']] = $u; } $itemList = \app\admin\model\order\Item::where('order_no', 'in', $orderNos)->select(); $itemMap = []; foreach ($itemList as $goods) { $detail = json_decode($goods['snapshoot'], true); $goods['detail_name'] = $detail['name'] ?? $goods['item_name'] ?? '-'; $itemMap[$goods['order_no']][] = $goods; } $addressMap = []; if(!empty($physicalOrderIds)){ $addressList = \app\common\model\app\physical\OrderAddress::where('order_id', 'in', $physicalOrderIds)->select(); foreach ($addressList as $addr) { $addressMap[$addr['order_id']] = $addr; } } $expressMap = []; if(!empty($physicalOrderIds)){ $expressList = \app\common\model\app\physical\OrderExpress::where('order_id', 'in', $physicalOrderIds)->select(); foreach ($expressList as $exp) { $expressMap[$exp['order_id']] = $exp; } } $channelsMap = []; $storeMap = []; if(!empty($channelsOrderNos) && $isChannelsInstalled && $systemType == 'single'){ $channelsList = \app\admin\model\app\channels\Order::where('order_id', 'in', $channelsOrderNos)->with(['member','store'])->select(); if($channelsList){ if(is_array($channelsList) === false){ $channelsList = $channelsList->toArray(); } foreach ($channelsList as $ch) { $channelsMap[$ch['order_id']] = $ch; if(isset($ch['store_id']) && $ch['store_id'] && !isset($storeMap[$ch['store_id']])){ $storeMap[$ch['store_id']] = $ch['store'] ?? null; } } } } foreach ($list as $item){ $itemNames = []; $unitPrices = []; $counts = []; if(!empty($itemMap[$item['order_no']])){ foreach ($itemMap[$item['order_no']] as $goods){ $itemNames[] = $goods['detail_name']; $unitPrices[] = $goods['unit_price']; $counts[] = $goods['count']; } } $userInfo = isset($userMap[$item['user_id']]) ? $userMap[$item['user_id']] : null; $consignee = '-'; $consigneeMobile = '-'; $consigneeAddress = '-'; $expressName = '-'; $expressNo = '-'; if($item['order_type'] == 'physical'){ if(isset($addressMap[$item['id']])){ $addr = $addressMap[$item['id']]; $consignee = $addr['consignee'] ?: '-'; $consigneeMobile = $addr['mobile'] ?: '-'; $consigneeAddress = ($addr['province_name'] ?? '') . ($addr['city_name'] ?? '') . ($addr['district_name'] ?? '') . ($addr['address'] ?? ''); if(!$consigneeAddress) $consigneeAddress = '-'; } if(isset($expressMap[$item['id']])){ $exp = $expressMap[$item['id']]; $expressName = $exp['express_name'] ?: '-'; $expressNo = $exp['express_no'] ?: '-'; } } $channelsInfo = '-'; if(strtolower($item['source']) == 'channels' && isset($channelsMap[$item['order_no']])){ $ch = $channelsMap[$item['order_no']]; $parts = []; if(!empty($ch['mobile'])){ $parts[] = '联系电话:' . $ch['mobile']; } $orderSceneList = (new \app\admin\model\app\channels\Order())->getOrderScene(); if(isset($ch['order_scene']) && isset($orderSceneList[$ch['order_scene']])){ $parts[] = '下单场景:' . $orderSceneList[$ch['order_scene']]; } if(isset($storeMap[$ch['store_id']]) && $storeMap[$ch['store_id']]){ $parts[] = '所属店铺:' . ($storeMap[$ch['store_id']]['nickname'] ?? $storeMap[$ch['store_id']]['username'] ?? '-'); } $channelsInfo = !empty($parts) ? implode("\t", $parts) : '-'; } $objPHPExcel->getActiveSheet()->setCellValue('A'.(2 + $this->exportIndex), $item['order_no']); $objPHPExcel->getActiveSheet()->setCellValue('B'.(2 + $this->exportIndex), implode("\n", $itemNames)); $objPHPExcel->getActiveSheet()->setCellValue('C'.(2 + $this->exportIndex), implode("\n", $unitPrices)); $objPHPExcel->getActiveSheet()->setCellValue('D'.(2 + $this->exportIndex), implode("\n", $counts)); $objPHPExcel->getActiveSheet()->setCellValue('E'.(2 + $this->exportIndex), $item['real_price']); $objPHPExcel->getActiveSheet()->setCellValue('F'.(2 + $this->exportIndex), isset($statusList[$item['status']]) ? $statusList[$item['status']] : $item['status']); $objPHPExcel->getActiveSheet()->setCellValue('G'.(2 + $this->exportIndex), $userInfo ? $userInfo['username'] : '-'); $objPHPExcel->getActiveSheet()->setCellValue('H'.(2 + $this->exportIndex), $userInfo ? $userInfo['mobile'] : '-'); $objPHPExcel->getActiveSheet()->setCellValue('I'.(2 + $this->exportIndex), isset($typeList[$item['order_type']]) ? $typeList[$item['order_type']] : $item['order_type']); $objPHPExcel->getActiveSheet()->setCellValue('J'.(2 + $this->exportIndex), isset($sourceList[$item['source']]) ? $sourceList[$item['source']] : $item['source']); $objPHPExcel->getActiveSheet()->setCellValue('K'.(2 + $this->exportIndex), $item['star'] ?: '-'); $objPHPExcel->getActiveSheet()->setCellValue('L'.(2 + $this->exportIndex), $item['buyer_remark'] ?: '-'); $objPHPExcel->getActiveSheet()->setCellValue('M'.(2 + $this->exportIndex), $item['merch_remark'] ?: '-'); $objPHPExcel->getActiveSheet()->setCellValue('N'.(2 + $this->exportIndex), $consignee); $objPHPExcel->getActiveSheet()->setCellValue('O'.(2 + $this->exportIndex), $consigneeMobile); $objPHPExcel->getActiveSheet()->setCellValue('P'.(2 + $this->exportIndex), $consigneeAddress); $objPHPExcel->getActiveSheet()->setCellValue('Q'.(2 + $this->exportIndex), $expressName); $objPHPExcel->getActiveSheet()->setCellValueExplicit('R'.(2 + $this->exportIndex), $expressNo, \PHPExcel_Cell_DataType::TYPE_STRING); $objPHPExcel->getActiveSheet()->setCellValue('S'.(2 + $this->exportIndex), $channelsInfo); $objPHPExcel->getActiveSheet()->setCellValue('T'.(2 + $this->exportIndex), $item['createtime'] ? date('Y-m-d H:i:s', $item['createtime']) : '-'); $objPHPExcel->getActiveSheet()->setCellValue('U'.(2 + $this->exportIndex), $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '-'); $this->exportIndex++; } }); $objPHPExcel->getActiveSheet()->getStyle('A1:U1')->getFont()->setBold(true)->getColor()->setARGB(\PHPExcel_Style_Color::COLOR_BLACK); $objPHPExcel->getActiveSheet()->getStyle('A1:U1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); $objPHPExcel->getActiveSheet()->getStyle('A1:U1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('D9FFC125'); $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(22); $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30); $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(10); $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(8); $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(15); $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(15); $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(10); $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8); $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(20); $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(20); $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(12); $objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(15); $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(30); $objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(15); $objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(20); $objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(30); $objPHPExcel->getActiveSheet()->getColumnDimension('T')->setWidth(18); $objPHPExcel->getActiveSheet()->getColumnDimension('U')->setWidth(18); $objPHPExcel->setActiveSheetIndex(0); ob_end_clean(); header('pragma:public'); header("Content-Disposition:attachment;filename={$excelTitle}.xlsx"); header('Cache-Control: max-age=0'); $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save('php://output'); exit; } /** * 更新物流信息 * * @param \think\Model $expressModel 发货单模型 * @return void */ private function updateExpressInfo($expressModel) { try { // 获取阿里云配置 $aliyunConfig = [ 'appcode' => 'd6beec8b9be945bfa3c07b9c712f6bce', 'appkey' => '203944259', 'appsecret' => 'R8rx9QLNZlRKxHtvgjBlocFI8f0hq12J' ]; $expressLib = new \app\common\library\app\physical\express\Express('aliyun', $aliyunConfig); $expressLib->updateExpress($expressModel); } catch (\Exception $e) { \think\Log::error('updateExpressInfo.Exception: ' . $e->getMessage()); } } }