// +---------------------------------------------------------------------- namespace App\Services; use App\Models\ActionLogModel; use App\Models\MemberModel; use App\Models\TradeModel; use Illuminate\Support\Facades\DB; use function GuzzleHttp\Psr7\str; /** * 交易明细管理-服务类 * @author wesmiler * @since 2020/11/11 * Class TradeService * @package App\Services */ class TradeService extends BaseService { protected static $instance = null; /** * 构造函数 * @author wesmiler * @since 2020/11/11 * TradeService constructor. */ public function __construct() { $this->model = new TradeModel(); } /** * 静态入口 * @return TradeService|null */ public static function make(){ if(!self::$instance){ self::$instance = new TradeService(); } return self::$instance; } /** * 获取列表 * @return array * @since 2020/11/11 * @author wesmiler */ public function getList() { $params = request()->all(); $page = isset($params['pageSize']) ? intval($params['pageSize']) : PAGE; $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : PERPAGE; $dataList = $this->model::from('account_logs as a') ->leftJoin('member as m', 'm.id', '=', 'a.user_id') ->where(function ($query) use ($params) { $query->where('a.mark', 1); $type = isset($params['type']) ? $params['type'] : 0; if ($type > 0) { $type = explode(',', $type); $query->whereIn('a.type', $type); } $payType = isset($params['pay_type']) ? $params['pay_type'] : 0; if ($payType > 0) { $query->where('a.pay_type', $payType); } $coinType = isset($params['coin_type']) ? $params['coin_type'] : 0; if ($coinType > 0) { $query->where('a.coin_type', $coinType); } $changeType = isset($params['change_type']) ? $params['change_type'] : 0; if ($changeType > 0) { $query->where('a.change_type', $changeType); } $userId = isset($params['user_id']) ? $params['user_id'] : 0; if ($userId > 0) { $query->where('a.user_id', $userId); } $datetime = isset($params['datetime'])? $params['datetime'] : []; $dateStart = $datetime && isset($datetime[0])? $datetime[0] : ''; $dateEnd = isset($datetime[1])? $datetime[1] : ''; if($dateStart && $dateEnd && $dateEnd> $dateStart){ $query->where('a.create_time', '>=', strtotime($dateStart))->where('a.create_time','<=', strtotime($dateEnd)+86399); }else if($dateStart && $dateStart == $dateEnd){ $query->where('a.create_time', '>=', strtotime($dateStart))->where('a.create_time','<=', strtotime($dateStart)+86399); }else if ($dateStart){ $query->where('a.create_time', '<=', strtotime($dateStart)+86399); } $status = isset($params['status']) ? $params['status'] : 0; if ($status > 0) { $query->where('a.status', $status); } else { $query->whereIn('a.status', [1, 2, 3]); } }) ->where(function ($query) use ($params) { $keyword = isset($params['keyword']) ? trim($params['keyword']) : ''; if (!empty($keyword)) { $query->where('m.nickname','like',"%{$keyword}%"); } }) ->select(['a.id', 'a.user_id', 'm.nickname','a.type','a.pay_type','a.change_type','a.coin_type','a.money', 'a.balance', 'a.status', 'a.create_time', 'a.update_time','a.remark']) ->orderBy('a.create_time', 'desc') ->paginate($pageSize); $dataList = $dataList ? $dataList->toArray() : []; if ($dataList) { foreach ($dataList['data'] as &$item) { $item['create_time'] = $item['create_time'] ? datetime($item['create_time'],'Y-m-d H:i:s') : ''; } unset($item); } // 合计 $curDate = date('Y-m-d'); $counts = $this->counts($params); // 今日 $params['datetime'] = [$curDate,$curDate]; $countToday = $this->counts($params); // 本周 $w = date('w', strtotime($curDate)); $w = $w? $w-1 : 6; $params['datetime'] = [ date('Y-m-d', strtotime("{$curDate} - {$w} days")), $curDate, ]; $countWeek = $this->counts($params); // 本月 $params['datetime'] = [ date('Y-m-01'), $curDate, ]; $countMonth = $this->counts($params); return [ 'code' => 0, 'success'=> true, 'msg' => '操作成功', 'count' => isset($dataList['total']) ? $dataList['total'] : 0, 'counts'=> [ 'totals'=> $counts, 'total'=> $counts[2], 'today'=> $countToday[2], 'todays'=> $countToday, 'week'=> $countWeek[2], 'weeks'=> $countWeek, 'month'=> $countMonth[2], 'months'=> $countMonth, ], 'data' => isset($dataList['data']) ? $dataList['data'] : 0, ]; } /** * 消费排名 * @return mixed */ public function ranks($dateType, $coinType=0){ $firstTime = strtotime(date('Y-m-d')); if($dateType==1){ $firstTime = strtotime('monday this week'); }else if($dateType==2){ $firstTime = strtotime(date('Y-m-01')); }else if($dateType==3){ $firstTime = strtotime(date('Y-01-01')); } $where = ['a.mark'=> 1,'m.mark'=> 1,'a.status'=> 1,'a.coin_type'=> 2,'a.pay_type'=> 2,'a.change_type'=> 2]; if($coinType==1 || $coinType==3) { $where['a.coin_type'] = $coinType; $where['a.pay_type'] = 1; } $dataList = $this->model::from('account_logs as a') ->leftJoin('member as m', 'm.id', '=', 'a.user_id') ->where('a.create_time','>=', $firstTime) ->where('a.create_time','<=', time()) ->where($where) ->select(['m.avatar','m.nickname','a.id','a.user_id', \DB::raw('sum('.env('DB_PREFIX').'a.`money`) as total')]) ->groupBy('a.user_id') ->orderBy(\DB::raw('sum('.env('DB_PREFIX').'a.`money`)'),'desc') ->orderBy('m.create_time','asc') ->take(50) ->get(); if($dataList){ foreach ($dataList as &$item){ $item['avatar'] = $item['avatar']? get_image_url($item['avatar']) : ''; $item['total'] = $coinType==2? moneyFormat($item['total']) : intval($item['total']); } unset($item); } return $dataList; } /** * 统计表数据 * @param $dateType * @return array */ public function tableData($dateType, $coinType=0){ $cacheKey = "caches:statistics:table_trade_{$dateType}_{$coinType}"; $datas = RedisService::get($cacheKey); if($datas){ return $datas; } $firstTime = strtotime(date('Y-m-d')); if($dateType == 0){ $formatStr = "%Y-%m-%d %H:00"; $firstTime = strtotime(date('Y-m-d')); for($i = 0; $i<24; $i++){ $i = $i<10? '0'.$i : $i; $ks = date('Y-m-d')." {$i}:00"; $datas[$ks] = [ 'date'=> $i.'点', 'ks'=> $ks, 'value'=> 0, ]; } }else if($dateType == 1){ $formatStr = "%Y-%m-%d"; $firstTime = strtotime('monday this week'); $weeks = ['周一','周二','周三','周四','周五','周六','周日']; for($i = 0; $i<7; $i++){ $ks = date('Y-m-d', $firstTime+$i*86400); $datas[$ks] = [ 'date'=> $weeks[$i], 'ks'=> $ks, 'value'=> 0, ]; } }else if($dateType == 2){ $formatStr = "%Y-%m-%d"; $firstTime = strtotime(date('Y-m-01')); $num = cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y')); for($i = 1; $i<=$num; $i++){ $i = $i<10? '0'.$i : $i; $ks = date('Y-m')."-{$i}"; $datas[$ks] = [ 'date'=> $i.'号', 'ks'=> $ks, 'value'=> 0, ]; } }else if($dateType == 3){ $formatStr = "%Y-%m"; $firstTime = strtotime(date('Y-01-01')); for($i = 1; $i<=12; $i++){ $ks = date('Y')."-".($i<10? '0'.$i : $i); $datas[$ks] = [ 'date'=> $i.'月', 'ks'=> $ks, 'value'=> 0, ]; } } $where = ['a.mark'=> 1,'m.mark'=> 1,'a.status'=> 1,'a.coin_type'=> 2,'a.pay_type'=> 2,'a.change_type'=> 2]; if($coinType==1 || $coinType==3) { $where['a.coin_type'] = $coinType; $where['a.pay_type'] = 1; } $counts = $this->model::from('account_logs as a') ->leftJoin('member as m', 'm.id', '=', 'a.user_id') ->where($where) ->where('a.create_time','>=', $firstTime) ->where('a.create_time','<=', time()) ->select([\DB::raw('sum('.env('DB_PREFIX').'a.`money`) as value'),\DB::raw('FROM_UNIXTIME('.env('DB_PREFIX')."a.create_time,'{$formatStr}') as ks")]) ->groupBy(\DB::raw('FROM_UNIXTIME('.env('DB_PREFIX')."a.create_time,'{$formatStr}')")) ->get(); $counts = $counts? $counts->toArray() : []; if($counts){ foreach ($counts as $v){ if(isset($datas[$v['ks']])){ $datas[$v['ks']]['value'] = $coinType==2? moneyFormat($v['value']) : intval($v['value']); } } } $datas = array_values($datas); RedisService::set($cacheKey, $datas, rand(5, 10)); return $datas; } /** * 统计 * @param $params * @return mixed */ public function counts($params){ $counts = [0,0,0]; $countData = $this->model::from('account_logs as a') ->leftJoin('member as m', 'm.id', '=', 'a.user_id') ->where(function ($query) use ($params) { $query->where('a.mark', 1); $type = isset($params['type']) ? $params['type'] : 0; if ($type > 0) { $type = explode(',', $type); $query->whereIn('a.type', $type); } $payType = isset($params['pay_type']) ? $params['pay_type'] : 0; if ($payType > 0) { $query->where('a.pay_type', $payType); } $coinType = isset($params['coin_type']) ? $params['coin_type'] : 0; if ($coinType > 0) { $query->where('a.coin_type', $coinType); } $changeType = isset($params['change_type']) ? $params['change_type'] : 0; if ($changeType > 0) { $query->where('a.change_type', $changeType); } $userId = isset($params['user_id']) ? $params['user_id'] : 0; if ($userId > 0) { $query->where('a.user_id', $userId); } $datetime = isset($params['datetime'])? $params['datetime'] : []; $dateStart = $datetime && isset($datetime[0])? $datetime[0] : ''; $dateEnd = isset($datetime[1])? $datetime[1] : ''; if($dateStart && $dateEnd && $dateEnd> $dateStart){ $query->where('a.create_time', '>=', strtotime($dateStart))->where('a.create_time','<=', strtotime($dateEnd)+86399); }else if($dateStart && $dateStart == $dateEnd){ $query->where('a.create_time', '>=', strtotime($dateStart))->where('a.create_time','<=', strtotime($dateStart)+86399); }else if ($dateStart){ $query->where('a.create_time', '<=', strtotime($dateStart)+86399); } $status = isset($params['status']) ? $params['status'] : 0; if ($status > 0) { $query->where('a.status', $status); } else { $query->whereIn('a.status', [1, 2, 3]); } }) ->where(function ($query) use ($params) { $keyword = isset($params['keyword']) ? trim($params['keyword']) : ''; if (!empty($keyword)) { $query->where('m.nickname','like',"%{$keyword}%"); } }) ->select([\DB::raw("sum(money) as total"),'a.change_type']) ->orderBy('a.create_time','desc') ->groupBy('a.change_type') ->get(); $countData = $countData? $countData : []; $count1 = isset($countData[0]['total'])? $countData[0]['total'] : 0; $count2 = isset($countData[1]['total'])? $countData[1]['total'] : 0; if($counts){ $counts[0] = $count1; $counts[1] = -$count2; $counts[2] = moneyFormat($count1-$count2); }else{ $counts = [0,0,0]; } return $counts; } /** * 获取列表 * @return array * @since 2020/11/11 * @author wesmiler */ public function getDataList($params) { $page = isset($params['pageSize']) ? intval($params['pageSize']) : PAGE; $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : PERPAGE; $dataList = $this->model::from('account_logs as a') ->leftJoin('member as m', 'm.id', '=', 'a.user_id') ->where(function ($query) use ($params) { $query->where(['a.mark'=>1,'a.status'=> 1]); $type = isset($params['type']) ? $params['type'] : 0; if ($type > 0) { $query->where('a.type', $type); } $payType = isset($params['pay_type']) ? $params['pay_type'] : 0; if ($payType > 0) { $query->where('a.pay_type', $payType); } $coinType = isset($params['coin_type']) ? $params['coin_type'] : 0; if ($coinType > 0) { $query->where('a.coin_type', $coinType); } $changeType = isset($params['change_type']) ? $params['change_type'] : 0; if ($changeType > 0) { $query->where('a.change_type', $changeType); } $userId = isset($params['user_id']) ? $params['user_id'] : 0; if ($userId > 0) { $query->where('a.user_id', $userId); } $datetime = isset($params['datetime'])? $params['datetime'] : []; $dateStart = $datetime && isset($datetime[0])? $datetime[0] : ''; $dateEnd = isset($datetime[1])? $datetime[1] : ''; if($dateStart && $dateEnd && $dateEnd> $dateStart){ $query->where('a.create_time', '>', strtotime($dateStart))->where('a.create_time','<=', strtotime($dateEnd)+86399); }else if($dateStart && $dateStart == $dateEnd){ $query->where('a.create_time', '>=', strtotime($dateStart))->where('a.create_time','<=', strtotime($dateStart)+86399); }else if ($dateStart){ $query->where('a.create_time', '<=', strtotime($dateStart)+86399); } }) ->where(function ($query) use ($params) { $keyword = isset($params['keyword']) ? trim($params['keyword']) : ''; if (!empty($keyword)) { $query->where('m.nickname','like',"%{$keyword}%"); } }) ->select(['a.id', 'a.user_id', 'm.nickname','a.type','a.pay_type','a.change_type','a.coin_type','a.money', 'a.balance', 'a.status', 'a.create_time', 'a.update_time','a.remark']) ->orderBy('a.create_time', 'desc') ->paginate($pageSize); $dataList = $dataList ? $dataList->toArray() : []; if ($dataList) { $types = ['','消费支付','充值支付','赠送奖励','平台扣除','平台调整','邀请奖励','工资结算','提现打款']; foreach ($dataList['data'] as &$item) { $item['create_time'] = $item['create_time'] ? datetime($item['create_time'],'Y-m-d H:i:s') : ''; $item['remark'] = $item['remark']? $item['remark'] : (isset($types[$item['type']])? $types[$item['type']] : ''); } unset($item); } return [ 'code' => 0, 'success'=> true, 'msg' => '操作成功', 'count' => isset($dataList['total']) ? $dataList['total'] : 0, 'data' => isset($dataList['data']) ? $dataList['data'] : 0, ]; } /** * 添加或编辑 * @return array * @since 2020/11/11 * @author wesmiler */ public function edit() { $data = request()->all(); $data['update_time'] = time(); return parent::edit($data); // TODO: Change the autogenerated stub } /** * 账户后台调整 * @param $userId * @return array */ public function change($adminUid){ $params = request()->all(); $num = isset($params['num'])? $params['num'] : 0; $type = isset($params['type'])? $params['type'] : 1; $userId = isset($params['user_id'])? $params['user_id'] : 1; $changeType = isset($params['change_type'])? $params['change_type'] : 1; $typeName = $type == 1? '花灯券':($type==3? '积分' : '工资'); if($num<=0){ return message('请填写调整'.$typeName.($type==2? '金额':'数量'), false); } if(!in_array($changeType, [1,2])){ return message('操作类型错误', false); } $memberInfo = MemberModel::where(['id'=> $userId,'mark'=> 1,'status'=> 1]) ->select(['id','openid','nickname','coupon','score','salary']) ->first(); if($userId<=0 || !$memberInfo){ return message('用户账户状态不可操作', false); } if($changeType == 2){ if($type == 1 && $memberInfo->coupon < $num){ return message('用户花灯券剩余'.$memberInfo->coupon.',已超出调整数量', false); } if($type == 2 && $memberInfo->salary < $num){ return message('用户工资剩余'.$memberInfo->salary.',已超出调整数量', false); } if($type == 3 && $memberInfo->score < $num){ return message('用户积分剩余'.$memberInfo->score.',已超出调整数量', false); } } \DB::beginTransaction(); $field = $type == 1? 'coupon' : ($type==3? 'score' : 'salary'); if(!MemberModel::where(['id'=> $userId])->increment($field, ($changeType==1? $num : -$num))){ \DB::rollBack(); return message("{$typeName}账户更新失败", false); } // 明细 $mark = $type ==2? '元':'个'; $remark = isset($params['remark'])? $params['remark'] : ''; $data = [ 'user_id'=> $userId, 'source_uid'=> $adminUid, 'type'=> $type == 2? 9 : 5, 'coin_type'=> $type, 'pay_type'=> 4, 'money'=> $num, 'change_type'=> $changeType, 'balance'=> $type == 1? $memberInfo->coupon : ($type==2? $memberInfo->salary : $memberInfo->score), 'create_time'=> time(), 'remark'=> $remark? $remark : "平台调整账户,".($changeType==1?'增加':'减少')."{$num}{$mark}{$typeName}", 'status'=> 1, ]; if(!$this->model::insertGetId($data)){ \DB::rollBack(); return message("{$typeName}账户明细处理失败", false); } \DB::commit(); // 设置日志标题 ActionLogModel::setTitle("用户{$typeName}账户调整,".($changeType==1?'增加':'减少')."{$num}{$mark}{$typeName}"); ActionLogModel::record(); return message(($changeType==1?'增加':'减少')."{$num}{$mark}{$typeName}成功", true); } }