<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: huajie < banhuajie @ 163 . com >
// +----------------------------------------------------------------------
namespace Admin\Model;
use Common\Api\GameApi;
use Org\WeixinSDK\Weixin;
use Think\Model;
/**
* 文档基础模型
*/
class SpendModel extends Model{
/* 自动验证规则 */
protected $_validate = array();
/* 自动完成规则 */
protected $_auto = array(
array('pay_time', 'getCreateTime', self::MODEL_INSERT,'callback'),
array('pay_status', 0, self::MODEL_INSERT),
array('order_number','',self::MODEL_INSERT),
);
protected function _after_select(& $result,$options){
foreach($result as $key=>$value){
// $result[$key]['pay_way'] = date('Y-m-d ', $value['time']);
}
}
/**
* 构造函数
* @param string $name 模型名称
* @param string $tablePrefix 表前缀
* @param mixed $connection 数据库连接信息
*/
public function __construct($name = '', $tablePrefix = '', $connection = '') {
/* 设置默认的表前缀 */
$this->tablePrefix ='tab_';
/* 执行构造方法 */
parent::__construct($name, $tablePrefix, $connection);
}
/**
* 创建时间不写则取当前时间
* @return int 时间戳
* @author huajie < banhuajie @ 163 . com >
*/
protected function getCreateTime(){
$create_time = I('post.create_time');
return $create_time?strtotime($create_time):NOW_TIME;
}
public function amdin_account()
{
return session('user_auth.username');
}
public function totalSpendTimes($map=""){
$map['s.pay_status'] = 1;
$data = $this->alias("s")->field("IFNULL(count(pay_amount),0) as count")
->join("left join tab_game g on g.id = s.game_id")
->where($map)
->find();
return $data['count'];
}
/**
* [dealPage 页码处理]
* @param [type] $p [description]
* @return [type] [description]
*/
public function dealPage($p){
$page = intval($p);
$page = $page ? $page : 1; //默认显示第一页数据
return $page;
}
/**
* 自动补单
*/
public static function auto_repair(){
$game = new GameApi();
$map['pay_status'] = 1;
$map['pay_game_status'] = 0;
$order = M("spend",'tab_')->field('pay_order_number,1 as code')->where($map)->select();//普通消费
$bind_spend = M("bind_spend",'tab_')->field('pay_order_number,2 as code')->where($map)->select();//绑币消费
if(!empty($bind_spend)){
array_push($order,$bind_spend);
}
$success_num = $error_num = 0;
foreach ($order as $key=>$val) {
$param['out_trade_no'] = $val['pay_order_number'];
$result = $game->game_pay_notify($param, $val['code']);
if($val['code'] == 1){
M('spend','tab_')->where(['pay_order_number'=>$val['pay_order_number']])->setInc('auto_compensation');
}else{
M('bind_spend','tab_')->where(['pay_order_number'=>$val['pay_order_number']])->setInc('auto_compensation');
}
if($result == "success"){
$success_num++;
}else{
$error_num++;
}
}
$time = time_format0();
\Think\Log::record("自动补单({$time}) :成功 {$success_num} 个,失败:{$error_num}个");
}
/**
* 退款接口
* @param $map
*/
public function Refund($map,$order,$sign)
{
if(md5("mcaseqwezdsi".$order)!==$sign){
return false;
}
$RefundRecord = M('RefundRecord', 'tab_')->where($map)->find();
if (null == $RefundRecord) {
$find = $this->where($map)->find();
$order_number = $find['pay_way'] == 1 ? date("YmdHis") : "TK_" . date('Ymd') . date('His') . sp_random_string(4);
$BatchNo=date("YmdHis");
} else {
$order_number = $RefundRecord['order_number'];
$BatchNo=$RefundRecord['batch_no'];
$find = $RefundRecord;
}
if ($find['pay_way'] == 1) {
//页面上通过表单选择在线支付类型, 支付宝为alipay 财付通为tenpay
$pay = new \Think\Pay('alipay', C('alipay'));
$vo = new \Think\Pay\PayVo();
$detail_data = $find['order_number'] . "^" . $find['pay_amount'] . "^调单";
$find['batch_no']=$BatchNo;
$vo->setOrderNo($find['order_number'])
->setService("refund_fastpay_by_platform_pwd")
->setSignType("MD5")
->setPayMethod("refund")
->setTable("RefundRecord")
->setBatchNo($BatchNo)
->setDetailData($detail_data);
$this->add_refund_record($find, $find['order_number']);
$this->where($map)->delete();
return $pay->buildRequestForm($vo);
} elseif ($find['pay_way'] == 3) {
$weixn = new Weixin();
$res = json_decode($weixn->weixin_Refund_pub($find['pay_order_number'], $order_number, $find['pay_amount'], $find['pay_amount'], C('wei_xin_app.partner')), true);
$this->add_refund_record($find, $order_number);
$this->where($map)->delete();
if ($res['status'] == 1) {
return $res['status'];
} else {
return $res;
}
} elseif ($find['pay_way'] == 4) {
$config = array("partner" => trim(C("weixin.partner")), "email" => "", "key" => trim(C("weixin.key")));
$pay = new \Think\Pay('swiftpass', $config);
$vo = new \Think\Pay\PayVo();
$vo->setService('unified.trade.refund')
->setSignType("MD5")
->setPayMethod("refund")
->setTable("RefundRecord")
->setOrderNo($find['pay_order_number'])
->setBatchNo($order_number)
->setFee($find['pay_amount']);
$this->add_refund_record($find, $order_number);
$this->where($map)->delete();
$res=$pay->buildRequestForm($vo);
if ($res['status'] == 0) {
return $res['status'];
} else {
return false;
}
} elseif ($find['pay_way'] == 0) {
$user_map['id'] = $find['user_id'];
M('user', 'tab_')->where($user_map)->setInc('balance', $find['pay_amount']);
$this->add_refund_record($find, $order_number);
$this->where($map)->delete();
return true;
}
}
/**
* 添加退款记录
* @param $data
* @return mixed
*/
public function add_refund_record($data, $order_number)
{
$RefundRecord = M('RefundRecord', 'tab_');
unset($data['id']);
$map['pay_order_number'] = $data['pay_order_number'];
$find = $RefundRecord->where($map)->find();
if (null !== $find) {
if($data['pay_way']==4||$data['pay_way']==3){
$RefundRecord->where($map)->delete();
$data['tui_status'] = 2;
$data['create_time'] = time();
$data['tui_amount'] = $data['pay_amount'];
$data['order_number'] = $order_number;
return $RefundRecord->add($data);
}else{
return true;
}
} else {
if ($data['pay_way'] == 0) {
$data['tui_status'] = 1;
$data['tui_time'] = time();
$savv['sub_status']=1;
$savv['settle_check']=1;
$this->where($map)->save($savv);
}elseif($data['pay_way'] == 4||$data['pay_way']==3){
$data['tui_status'] = 2;
}
$data['create_time'] = time();
$data['tui_amount'] = $data['pay_amount'];
$data['order_number'] = $order_number;
return $RefundRecord->add($data);
}
}
/**
* 微信退款查询接口
* @param [type] $orderNo [description]
* @return [type] [description]
*/
public function weixin_refundquery($orderNo){
$weixn = new Weixin();
$res = $weixn->weixin_refundquery($orderNo);
if($res=="SUCCESS"){
M('RefundRecord', 'tab_')->where(array('pay_order_number'=>$orderNo))->setField('tui_status', 1);
return json_encode(array('status'=>1,'msg'=>'退款成功'));
}elseif($res=="FAIL"){
return json_encode(array('status'=>0,'msg'=>'退款失败'));
}elseif($res=="PROCESSING"){
return json_encode(array('status'=>0,'msg'=>'退款处理中'));
}
}
/**
* 威富通查询退款接口
* @param [type] $map [description]
* @return [type] [description]
*/
public function swiftpass_refund($orderNo){
$config = array("partner" => trim(C("weixin.partner")), "email" => "", "key" => trim(C("weixin.key")));
$pay = new \Think\Pay('swiftpass', $config);
$vo = new \Think\Pay\PayVo();
$vo->setOrderNo($orderNo)
->setService('unified.trade.refundquery')
->setSignType("MD5")
->setPayMethod("find")
->setTable("RefundRecord");
$res=$pay->buildRequestForm($vo);
if($res['refund_status']=="SUCCESS"){
M('RefundRecord', 'tab_')->where(array('pay_order_number'=>$orderNo))->setField('tui_status', 1);
return json_encode(array('status'=>1,'msg'=>'退款成功'));
}elseif($res['refund_status']=="FAIL"){
return json_encode(array('status'=>0,'msg'=>'退款失败'));
}elseif($res['refund_status']=="PROCESSING"){
return json_encode(array('status'=>0,'msg'=>'退款处理中'));
}
}
/**
* 开放平台 付费人数
* @param string $map
* @return mixed
* author: xmy 280564871@qq.com
*/
public function countSpendUserOfOpen($map=""){
$sql = $this->alias("s")->field("s.user_id")
->join("left join tab_game g on g.id = s.game_id")
->where($map)
->group("s.game_id,s.user_id")
->select(false);
$sql = "select count(DISTINCT user_id) as num from ({$sql}) as res";
$data = M()->query($sql);
return $data[0]['num'];
}
/**
* 累计付费
* @param string $map
* @return mixed
* author: xmy 280564871@qq.com
*/
public function totalSpend($map=""){
$map['s.pay_status'] = 1;
$data = $this->alias("s")->field("IFNULL(sum(pay_amount),0) as num")
->join("right join tab_game g on g.id = s.game_id")
->where($map)
->find();
return $data['num'];
}
/**
* 获取开放平台流水
* @param $map
* @param $develop_id
* author: xmy 280564871@qq.com
*/
public function getOpenSpend($map,$develop_id,$game_id){
// empty($game_id) || $map['s.game_id'] = $game_id;
empty($game_id) || $join = "and g.id = {$game_id}";
$data = $this->alias("s")->field("IFNULL(sum(pay_amount),0) as num,d.time")
->join("right join tab_game g on g.id = s.game_id and g.developers = $develop_id {$join}")
->join("right join sys_date_list d on d.time = FROM_UNIXTIME(s.pay_time,'%Y-%m-%d') and s.pay_status = 1")
->where($map)
->group("d.time")
->select();
return $data;
}
/**
* 付费玩家数
* @param $map
* @param $develop_id
* @return mixed
* author: xmy 280564871@qq.com
*/
public function getPayerNum($map,$develop_id,$game_id){
// empty($game_id) || $map['s.game_id'] = $game_id;
empty($game_id) || $join = "and g.id = {$game_id}";
$data = $this->alias("s")->field("IFNULL(count(DISTINCT user_id),0) as num,d.time")
->join("right join tab_game g on g.id = s.game_id and g.developers = $develop_id {$join}")
->join("right join sys_date_list d on d.time = FROM_UNIXTIME(s.pay_time,'%Y-%m-%d') and s.pay_status = 1")
->where($map)
->group("d.time")
->select();
return $data;
}
/**
* 新增付费玩家
* @param $start
* @param $end
* @param $develop_id
* @return mixed
* author: xmy 280564871@qq.com
*/
public function getNewPayerNum($start,$end,$develop_id,$game_id){
//第一次充值
empty($game_id) || $map['s.game_id'] = $game_id;
$map['s.pay_status'] = 1;
$sql = $this->alias("s")->field("user_id,min(pay_time) as pay_time")
->join("right join tab_game g on g.id = s.game_id and g.developers = $develop_id")
->where($map)
->group("s.user_id")
->select(false);
$sql = "SELECT count(res.user_id) as num,d.time FROM ({$sql}) res right join sys_date_list d on d.time = FROM_UNIXTIME(res.pay_time,'%Y-%m-%d')
WHERE d.time BETWEEN '{$start}' and '{$end}' GROUP BY d.time";
$data = $this->query($sql);
return $data;
}
/**
* 累计付费玩家数(按天分组)
* @param $map
* @param $develop_id
* @return mixed
* author: xmy 280564871@qq.com
*/
public function getTotalPayerNum($start,$end,$develop_id){
$start = strtotime($start);
$end = strtotime($end);
$map['g.developers'] = $develop_id;
$map['s.pay_status'] = 1;
for ($time = $start; $time < = $end; $time += 86400) {
$map['s.pay_time'] = ['lt',$time+86399];
$data[]['num'] = $this->countSpendUserOfOpen($map);
}
return $data;
}
/**
* 累计流水
* @param $map
* @return mixed
* author: xmy 280564871@qq.com
*/
public function getTotalSpend($map){
$map['pay_status'] = 1;
$data = $this->field("IFNULL(sum(pay_amount),0) as num")->where($map)->find();
return $data;
}
/*
* 游戏充值未到账列表
* @return array 结果集
* @author 鹿文学
*/
public function checkSpend() {
$list = $this->field('id,user_id,user_account,game_id,game_name,pay_amount,pay_order_number')->where(array('pay_status'=>0))->select();
$type = 101;
if ($list[0]) {
$list = D('check')->dealWithCheckList($type,$list);
if (empty($list[0])) {return '';}
foreach ($list as $k => $v) {
$data[$k]['info'] = '玩家:'.$v['user_account'].',游戏['.$v['game_name'].']充值金额:'.$v['pay_amount'].',订单状态:下单未支付';
$data[$k]['type'] = $type;
$data[$k]['url'] = U('Spend/lists',array('pay_order_number'=>$v['pay_order_number']));
$data[$k]['create_time'] = time();
$data[$k]['status']=0;
$data[$k]['position'] = $v['id'];
}
return $data;
}else {
D('check')->dealWithCheckListOnNull($type);
return '';
}
}
/*
* 游戏补单列表
* @return array 结果集
* @author 鹿文学
*/
public function checkSupplement() {
$list = $this->field('id,user_id,user_account,pay_order_number')->where(array('pay_status'=>1,'pay_game_status'=>0))->select();
$type = 102;
if ($list[0]) {
$list = D('check')->dealWithCheckList($type,$list);
if (empty($list[0])) {return '';}
foreach ($list as $k => $v) {
$data[$k]['info'] = '玩家:'.$v['user_account'].',订单:'.$v['pay_order_number'].',操作:补单失败';
$data[$k]['type'] = $type;
$data[$k]['url'] = U('Spend/lists',array('pay_order_number'=>$v['pay_order_number']));
$data[$k]['create_time'] = time();
$data[$k]['status']=0;
$data[$k]['position'] = $v['id'];
}
return $data;
}else {
D('check')->dealWithCheckListOnNull($type);
return '';
}
}
/**
* 统计总流水
* @param array $where 条件数组
* @return integer 数量
* @author 鹿文学
*/
public function totalAmount($map=array()) {
$map['pay_status'] = 1;
$sum = $this->where($map)->sum('pay_amount');
return $sum?$sum:0;
}
/**
* 分组统计流水
* @param array $map 条件数组
* @param string $fieldname 字段别名
* @param string $group 分组字段名
* @param integer $flag 时间类别( 1: 天, 2: 月, 3: 周)
* @return array 详细数据
* @author 鹿文学
*/
public function totalAmountByGroup($map=array(),$fieldname='amount',$group='time',$flag=1,$order='time') {
switch($flag) {
case 2:{$dateform = '%Y-%m';};break;
case 3:{$dateform = '%Y-%u';};break;
case 4:{$dateform = '%Y';};break;
case 5:{$dateform = '%Y-%m-%d %H';};break;
default:$dateform = '%Y-%m-%d';
}
$map['pay_status']=1;
$data = $this->field('FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',sum(pay_amount) as '.$fieldname)
->where($map)->group($group)->order($order)->select();
return $data;
}
/**
* 分组统计所有流水
* @param array $map 条件数组
* @param string $fieldname 字段别名
* @param string $group 分组字段名
* @param integer $flag 时间类别( 1: 天, 2: 月, 3: 周)
* @return array 详细数据
* @author 鹿文学
*/
public function allAmountByGroup($map=array(),$fieldname='amount',$group='time',$flag=1,$order='time') {
switch($flag) {
case 2:{$dateform = '%Y-%m';};break;
case 3:{$dateform = '%Y-%u';};break;
case 4:{$dateform = '%Y';};break;
case 5:{$dateform = '%Y-%m-%d %H';};break;
default:$dateform = '%Y-%m-%d';
}
$map['pay_status']=1;
$union = D('deposit')->field('pay_order_number,FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',sum(pay_amount) as '.$fieldname)
->where(['create_time'=>$map['pay_time'],'pay_status'=>1])
->group($group)->select(false);
$bind = M('Bind_recharge','tab_')->field('pay_order_number,FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',sum(real_amount) as '.$fieldname)
->where(['create_time'=>$map['pay_time'],'pay_status'=>1])
->group($group)->select(false);
$sql = $this->field('pay_order_number,FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',sum(pay_amount) as '.$fieldname)
->union('('.$union.')')
->union('('.$bind.')')
->where($map)->group($group)->select(false);
$data = $this->table('('.$sql.') as a')->field('a.'.$group.',sum(a.'.$fieldname.') as '.$fieldname)->group('a.'.$group)->order($order)->select();
return $data;
}
/*
* 付费用户
* @param array $map 条件数组
* @param string $fieldname 字段别名
* @param string $group 分组字段名
* @param integer $flag 时间类别( 1: 天, 2: 月, 3: 周)
* @return array 详细数据
* @author 鹿文学
*/
public function totalPlayerByGroup($map=array(),$fieldname='count',$group='time',$flag=1,$order='time') {
switch($flag) {
case 2:{$dateform = '%Y-%m';};break;
case 3:{$dateform = '%Y-%u';};break;
case 4:{$dateform = '%Y';};break;
case 5:{$dateform = '%Y-%m-%d %H';};break;
default:$dateform = '%Y-%m-%d';
}
$map['pay_status']=1;
$data = $this->field('FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',count( DISTINCT user_id) as '.$fieldname)
->where($map)->group($group)->order($order)->select();
return $data;
}
/*
* 付费用户
* @param integer $start 开始时间戳
* @param integer $end 结束时间戳
* @param string $fieldname 字段别名
* @param string $group 分组字段名
* @param integer $flag 时间类别( 1: 天, 2: 月, 3: 周)
* @return array 详细数据
* @author 鹿文学
*/
public function totalPlayerByTime($start,$end,$fieldname='count',$group='time',$flag=1,$order='time') {
switch($flag) {
case 2:{$dateform = '%Y-%m';};break;
case 3:{$dateform = '%Y-%u';};break;
case 4:{$dateform = '%Y';};break;
case 5:{$dateform = '%Y-%m-%d %H';};break;
default:$dateform = '%Y-%m-%d';
}
$map['pay_status']=1;
$map['create_time'] = ['between',[$start,$end]];
$bindrecharge_data = M('bind_recharge','tab_')->field('FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',GROUP_CONCAT( DISTINCT user_id) as user_id')
->where($map)->group($group)->select(false);
$deposit_data = M('deposit','tab_')->field('FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',GROUP_CONCAT( DISTINCT user_id) as user_id')
->where($map)->group($group)->select(false);
$map['pay_way'] = array('gt',0);
unset($map['create_time']);
$map['pay_time'] = ['between',[$start,$end]];
$lists = $this->field('FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',GROUP_CONCAT( DISTINCT user_id) as user_id')
->union(' ('.$bindrecharge_data.') ')->union(' ('.$deposit_data.') ')
->where($map)->group($group)->select(false);
$lists = $this->field('a.'.$group.',GROUP_CONCAT(a.user_id) as user_id')->table(' ('.$lists.') as a')->group('a.'.$group)->order('a.'.$order)->select();
$data = [];
foreach($lists as $k=>$v) {
$userid = array_unique(explode(',',$v['user_id']));
$data[$k] = array(
$group => $v[$group],
$fieldname=>count($userid),
);
}
return $data;
}
/*
* 付费用户总数
* @param array $map 条件数组
* @author 鹿文学
*/
public function player($map=array()) {
$map['pay_status']=1;
$data = $this->field('count( DISTINCT user_id) as count')
->where($map)->select();
return $data[0]?$data[0]['count']:0;
}
/*
* 付费总数
* @param array $map 条件数组
* @author 鹿文学
*/
public function amount($map=array()) {
$map['pay_status'] = 1;
$data = $this
->where($map)->sum('pay_amount');
return $data?$data:0;
}
/**
* 列表
*
* @param int $p
* @param array $map
* @param bool $field
*
* @return mixed
*
* @author: 鹿文学[lwx]< fyj301415926 @ 126 . com >
* @since: 2019\4\11 0011 13:40
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function lists($p=1, $map=array(), $order, $field=true)
{
$page = intval($p);
$page = $page ? $page : 1; //默认显示第一页数据
if(isset($_REQUEST['row'])) {
$row = $_REQUEST['row'];
} else {
$row = 10;
}
$list = $this->field("tab_spend.*")
->join("left join tab_promote as tp on tp.id = tab_spend.promote_id")
->where($map)
->page($page, $row)
->order($order?$order:'tab_spend.pay_time desc')
->select();
$count = $this->where($map)->join("left join tab_promote as tp on tp.id = tab_spend.promote_id")->count();
$data['data'] = $list;
$page = set_pagination($count,$row);
if($page) {
$data['page']=$page;
}
return $data;
}
}