123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- <?php
- /**
- * Settle.php UTF-8
- * 提现
- *
- * @date : 2018/5/18 16:27
- *
- * @license 这不是一个自由软件,未经授权不许任何使用和传播。
- * @author : wuyonghong <wyh@huosdk.com>
- * @version : HUOSDK 8.0
- */
- namespace huo\controller\finance;
- use huo\controller\agent\AgentCache;
- use huo\controller\agent\AgentWallet;
- use huo\controller\common\Base;
- use huo\controller\member\MemCache;
- use huo\controller\queue\SettleQueue;
- use huo\controller\wap\Option;
- use huo\logic\finance\SettleLogic;
- use huo\model\finance\SettleHistoryModel;
- use huo\model\finance\SettleModel;
- use huo\model\member\MemoauthModel;
- use huolib\constant\CommonConst;
- use huolib\constant\MemConst;
- use huolib\constant\OauthConst;
- use huolib\constant\OptionConst;
- use huolib\constant\SettleConst;
- use huolib\status\CommonStatus;
- use huolib\status\OrderStatus;
- use huolib\status\SettleStatus;
- use huolib\tool\StrUtils;
- use huolib\tool\Time;
- use huolib\withdraw\driver\Alipay;
- use huolib\withdraw\driver\Wxpay;
- use huomp\controller\finance\SettleVerifiedOut;
- use huomp\logic\finance\SettleLogLogic;
- use huomp\logic\game\OaMchLogic;
- use huomp\model\member\UnusualMemModel;
- use huomp\model\weixin\MpConfModel;
- use huoMpMsg\controller\OaOut;
- use think\Log;
- class Settle extends Base {
- /**
- * 获取提现列表
- *
- * @param $agent_id
- * @param $param
- * @param string $page
- * @param string $order
- *
- * @return array
- */
- public function getSettleList($agent_id, $param, $page = '1,10', $order = '-create_time') {
- $_rdata = (new SettleLogic())->getSettleList($agent_id, $param, $page, $order);
- $_code = CommonStatus::NO_ERROR;
- return $this->retSucMsg($_code, $_rdata);
- }
- /**
- * 提现
- *
- * @param int $agent_id
- * @param float $amount
- * @param string $type
- *
- * @param array $oauth_data //第三方参数
- *
- * @return array
- */
- public function doSettle($agent_id, $amount, $type, $oauth_data = []) {
- if (!is_numeric($amount) || StrUtils::compareNumber($amount, 0) <= 0) {
- $_code = SettleStatus::AMOUNT_IS_ERROR;
- return $this->huoError($_code, SettleStatus::getMsg($_code));
- }
- /* 更新钱包 */
- $_rs = (new AgentWallet())->updateWallet(
- $agent_id, $amount, SettleConst::SETTLE_WALLET_DEDUCT, SettleConst::SETTLE_WALLET_LOCK
- );
- if (SettleStatus::NO_ERROR != $_rs) {
- return $this->huoError($_rs, SettleStatus::getMsg($_rs));
- }
- $_withdraw_cnt = (new SettleModel())->getCnt($agent_id);
- /* 添加提现记录 */
- $_rs_data = $this->buildSettleOrder($agent_id, $amount, $type, $oauth_data);
- if (SettleStatus::NO_ERROR != $_rs_data['code']) {
- return $this->huoReturn($_rs_data);
- }
- /* 判断用户状态 冻结用户不可自动打款*/
- $_ag_data = AgentCache::ins()->getInfoByAgentId($agent_id);
- if (!empty($_ag_data['mem_id'])) {
- $_mem_data = MemCache::ins()->getInfoById($_ag_data['mem_id']);
- if (MemConst::STATUS_FORBID == $_mem_data['status']) {
- $_um_model = new UnusualMemModel();
- $_data = [
- 'mem_id' => $_ag_data['mem_id'],
- 'agent_id' => $agent_id,
- 'type' => MemConst::UNUSUAL_MEN_TYPE_3
- ];
- $_um_data = $_um_model->getDataByAgentId($agent_id);
- if (empty($_um_data)) {
- $_um_model->addData($_data);
- } else {
- $_um_model->updateDataByAgentId($_data, $_data['agent_id']);
- }
- if (!empty($_rs_data['data']['s_id'])) {
- (new SettleModel())->updateData(['tag' => SettleConst::SETTLE_TAG_2], $_rs_data['data']['s_id']);
- }
- /* 已冻结用户 需要运营审核 */
- return $this->huoReturn($_rs_data);
- }
- }
- /* 判断重名数 大于等于限制值 不可自动提现打款 */
- if (!empty($oauth_data['real_name'])) {
- $_rs = (new SettleVerifiedOut())->isLimit($oauth_data['real_name']);
- $_um_model = new UnusualMemModel();
- if (true == $_rs) { //达到限制记录玩家
- $_data = [
- 'mem_id' => $_ag_data['mem_id'],
- 'agent_id' => $agent_id,
- 'type' => MemConst::UNUSUAL_MEN_TYPE_4
- ];
- $_um_data = $_um_model->getDataByAgentId($agent_id);
- if (empty($_um_data)) {
- $_um_model->addData($_data);
- } else {
- $_um_model->updateDataByAgentId($_data, $_data['agent_id']);
- }
- /* 达到限制数量的第一个用户标记为 重名用户 需要运营审核 */
- if (!empty($_rs_data['data']['s_id'])) {
- (new SettleModel())->updateData(['tag' => SettleConst::SETTLE_TAG_2], $_rs_data['data']['s_id']);
- }
- return $this->huoReturn($_rs_data);
- } else {
- $_um_model->deleteByAgentId($agent_id);
- }
- }
- $_max_amount = $this->getAutoMaxAmount($_withdraw_cnt);
- $_diff = StrUtils::compareNumber($amount, $_max_amount);
- $_can_settle = $_diff > 0 ? false : true;
- if (false == $_can_settle) {
- /* 已提现并且第一次提现大于最大自动提现金额 需要运营审核 */
- return $this->huoReturn($_rs_data);
- }
- $_s_id = $_rs_data['data']['s_id'];
- /* 运营审核通过 */
- $_rs = $this->setStatus($agent_id, $_s_id, SettleConst::SETTLE_STATUS_FIN_CHECK, '自动提现');
- if (CommonStatus::NO_ERROR != $_rs['code']) {
- return $this->huoReturn($_rs);
- }
- return $this->setStatus($agent_id, $_s_id, SettleConst::SETTLE_STATUS_OK, '自动提现');
- }
- /**
- * 获取最大提现金额
- *
- * @param int $withdraw_cnt 提现次数
- *
- * @return float
- */
- public function getAutoMaxAmount($withdraw_cnt = 0) {
- $_setting_name = OptionConst::SETTING_SETTLE_LIMIT;
- $_m = new Option();
- $_item = $_m->getOptionData($_setting_name, 1, true);
- if (!empty($_item['option_value'])) {
- $_option_value = json_decode($_item['option_value'], true);
- unset($_item);
- }
- if (empty($withdraw_cnt)) {
- return empty($_option_value['first_limit']) ? 0.5 : $_option_value['first_limit'];
- }
- return empty($_option_value['again_limit']) ? 0 : $_option_value['again_limit'];;
- }
- /**
- * 创建提现订单
- *
- * @param $agent_id
- * @param $amount
- * @param $type
- *
- * @param array $oauth_data //第三方参数
- *
- * @return array
- */
- public function buildSettleOrder($agent_id, $amount, $type, $oauth_data = []) {
- $_data['agent_id'] = $agent_id;
- $_data['amount'] = $amount;
- $_data['type'] = $type;
- $_data['bankname'] = '';
- $_data['branchname'] = '';
- $_data['cardholder'] = empty($oauth_data['real_name']) ? '' : $oauth_data['real_name'];
- $_data['banknum'] = empty($oauth_data['openid']) ? '' : $oauth_data['openid'];
- $_data['status'] = SettleConst::SETTLE_STATUS_OP_CHECK;
- $_rs = (new SettleModel())->createOrder($_data);
- if (false === $_rs) {
- $_code = OrderStatus::ORDER_CREATE_FAIL;
- return $this->huoError($_code, OrderStatus::getMsg($_code));
- }
- $_code = SettleStatus::NO_ERROR;
- $_rdata['s_id'] = $_rs;
- return $this->huoSuccess($_code, SettleStatus::getMsg($_code), $_rdata);
- }
- /**
- * 获取今日有效提现数量, 状态为 1待审核、2待财务审核、3已结算的为有效提现 状态为 4运营审核不通过、5财务审核不通过 为无效提现
- *
- * @param int $agent_id
- *
- * @param float $amount
- *
- * @return array
- */
- public function isAllowSettle($agent_id, $amount = 0.00) {
- /* 判断是否限制提下用户 */
- $_umdata = (new UnusualMemModel())->getDataByAgentId($agent_id);
- if (!empty($_umdata) && MemConst::UNUSUAL_MEN_TYPE_5 == $_umdata['type']) {
- $_code = SettleStatus::SETTLT_REACHED_NOT_ALLOW;
- return $this->huoError($_code, SettleStatus::getMsg($_code));
- }
- if (StrUtils::compareNumber($amount, 0.3) < 0) {
- $_code = SettleStatus::AMOUNT_IS_ERROR;
- return $this->huoError($_code, '提现金额必须不小于0.3元');
- }
- list($_start_time, $_end_time) = Time::today();
- $_map = [
- 'agent_id' => $agent_id,
- 'type' => SettleConst::SETTLE_TYPE_MP,
- 'create_time' => ['gt', $_start_time],
- 'status' => ['in', [SettleConst::SETTLE_STATUS_OP_CHECK, SettleConst::SETTLE_STATUS_FIN_CHECK,
- SettleConst::SETTLE_STATUS_OK]],
- ];
- $_count = (new SettleModel())->where($_map)->count('id');
- $_limit = $this->getSettleLimit();
- if (empty($_count) || $_count < $_limit) {
- $_code = CommonStatus::NO_ERROR;
- return $this->huoError($_code, SettleStatus::getMsg($_code), ['count' => $_count, 'limit' => $_limit]);
- }
- $_code = SettleStatus::SETTLT_REACHED_LIMIT;
- return $this->huoError($_code, SettleStatus::getMsg($_code), ['count' => $_count, 'limit' => $_limit]);
- }
- /**
- * 获取限制提现次数
- */
- public function getSettleLimit() {
- $_limit = 1;
- return $_limit;
- }
- /**
- * 设置状态
- *
- *
- * @param int $admin_id
- * @param int $s_id
- * @param int $status
- * @param string $content
- *
- * @return array
- */
- public function setStatus($admin_id, $s_id, $status, $content = '') {
- $_settle_model = new SettleModel();
- $_data = $_settle_model->getDetail($s_id);
- if (empty($_data) || !is_numeric($admin_id)) {
- $_code = SettleStatus::INVALID_PARAMS;
- return $this->huoError($_code, SettleStatus::getMsg($_code));
- }
- $_old_status = $_data['status'];
- $_check_time = $_data['check_time'];
- switch ($status) {
- case SettleConst::SETTLE_STATUS_FIN_CHECK:
- $_content = '运营审核通过,'.$content;
- $_data['status'] = SettleConst::SETTLE_STATUS_FIN_CHECK;
- $_data['check_time'] = time();
- break;
- case SettleConst::SETTLE_STATUS_OK:
- $_content = '提现成功,'.$content;
- $_data['status'] = SettleConst::SETTLE_STATUS_OK;
- $_data['settle_time'] = time();
- // $_data['pay_status'] = SettleConst::SETTLE_PAY_SUCCESS;
- break;
- case SettleConst::SETTLE_STATUS_OP_NO:
- $_content = '运营审核不通过,'.$content;
- $_data['status'] = SettleConst::SETTLE_STATUS_OP_NO;
- $_data['check_time'] = time();
- $_data['failreason'] = $_content;
- break;
- case SettleConst::SETTLE_STATUS_FIN_NO:
- $_content = '财务审核不通过,'.$content;
- $_data['status'] = SettleConst::SETTLE_STATUS_FIN_NO;
- $_data['settle_time'] = time();
- $_data['failreason'] = $_content;
- break;
- default:
- $_code = SettleStatus::INVALID_PARAMS;
- return $this->huoError($_code, SettleStatus::getMsg($_code));
- }
- $_rs = $_settle_model->updateData($_data, $s_id);
- if (false === $_rs) {
- $_code = SettleStatus::INNER_ERROR;
- return $this->huoError($_code, SettleStatus::getMsg($_code));
- }
- $_agent_wallet = new AgentWallet();
- switch ($status) {
- case SettleConst::SETTLE_STATUS_OK:
- /* 减少冻结金额 */
- $_rs = $_agent_wallet->updateWallet(
- $_data['agent_id'],
- $_data['amount'],
- SettleConst::SETTLE_WALLET_NO,
- SettleConst::SETTLE_WALLET_UNLOCK
- );
- if (SettleStatus::NO_ERROR == $_rs) {
- if (SettleConst::SETTLE_TYPE_MP == $_data['type']) {//小程序提现在线打款 2018-08-16
- /*在线打款*/
- /* 提现入队列 */
- $_data['status'] = SettleConst::SETTLE_STATUS_QUEUE;
- $_queue_data = $_data;
- $_queue_data['admin_id'] = $admin_id;
- $_rs = (new SettleQueue($_queue_data))->pushQueue();
- if (SettleStatus::NO_ERROR != $_rs['code']) { //打款失败
- $_agent_wallet->updateWallet(
- $_data['agent_id'], $_data['amount'], SettleConst::SETTLE_WALLET_NO,
- SettleConst::SETTLE_WALLET_LOCK
- ); //增加冻结金额
- /*更换回运营审核通过*/
- $_data['status'] = $_old_status;
- $_data['check_time'] = $_check_time;
- $_data['pay_status'] = SettleConst::SETTLE_PAY_PROCESSING;
- $_data['failreason'] = $_rs['msg'];
- $_settle_model->updateData($_data, $s_id);
- return $this->huoError(SettleStatus::SETTLT_PAY_ERROR, $_rs['msg']);
- }
- //
- $_content = '进入提现队列,'.$content;
- }
- } else {
- $_data['status'] = SettleConst::SETTLE_STATUS_FIN_CHECK;
- $_data['check_time'] = time();
- $_data['failreason'] = '';
- $_settle_model->updateData($_data, $s_id);
- (new OaOut())->sendAdminSettleMsg($_data['agent_id'], $_data['amount']);
- return $this->huoError($_rs, SettleStatus::getMsg($_rs));
- }
- break;
- case SettleConst::SETTLE_STATUS_OP_NO:
- case SettleConst::SETTLE_STATUS_FIN_NO:
- /* 返回到账户中 */
- $_rs = $_agent_wallet->updateWallet(
- $_data['agent_id'],
- $_data['amount'],
- SettleConst::SETTLE_WALLET_ADD,
- SettleConst::SETTLE_WALLET_UNLOCK
- );
- if (SettleStatus::NO_ERROR == $_rs) {
- (new OaOut())->sendAdminMoneyChangeMsg($_data['agent_id'], $_data['amount']);
- $_data['is_return'] = 2;
- } else {
- $_data['is_return'] = 1;
- }
- break;
- default:
- break;
- }
- $_settle_model->updateData($_data, $s_id);
- $_sh_data['s_id'] = $s_id;
- $_sh_data['u_id'] = $admin_id;
- $_sh_data['content'] = $_content;
- (new SettleHistoryModel())->addLog($_sh_data);
- $_code = SettleStatus::NO_ERROR;
- return $this->huoError($_code, SettleStatus::getMsg($_code));
- }
- /**
- * 放入队列处理
- *
- * @param array $s_data 提现数据
- *
- * @return array
- */
- public function withdrawQueue($s_data) {
- $_data = $s_data;
- $_rs = $this->withdrawPayment($_data);
- if (SettleConst::SETTLE_SUCCESS != $_rs['code']) {
- /* 打款失败 */
- /* 1.1 增加冻结金额 */
- Log::write(
- '打款失败增加冻结金额'.json_encode($_data), Log::ERROR
- );
- if (SettleConst::SETTLE_STATUS_QUEUE == $_data['status']) {
- (new AgentWallet())->updateWallet(
- $_data['agent_id'], $_data['amount'], SettleConst::SETTLE_WALLET_NO,
- SettleConst::SETTLE_WALLET_LOCK
- );
- }
- $_data['status'] = SettleConst::SETTLE_STATUS_FIN_CHECK; // 退回财务审核
- $_data['pay_status'] = SettleConst::SETTLE_PAY_FAILED; // 打款失败
- $_data['failreason'] = json_encode($_rs);
- $_content = '提现失败,'.$_data['failreason'];
- $_rs['code'] = SettleStatus::SETTLT_PAY_ERROR;
- } else {
- /* 打款成功 */
- $_content = '提现成功';
- $_data['status'] = SettleConst::SETTLE_STATUS_OK;
- $_data['settle_time'] = time();
- $_data['pay_status'] = SettleConst::SETTLE_PAY_SUCCESS;
- $_rs['code'] = SettleStatus::NO_ERROR;
- (new OaOut())->sendAdminSettleMsg($_data['agent_id'], $_data['amount']);
- }
- (new SettleModel())->updateData($_data, $_data['id']);
- (new SettleHistoryModel())->addData($s_data['id'], $s_data['admin_id'], $_content);
- $_rs['data'] = [];
- return $this->huoReturn($_rs);
- }
- /**
- * 提现打款
- *
- * @param $s_data
- *
- * @return array|int
- */
- public function withdrawPayment($s_data) {
- if (empty($s_data)) {
- return SettleStatus::INVALID_PARAMS;
- }
- switch ($s_data['type']) {
- case SettleConst::SETTLE_TYPE_BANK: //银行卡
- return SettleStatus::TYPE_EMPTY; // TODO: chenbingling 2018/7/6 银行在线打款未接入
- break;
- case SettleConst::SETTLE_TYPE_ALIPAY: //支付宝
- $_pay_class = new Alipay();
- $_pay_class->setPayeeAccount($s_data['banknum']);
- $_pay_class->setPayerShowName($this->getSettleRemark('show_name'));
- //$_pay_class->setRealAmount('0.1'); //TODO: chenbingling 2018/7/6 测试打款 使用 正式上线请勿使用
- break;
- case SettleConst::SETTLE_TYPE_WXPAY: //微信
- case SettleConst::SETTLE_TYPE_MP: //小程序提现
- /* 获取微信商户配置 */
- $_mem_auto = (new MemoauthModel())->getInfoByOpenId(OauthConst::OAUTH_WEIXIN, $s_data['banknum']);
- $_mp_id = (new MpConfModel())->getMpIdById($_mem_auto['conf_id']);
- $_config = (new OaMchLogic())->getDefaultMchConf($_mp_id);
- $_pay_class = new Wxpay($_config);
- $_pay_class->setOpenId($s_data['banknum']);
- //$_pay_class->setRealAmount('1'); //TODO: chenbingling 2018/7/6 测试打款 使用 正式上线请勿使用
- break;
- default:
- return SettleStatus::TYPE_EMPTY;
- }
- /* 获取后台提现配置 */
- $_vcfg = (new SettleVerifiedOut())->getVerifiedCfg();
- if (CommonConst::STATUS_YES == $_vcfg['is_verified']) { //提现需实名
- $_withdraw_cnt = (new SettleModel())->getCnt($s_data['agent_id']);
- if (CommonConst::STATUS_YES == $_vcfg['first_verified'] || $_withdraw_cnt > 1) {
- $_agent_data = AgentCache::ins()->getInfoByAgentId($s_data['agent_id']);
- $_mem_data = MemCache::ins()->getInfoById(get_val($_agent_data, 'mem_id', 0));
- $_pay_class->setCheckName('FORCE_CHECK'); //微信校验用户姓名选项 NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
- $s_data['cardholder'] = $_mem_data['real_name'];
- }
- }
- $_pay_class->setPayeeRealName($s_data['cardholder']);
- $_pay_class->setOrderId($s_data['id']);
- $_pay_class->setRealAmount($s_data['amount']); //TODO: chenbingling 2018/7/6 正式打款请用这个
- $_pay_class->setRemark($this->getSettleRemark('remark', $s_data['amount']));
- $_rs = $_pay_class->withDraw();
- // $_rs=[];
- /*打款记录*/
- $_pay_data = [];
- $_pay_data['mem_id'] = get_val($s_data, 'mem_id', 0);
- $_pay_data['agent_id'] = get_val($s_data, 'agent_id', 0);
- $_pay_data['order_id'] = get_val($s_data, 'id', '');
- $_pay_data['amount'] = get_val($s_data, 'amount', 0.00);
- $_pay_data['type'] = get_val($s_data, 'type', '');
- $_pay_data['cardholder'] = get_val($s_data, 'cardholder', '');
- $_pay_data['banknum'] = get_val($s_data, 'banknum', '');
- $_pay_data['code'] = get_val($_rs, 'code', '');
- $_pay_data['msg'] = get_val($_rs, 'msg', '');
- $_pay_data['result'] = get_val($_rs, 'result', '');
- $_pay_data['query_result'] = get_val($_rs, 'query_result', '');
- (new SettleLogLogic())->addPayLog($_pay_data);
- return $_rs;
- }
- /**
- * 获取提现显示名称和备注
- *
- * @param $name
- * @param int $money
- *
- * @return mixed
- */
- protected function getSettleRemark($name = 'show_name', $money = 0) {
- $_setting_name = OptionConst::NAME_SETTLE_PAY_NOTE;
- $_option_value = [
- 'show_name' => SettleConst::SETTLE_SHOW_NAME,
- 'remark' => SettleConst::SETTLE_REMARK
- ];
- $_m = new Option();
- $_item = $_m->getOptionData($_setting_name, 1, true, json_encode($_option_value));
- if (!empty($_item['option_value'])) {
- $_item['option_value'] = json_decode($_item['option_value'], true);
- }
- $_data = [
- 'show_name' => $_item['option_value']['show_name'], //提现显示付款方姓名
- 'remark' => sprintf($_item['option_value']['remark'], $money) //提现显示备注
- ];
- if (empty($_data[$name])) {
- return '';
- }
- return $_data[$name];
- }
- }
|