/** * Auther:langxi * $member_id:用户id,$product_id:项目id,$money:用户投资钱数 * 用户投资 */ public static function invest($member_id, $product_id, $money) { ini_set('max_execution_time', 60); $member_id = (int) $member_id; $product_id = (int) $product_id; $money = (double) $money; //判断用户是否可进行投资操作 $is_go = Info::find()->select(['status'])->where(['member_id' => $member_id])->asArray()->one(); if ($is_go['status'] > 0) { Info::updateAll(['status' => '0'], ['member_id' => $member_id]); $result = array('errorNum' => '1', 'errorMsg' => '处理中,请稍后再试', 'data' => null); return $result; } Info::updateAll(['status' => Info::GO_TWO], ['member_id' => $member_id]); //进行操作,状态变为投资处理中 //检测用户投资资金,次数 $check_invest = self::check_invest($member_id, $product_id, $money); if ($check_invest['errorNum']) { Info::updateAll(['status' => '0'], ['member_id' => $member_id]); return $check_invest; } //检测用户状态 $checkMember = self::checkMember($member_id); if ($checkMember) { Info::updateAll(['status' => '0'], ['member_id' => $member_id]); return $checkMember; } //检测用户账户余额是否满足投资金额 $card = Info::find()->where(['member_id' => $member_id])->asArray()->one(); if ($card['balance'] < $money) { Info::updateAll(['status' => '0'], ['member_id' => $member_id]); $result = array('errorNum' => '1', 'errorMsg' => '账户金额不足,请进行充值', 'data' => null); return $result; } //检测投资金额是否满足项目的每次投资最大最小额度限制 $checkMoney = self::checkMoney($product_id, $money); if ($checkMoney) { Info::updateAll(['status' => '0'], ['member_id' => $member_id]); return $checkMoney; } //检测项目状态 $checkProduct = self::checkProduct($product_id, $money); if ($checkProduct) { Info::updateAll(['status' => '0'], ['member_id' => $member_id]); return $checkProduct; } $asset = Info::find()->where(['member_id' => $member_id])->asArray()->one(); $bank_card = $asset['bank_card']; //用户银行卡 $product = Product::find()->where(['id' => $product_id])->asArray()->one(); $end_at = $product['end_at']; //项目投资终止时间 //事物回滚 $transaction = \Yii::$app->db->beginTransaction(); try { //将账户中的钱取出,放入冻结金额中 $asset = Info::findOne($member_id); $asset->balance = $asset['balance'] - $money; $asset->freeze = $asset['freeze'] + $money; $asset = $asset->save(); if (!$asset) { throw new ErrorException('投资失败', 4002); } if ($product['type'] == Product::TYPE_THIRD) { //进行投资将钱放入order中 type=1债权转让项目(一对多) $order = new Order(); $order->member_id = $member_id; $order->product_id = $product_id; $order->type = Product::TYPE_THIRD; $order->money = $money; $order->start_money = $money; $order->status = Order::STATUS_ACTIVE; //1标识订单状态进行 $order->start_at = time(); $order->end_at = $end_at; $order = $order->save(); if (!$order) { throw new ErrorException('投资失败', 4002); } } else { //进行投资将钱放入order中 type=0债权项目(一对一) $order = new Order(); $order->member_id = $member_id; $order->product_id = $product_id; $order->type = Product::TYPE_PRO; $order->money = $money; $order->start_money = $money; $order->status = Order::STATUS_ACTIVE; //1标识订单状态进行 $order->start_at = time(); $order->end_at = $end_at; $order = $order->save(); if (!$order) { throw new ErrorException('投资失败', 4002); } } //检测用户是否投资过该项目,进行项目投资人数加一处理,项目已投金额增长 $check_people = self::check_people($member_id, $product_id); if ($check_people) { $product = Product::find()->where(['id' => $product_id])->asArray()->one(); $product_money = $product['invest_sum'] + $money; $total_money = $product['amount']; if ($product_money > $total_money) { throw new ErrorException('您投资的金额大于该项目剩余的额度', 4002); } $product = Product::findOne($product_id); $product->invest_sum = $product['invest_sum'] + $money; if ($product['amount'] - $product['invest_sum'] < 10) { $product->status = Product::STATUS_OUT; } $product->invest_people = $product['invest_people'] + 1; $res = $product->save(); if (!$res) { throw new ErrorException('项目已投金额、投资人数增加失败', 4002); } } else { $product = Product::find()->where(['id' => $product_id])->asArray()->one(); $product_money = $product['invest_sum'] + $money; $total_money = $product['amount']; if ($product_money > $total_money) { throw new ErrorException('您投资的金额大于该项目剩余的额度', 4002); } $product = Product::findOne($product_id); $product->invest_sum = $product['invest_sum'] + $money; if ($product['amount'] - $product['invest_sum'] < 10) { $product->status = Product::STATUS_OUT; } $res = $product->save(); if (!$res) { throw new ErrorException('项目已投金额增加失败', 4002); } } //type=1为一对多项目债权转让,等于0为债权项目一对一(只存在于product表中于thirdproduct无关) //获取用户此次投资此项目的债权字典 $thirdArr = self::creditor_dic($product_id, $money); //按照生成的债权字典,将钱分配给债权表 $setthird = self::set_Third($thirdArr, $member_id); if ($setthird) { return $setthird; } //删减用户账户冻结金额 $asset = Info::find()->where(['member_id' => $member_id])->asArray()->one(); $freeze = $asset['freeze']; //获取用户账户新的冻结金额 $asset = Info::findOne($member_id); $asset->freeze = $freeze - $money; $asset->invest = $asset['invest'] + $money; $asset->total_invest = $asset['total_invest'] + $money; //网站投资流程完成,增加用户累计投资额 $asset = $asset->save(); if (!$asset) { throw new ErrorException('删减冻结金额失败', 4002); } //投资成功进行投资记录 $assetlog = new Log(); $assetlog->member_id = $member_id; $assetlog->product_id = $product_id; $assetlog->step = $money; $assetlog->action = 'Invest/invest'; $assetlog->status = self::INVESTSUCCEED; //2标识投资成功 $assetlog->bankcard = $bank_card; $assetlog->remark = '投资成功'; $assetlog->save(); //处理债权字典,生成用于第三方代收的数据字典,键值为用户id,值为钱数 , $sina_pay为第三方代收函数需要的参数 $sina_dic = array(); foreach ($thirdArr as $v) { $sina_dic['m' . $v['maxcreditor']][] = array($v['mcmoney'], $v['maxcreditor']); $sina_dic['c' . $v['creditor']][] = array($v['ocmoney'], $v['creditor']); } $sina_pay = array(); foreach ($sina_dic as $key => $val) { foreach ($val as $k => $v) { if (!isset($sina_pay[$v['1']])) { $sina_pay[$v['1']] = $v['0']; } else { $sina_pay[$v['1']] += $v['0']; } } } //过滤掉金额为空的数组,得到第三方代收函数需要的参数,$sina_pay foreach ($sina_pay as $key => $value) { if (empty($value)) { unset($sina_pay[$key]); } } //调用封装好的第三方接口 $sina_invest = sinapay::invest((string) $member_id, (string) $product_id, (string) $money); //托管代收接口 if ($sina_invest['errorNum']) { throw new ErrorException($sina_invest['errorMsg'], 7001); } $sina_peyee = sinapay::batchPay($sina_pay, $sina_invest['data']['out_trade_no']); //托管批量代付接口 if ($sina_peyee['errorNum']) { $sina_refund = sinapay::hostingRefund($sina_invest['data']['identity_id'], $sina_invest['data']['out_trade_no'], $sina_invest['data']['money']); if ($sina_refund['errorNum']) { throw new ErrorException($sina_refund['errorMsg'], 7001); } throw new ErrorException($sina_peyee['errorMsg'], 7001); } //总投资记录 $total_log = self::total_log($member_id, $money); if ($total_log) { return $total_log; } $transaction->commit(); Info::updateAll(['status' => '0'], ['member_id' => $member_id]); $result = array('errorNum' => '0', 'errorMsg' => 'success', 'data' => null); return $result; } catch (\Exception $e) { $transaction->rollBack(); //对投资失败信息进行记录 $remark = $e->getMessage(); $assetlog = new Log(); $assetlog->member_id = $member_id; $assetlog->product_id = $product_id; $assetlog->step = $money; $assetlog->action = 'Invest/Invest'; $assetlog->status = self::INVESTERROR; //-2标识投资失败 $assetlog->bankcard = $bank_card; $assetlog->remark = $remark; $assetlog->save(); $result = array('errorNum' => '1', 'errorMsg' => $remark, 'data' => null); Info::updateAll(['status' => '0'], ['member_id' => $member_id]); return $result; } }