255], [['batch_num','order_sn'], 'string', 'max' => 32], [['name', 'mobile','job_id','job_detail_id'], 'string', 'max' => 64], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'mall_id' => 'Mall ID', 'user_id' => 'user id', 'account_id' => 'Account ID', 'withdraw_id' => 'Withdraw ID', 'title' => 'Title', 'batch_num' => 'Batch Num', 'name' => 'Name', 'mobile' => 'Account Num', 'amount' => 'Amount', 'remarks' => 'Remarks', 'type' => 'Type', 'account_type' => 'Account Type', 'status' => 'Status', 'alipay_response' => 'Alipay Response', 'error' => 'Error', 'updated_at' => 'Updated At', 'created_at' => 'Created At', ]; } public function getUserAuth() { return $this->hasOne(TaxUserAuth::class,['user_id'=>'user_id']); } public function beforeSave($insert) { if (parent::beforeSave($insert)) { $insert ? $this->created_at = $this->updated_at = time() : $this->updated_at = time(); return true; } else { return false; } } /** * 子订单 * * @return ActiveQuery hasMany($class, array $link) see [[BaseActiveRecord::hasMany()]] for more info */ public function getList() { return $this->hasMany(self::class, ['id' => 'order_id']); } /** * 商城提现 * * @return ActiveQuery hasMany($class, array $link) see [[BaseActiveRecord::hasMany()]] for more info */ public function getWithdraw() { return $this->hasOne(UserWithdrawLog::class, ['id' => 'withdraw_id']); } /** * 商城提现 * * @return ActiveQuery hasMany($class, array $link) see [[BaseActiveRecord::hasMany()]] for more info */ public function getWithdraw2() { return $this->hasOne(ModelsUserWithdrawLog::class, ['id' => 'withdraw_id']); } /** * 获取关联记帐本 * * @return ActiveQuery */ public function getAccount() { return $this->hasOne(TaxAccount::class, ['id' => 'account_id']); } /** * 获取关联记帐本 * * @return ActiveQuery */ public function getBook() { return $this->hasOne(TaxAccountBook::class, ['account_id' => 'account_id']); } /** * 获取用户订单 * * @return ActiveQuery hasMany($class, array $link) see [[BaseActiveRecord::hasMany()]] for more info */ public function getUserLog() { return $this->hasOne(TaxOrder::class, ['batch_num' => 'batch_num'])->where(['sub_type' => static::SUB_TYPE_USER]); } /** * 关联用户 * @Author: lun * @DateTime: 2023/6/9 0009 15:48 * @Copyright: copyright (c) 2021 广东七件事集团 * @return ActiveQuery */ public function getUser() { return $this->hasOne(User::class, ['id' => 'user_id'])->select('id,nickname,mobile'); } /** * 新增一条交易记录 * * @param array $data * @return boolean */ public function add($data) { $this->load($data, ''); return $this->save(); } /** * 获取一个批次号 * * @return string */ public static function getBatchNum() { srand(); $num = self::PREFIX . date('YmdHis') . rand(1000, 9909); return self::numExists($num) ? $num : self::getBatchNum(); } /** * 查询批次号是否存在 * * @param string $num * @return boolean */ public static function numExists($num) { return empty(self::find()->select('id')->where(['batch_num' => $num])->one()) ? true : false; } /** * 回款成功 * * @return bool */ public static function transSuccess($batch_num = null,$order_sn = null ) { $batch_num && $where['batch_num'] = $batch_num; $order_sn && $where['order_sn'] = $order_sn; if(empty($where)) return false; return self::updateAll(['status' => StatusEnum::STATUS_OUT_OK, 'error' => '', 'updated_at' => time()], $where); } /** * 订单完成 * * @return boolean */ public function taxOrderSuccess() { $this->error = ''; $this->status = StatusEnum::STATUS_OUT_OK; return $this->save(); } /** * 订单失败 * @param string $msg * * @return boolean */ public function taxOrderFail(string $msg = '') { $this->error = $msg; $this->status = StatusEnum::STATUS_FAIL; return $this->save(); } /** * 修改订单错误信息 * @param null $batch_num 批次号 * @param null $order_sn 订单号 * @param string $msg 错误信息 * @param null $status 状态 * * @return bool|int */ public static function transError($batch_num = null, $order_sn = null, $msg = '') { $batch_num && $where['batch_num'] = $batch_num; $order_sn && $where['order_sn'] = $order_sn; if(empty($where)) return false; return self::updateAll(['status' => StatusEnum::STATUS_FAIL, 'error' => $msg, 'updated_at' => time()], $where); } /** * 手续费打款失败 * * @return boolean */ public function transTaxFeeError(string $msg) { $this->error = $msg; return $this->save(); } /** * 通过批次号获取用户id */ public static function byBatchNumGetUserId($batch_num):array { $orders = TaxOrder::find()->select('withdraw_id')->where(['batch_num'=>$batch_num])->asArray()->all(); if ( empty($orders) ) return []; $userids = UserWithdrawLog::find() ->select("user_id") ->where(['id'=>array_column($orders,'withdraw_id')]) ->asArray() ->indexBy("user_id") ->all(); return $userids; } public static function changStatus($batch_num,$param) { $param['updated_at'] = time(); return self::updateAll($param,['batch_num'=>$batch_num]); } /** * 获取分页数据 * * @param integer $page * @param integer $limit * @param callable $callback * @param string $order_by * @return array */ public static function getPageList( int $page, int $limit, callable $callback, string $order_by = 'id' ) :array { $model = static::find(); if (!empty($callback)) call_user_func($callback, $model); $pagination = new Pagination(['totalCount' => $model->count(), 'pageSize' => $limit]); $model->limit($pagination->limit)->offset($pagination->offset); $list = $model->asArray()->orderBy($order_by)->all(); $data['list'] = $list; $data['page_count'] = $pagination->pageCount; $data['current_page'] = $page + 1; return $data; } /** * 添加支付响应 * * @param array $response * @return boolean */ public function addAlipayResponse($response) { $this->alipay_response = Json::encode($response); return $this->save(); } /** * 添加用户订单 * * @param string $batch_num * @param float $fee * @param UserWithdrawLog $withdraw_log * @return TaxOrder|false */ public static function addUserOrder( string $batch_num, int $account_id, float $fee, UserWithdrawLog $withdraw_log ) { $extra = Json::decode($withdraw_log->extra); $name = $extra['name']; $mobile = $extra['mobile']; $model = new static(); $model->mall_id = $withdraw_log->mall_id; $model->account_id = $account_id; $model->withdraw_id = $withdraw_log->id; $model->title = '商城销售分润'; $model->batch_num = $batch_num; $model->order_sn = $withdraw_log->order_no . '_' . rand(100, 999); $model->name = (string)$name; $model->mobile = (string)$mobile; $model->amount = $withdraw_log->actual_num; $model->pay_fee = $fee; $model->user_id = $withdraw_log->user_id; $model->type = OrderTypeEnum::TYPE_2; $model->sub_type = TaxOrder::SUB_TYPE_USER; $model->remarks = ''; return $model->save() ? $model : false; } /** * 添加手续费订单 * * @param string $batch_num * @param float $fee * @param UserWithdrawLog $withdraw_log * @param TaxConfigService $service * @return false|static */ public static function addTaxOrder( string $batch_num, int $account_id, float $fee, UserWithdrawLog $withdraw_log, TaxConfigService $service ) { $model = new static(); $config = $service->getTaxConfig(); $model->mall_id = $withdraw_log->mall_id; $model->account_id = $account_id; $model->withdraw_id = $withdraw_log->id; $model->title = '商城销售分润'; $model->batch_num = $batch_num; $model->order_sn = TaxOrder::TAX_ORDER_PRE . $withdraw_log->order_no . '_' . rand(100, 999); $model->name = $config['taxAccountName']; $model->mobile = $config['taxAccount']; $model->amount = $fee; $model->type = OrderTypeEnum::TYPE_2; $model->sub_type = TaxOrder::SUB_TYPE_TAX; $model->remarks = '手续费'; return $model->save() ? $model : false; } /** * @param string $batch_num * @return static|array|null a single row of query result. Depending on the setting of [[asArray]], */ public static function getFeeDeatilByNum(string $batch_num) { return static::find() ->where(['batch_num' => $batch_num, 'sub_type' => static::SUB_TYPE_TAX]) ->one(); } /** * @param string $batch_num * @return static|array|null a single row of query result. Depending on the setting of [[asArray]], */ public static function getOrderDetailByNum(string $batch_num) { return static::find() ->where(['batch_num' => $batch_num, 'sub_type' => static::SUB_TYPE_USER]) ->one(); } /** * 统计 * @Author: lun * @DateTime: 2023/6/9 0009 11:32 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $mall_id * @param array $date 日期选择 * @return array */ public static function statistic($mall_id, $date = []) { // 用户实际提现金额(未被平台扣除手续费) $withdraw = UserWithdrawLog::find()->where(['mall_id' => $mall_id, 'type' => 'alipay_tax', 'status' => UserWithdrawLog::STATUS_ALREADY_TRANS]); if (!empty($date)) { $withdraw->andWhere(['>=', 'created_at', strtotime($date[0])]); $withdraw->andWhere(['<=', 'created_at', strtotime($date[1])]); } $withdraw_total = $withdraw->sum('num'); // 打款成功统计 $success = self::find()->select('sum(amount) amount_total,sum(pay_fee) pay_fee_total')->where([ 'mall_id' => $mall_id, 'sub_type' => self::SUB_TYPE_USER, 'status' => StatusEnum::STATUS_OUT_OK, ]); if (!empty($date)) { $success->andWhere(['>=', 'created_at', strtotime($date[0])]); $success->andWhere(['<=', 'created_at', strtotime($date[1])]); } $success_total = $success->asArray()->one(); // 实发服务费 $fee = self::find()->where([ 'mall_id' => $mall_id, 'sub_type' => self::SUB_TYPE_TAX, 'status' => StatusEnum::STATUS_OUT_OK, ]); if (!empty($date)) { $fee->andWhere(['>=', 'created_at', strtotime($date[0])]); $fee->andWhere(['<=', 'created_at', strtotime($date[1])]); } $fee_total = $fee->sum('amount') ?? 0; return [ 'payment_total' => $success_total['amount_total'] ?? 0, 'payment_fee_total' => $success_total['pay_fee_total'] ?? 0, 'fee_total' => $fee_total, 'withdraw_total' => $withdraw_total, ]; } /** * 导出字段 * @Author: lun * @DateTime: 2023/6/9 0009 15:24 * @Copyright: copyright (c) 2021 广东七件事集团 * @param null $field * @return array|string[] */ public static function fieldsList($sub_type = self::SUB_TYPE_USER, $field = null){ $fields = [ 'account_id' => '记账方ID', 'user_id' => '用户ID', 'nickname' => '用户昵称', 'user_mobile' => '用户手机号', 'batch_num' => '批次号', 'order_sn' => '订单号', 'name' => '收款名称', 'mobile' => '收款账户', 'amount' => '金额', 'pay_fee' => '手续费', 'remarks' => '备注', 'status' => '状态', 'error' => '错误信息', 'created_at' => '时间', ]; if ($sub_type == self::SUB_TYPE_TAX) { unset($fields['user_id'], $fields['nickname'], $fields['user_mobile'], $fields['pay_fee']); } if ($field === null) return $fields; $temp = []; foreach ($field as $val) { if (isset($fields[$val])) $temp[$val] = $fields[$val]; } return $temp; } /** * 批量导出 * @Author: lun * @DateTime: 2023/6/9 0009 15:24 * @Copyright: copyright (c) 2021 广东七件事集团 * @param array $data * @return bool|string */ public static function exportHandle(array $data) { date_default_timezone_set('Asia/Shanghai'); $download_id = $data['download_id'] ?? 0; $download = Download::findOne(['id' => $download_id]); if ($download) { try { $params = json_decode($download->params,true); $filename = $download->name; $type = $download->type; $model = self::find(); $model->where(['mall_id' => $params['mall_id']]); if(!empty($params['sub_type'])) $model->andWhere(['sub_type' => $params['sub_type']]); if(!empty($params['status'])) $model->andWhere(['status' => $params['status']]); if(!empty($params['batch_num'])) $model->andWhere(['batch_num' => $params['batch_num']]); if(!empty($params['order_sn'])) $model->andWhere(['order_sn' => $params['order_sn']]); if(!empty($params['name'])) $model->andWhere(['name' => $params['name']]); if(!empty($params['mobile'])) $model->andWhere(['mobile' => $params['mobile']]); if (!empty($params['date'][0])) { $model->andWhere(['>=', 'created_at', strtotime($params['date'][0])]); } if (!empty($params['date'][1])) { $model->andWhere(['<=', 'created_at', strtotime($params['date'][1])]); } $model->with(['user' => function($query) { $query->select('id,nickname,username,mobile'); }]); $fields = $params['fields']; $status_map = StatusEnum::getMap(); $fields_arr = self::fieldsList(); $have_select_field_arr = []; foreach ($fields as $value){ if(isset($fields_arr[$value])) $have_select_field_arr[] = $fields_arr[$value]; } $csv = new CsvTool(); $csv->filename = $filename; $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type); $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC; $csv->header = $have_select_field_arr; foreach ($model->batch() as $detail) { $csv->data = array_map(function($detail)use($fields, $status_map){ $row = []; foreach ($fields as $field){ switch (true){ case (in_array($field,['created_at'])): $row[] = !empty($detail[$field]) ? date('Y-m-d H:i:s', $detail[$field]) : ''; break; case ($field=='status'): $row[] = !empty($status_map[$detail[$field]]) ? $status_map[$detail[$field]] : ''; break; case ($field=='user_mobile'): $row[] = $detail['user']['mobile'] ??''; break; case ($field=='nickname'): $row[] = $detail['user']['nickname'] ??''; break; default: $row[] = !empty($detail[$field]) ? $detail[$field] : ''; } } return $row; }, $detail); $csv->export(); } $csv->updateDown($download,$params['mall_id']); return true; } catch (\Exception $e) { $download->status = 3; $download->save(); echo '导出失败:'.$e->getMessage().$e->getFile().$e->getLine(); return true; } } } }