100], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'mall_id' => '商城id', 'store_id' => '门店id', 'user_id' => '会员id', 'order_no' => '订单编号', 'order_money' => '订单金额', 'pay_money' => '支付金额', 'discount_money' => '优惠金额', 'addons_bonus' => '插件分红', 'service_charge' => '服务费', 'amount_received' => '到账金额', 'is_settlement' => '结算状态 0:待结算;1:已结算', 'settle_type' => '1,2,3平台承担,4门店承担', 'type' => '类型:1:o2o订单;2:o2o收银台订单', 'created_at' => 'Created At', 'updated_at' => 'Updated At', 'status' => '状态[-1:删除;0:禁用;1启用]', 'store_send_commission' => '门店直接发放佣金', 'higo_reward' => 'HiGo商家让利,商户嗨贝不足扣除等额到账金额', 'store_contributing_money' => '折扣金额', 'amount_received_score' => '到账积分', 'score_deduct_num' => '抵扣积分数量', 'score_deduction_bear' => '积分抵扣-优惠承担对象 -1:未开启积分抵扣;0:平台:1:门店' ]; } public function getUser() { return $this->hasOne(User::class, ['id' => 'user_id']); } public function getStore() { return $this->hasOne(Store::class, ['id' => 'store_id'])->select('id, shop_mobile, store_name'); } public static function setData(array $params) { try { $model = new self(); $model->loadDefaultValues(); if (!$model->load($params, '') || !$model->save()) { throw new \Exception($model->getErrorMessage()); } return $model; } catch (\Exception $e) { self::$static_error = $e->getMessage() . $e->getLine() . $e->getFile(); return false; } } /** * @name: * @msg: 数据导出处理器 * @param {*} $data * @return {*} */ public static function exportHandle(array $data = null) { try { $download_id = $data['download_id'] ?? 0; $download = Download::findOne(['id' => $download_id]); $params = json_decode($download->params, true); // dd($params); $have_select_field_arr = []; $all_fields = self::fieldsList(); $fields = $params['fields'] ?? []; if (!empty($fields)) { foreach ($fields as $field) { $have_select_field_arr[] = $all_fields[$field]; } } else { $have_select_field_arr = $all_fields; } // dd($have_select_field_arr); $csv = new CsvTool(); $csv->filename = $download->name; $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($download->type); $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC; $csv->header = $have_select_field_arr; // if (!empty($fields)) { // $select = $fields; // // $select = array_merge($select, ['user_id', 'store_id']); // } else { // $select = '*'; // } $list_query = self::find()->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]); if (!empty($min_amount)) { $list_query->andWhere(['>=', 'pay_money', $min_amount]); } if (!empty($max_amount)) { $list_query->andWhere(['<=', 'pay_money', $max_amount]); } if (!empty($start_time)) { $list_query->andWhere(['>=', 'created_at', $start_time]); } if (!empty($end_time)) { $list_query->andWhere(['<=', 'created_at', $end_time]); } if (!empty($store_name)) { $stores = Store::find() ->select('id,store_name,logo_img') ->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]) ->andWhere(['like', 'store_name', $store_name]) ->asArray() ->indexBy('id') ->all(); $store_ids = array_column($stores, 'id'); $list_query->andWhere(['store_id' => $store_ids]); } if (!empty($user_id)) { $list_query->andWhere(['user_id' => $user_id]); } $user_wheres = []; $users = []; if (!empty($nickname)) { $user_wheres[] = ['like', 'nickname', $nickname]; } if (!empty($mobile)) { $user_wheres[] = ['like', 'mobile', $mobile]; } if (!empty($user_wheres)) { $user_wheres[] = ['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]; $query = User::find()->select('id,nickname,mobile,avatar_url'); foreach ($user_wheres as $where) { $query->andWhere($where); } $users = $query->asArray()->indexBy('id')->all(); $user_ids = array_column($users, 'id'); $list_query->andWhere(['user_id' => $user_ids]); } $rows = []; foreach ($list_query->asArray()->batch(200) as $lists) { // dd($lists); if (empty($users)) { $user_ids = array_column($lists, 'user_id'); $users = User::find() ->select('id,nickname,mobile,avatar_url') ->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED, 'id' => $user_ids]) ->asArray() ->indexBy('id') ->all(); } if (empty($stores)) { $store_ids = array_column($lists, 'store_id'); $stores = Store::find() ->select('id,store_name,logo_img') ->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED, 'id' => $store_ids]) ->asArray() ->indexBy('id') ->all(); } foreach ($lists as $list) { $user = $users[$list['user_id']] ?? ''; $store = $stores[$list['store_id']] ?? ''; $list['nickname'] = $user['nickname'] ?? ''; $list['mobile'] = $user['mobile'] ?? ''; $list['store_name'] = $store['store_name'] ?? ''; // dd($list); $arr = []; foreach ($fields as $field) { if (!empty($list[$field])) { if ('created_at' == $field) { $list[$field] = date('Y-m-d H:i:s', $list[$field]); } if ('mobile' == $field) { $list[$field] = (string)$list[$field]; } } else { $list[$field] = ''; } $arr[] = $list[$field]; } $rows[] = $arr; } } $csv->data = $rows; $csv->export(); $csv->updateDown($download, $params['mall_id']); return true; } catch (\Exception $e) { $download->status = 3; $res = $download->save(); self::setStaticError($e->getMessage()); return $e->getMessage(); } } /** * 订单详情导出 * @param array $data * @return string|true */ public static function orderDetailExportHandle(array $data) { $download_id = $data['download_id'] ?? 0; $download = Download::findOne(['id' => $download_id]); $transaction = \Yii::$app->db->beginTransaction(); try { $params = json_decode($download->params, true); $fileName = $download->name; $storeModel = self::find()->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED, 'type' => 1]); if (!empty($params['store_name'])) { $store_ids = Store::find() ->select('id') ->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]) ->andWhere(['like', 'store_name', $params['store_name']]) ->asArray() ->indexBy('id') ->column(); $storeModel->andWhere(['store_id' => $store_ids]); } $user_ids = []; if (!empty($params['user_id'])) { $user_ids[] = $params['user_id']; } if (!empty($params['nickname'])) { $user_ids = array_merge($user_ids, self::getUserIdsByParams($params, 'nickname')); } if (!empty($params['mobile'])) { $user_ids = array_merge($user_ids, self::getUserIdsByParams($params, 'mobile')); } if (!empty($user_ids)) { $storeModel->andWhere(['user_id' => $user_ids]); } if (!empty($params['order_no'])) { $storeModel->andWhere(['like', 'order_no', $params['order_no']]); } if (!empty($params['order_status'])) { switch ($params['order_status']) { case 1: $storeModel->andWhere(['is_settlement' => 0]); break; case 2: $storeModel->andWhere(['is_settlement' => 1]); break; default: $storeModel->andWhere(['!=', 'status', StatusEnum::ENABLED]); } } if (!empty($params['order_ids'])) { $storeModel->andWhere(['id' => $params['order_ids']]); } $batchSize = 10000; $totalRecords = $storeModel->count() ?? 0; $is_model_page = bcdiv($totalRecords, $batchSize); $oldFields = $params['fields'] ?? []; $exportHeader = []; $fields = []; $orderDetailFieldsList = self::orderDetailFieldsList(); foreach ($orderDetailFieldsList as $field => $fieldName) { if (in_array($field, $oldFields)) { $fields[] = $field; $exportHeader[] = $fieldName; } } $whereWith = ['store', 'user' => function ($query) { $query->select('id, nickname, mobile, avatar_url'); }]; $i = 0; foreach ($storeModel->with($whereWith)->orderBy('id desc')->asArray()->batch($batchSize) as $stores) { $exportList = []; foreach ($stores as $store) { $exportItem = self::buildExportItem($store, $fields); $exportList[] = $exportItem; } if (!empty($exportList)) { $csv = new CsvTool(); $csv->header = $exportHeader; $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($download->type); $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC; $csv->data = $exportList; $csv->filename = $is_model_page ? $fileName . '_1' : $fileName; if ($is_model_page && $i == 0) { // 因为订单页需要分页,所以需要设置文件名 $download->name = $fileName . '_1'; $download->save(); } if ($i >= 1) { $newFileName = $fileName . '_' . ($i + 1); $csv->filename = $newFileName; $downloadData = [ 'mall_id' => $download->mall_id, 'mch_id' => $download->mch_id, 'store_id' => $download->store_id, 'name' => $newFileName, 'type' => $download->type, 'handler_class' => $download->handler_class, 'method' => $download->method, 'params' => $download->params, 'data' => $exportList ]; $downloadModel = Download::setData($downloadData); if ($downloadModel === false) { Yii::$app->custom->logs('创建下载任务失败:' . $downloadData['name'], Download::getStaticError()); throw new \Exception('创建新下载任务失败'); }; $download = $downloadModel; } $csv->export(); $csv->updateDown($download, $params['mall_id']); $i++; } unset($exportList); } $transaction->commit();// 事务完成 return true; } catch (\Exception $e) { $transaction->rollBack(); $download->status = 3; $res = $download->save(); self::setStaticError($e->getMessage()); return $e->getMessage(); } } /** * 构建导出数据 * @param $store * @param $fields * @return array */ public static function buildExportItem($store, $fields): array { $exportItem = []; foreach ($fields as $field) { switch ($field) { case 'store_name': $exportItem[$field] = $store['store']['store_name'] ?? ''; break; case 'user_id': $exportItem[$field] = $store['user_id'] ?? ''; break; case 'nickname': $exportItem[$field] = $store['user']['nickname'] ?? ''; break; case 'mobile': $exportItem[$field] = $store['user']['mobile'] ?? ''; break; case 'order_no': $exportItem[$field] = $store['order_no'] ?? ''; break; case 'order_money': $exportItem[$field] = $store['order_money'] ?? ''; break; case 'discount_money': $exportItem[$field] = $store['discount_money'] ?? ''; break; case 'pay_money': $exportItem[$field] = $store['pay_money'] ?? ''; break; case 'addons_bonus': $exportItem[$field] = $store['addons_bonus'] ?? ''; break; case 'store_send_commission': $exportItem[$field] = $store['store_send_commission'] ?? ''; break; case 'service_charge': $exportItem[$field] = $store['service_charge'] ?? ''; break; case 'amount_received': $exportItem[$field] = $store['amount_received'] ?? ''; break; case 'is_settlement': $exportItem[$field] = $store['is_settlement'] == 1 ? '已结算' : '未结算'; break; case 'created_at': $exportItem[$field] = date('Y-m-d H:i:s', $store['created_at']); break; } } return $exportItem; } /** * 根据查询条件获取用户ID * @param $params * @param $field * @return array */ public static function getUserIdsByParams($params, $field): array { if (empty($params[$field])) { return []; } try { return User::find() ->select('id') ->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]) ->andWhere(['like', $field, $params[$field]]) ->asArray() ->column(); } catch (\Exception $e) { // 记录异常日志 \Yii::error("Failed to query user IDs by $field: " . $e->getMessage()); return []; } } public static function fieldsList(array $fields = []): array { $field_list = [ 'store_name' => '门店名称', 'nickname' => '会员昵称', 'mobile' => '会员手机号', 'order_no' => '订单编号', 'order_money' => '应付金额', 'pay_money' => '实付金额', 'discount_money' => '优惠金额', 'amount_received' => '实收金额', 'created_at' => '下单时间', ]; if (empty($fields)) { return $field_list; } else { $new_list = []; foreach ($fields as $val) { if (!empty($field_list[$val])) { $new_list[$val] = $fields[$val]; } } return $new_list; } } /** * 资产管理-订单明细导出 * @param array $fields * @return array */ public static function orderDetailFieldsList(array $fields = []): array { return [ 'store_name' => '门店名称', 'user_id' => '用户ID', 'nickname' => '用户昵称', 'mobile' => '用户手机号', 'order_no' => '订单编号', 'order_money' => '订单金额', 'discount_money' => '优惠金额', 'pay_money' => '实付金额', 'addons_bonus' => '插件分红', 'store_send_commission' => '门店股东分红', 'service_charge' => '服务费', 'amount_received' => '到账金额', 'is_settlement' => '状态', 'created_at' => '创建时间', ]; } }