| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- <?php
- declare (strict_types = 1);
- namespace app\api\command;
- use app\common\model\BoxMidHandleModel;
- use app\common\model\MoneyLogModel;
- use app\common\model\ScoreLogModel;
- use app\common\model\SubmeterModel;
- use app\common\model\UserModel;
- use think\console\Command;
- use think\console\Input;
- use think\console\Output;
- use think\facade\Db;
- use utils\RedisCache;
- /**
- * 空袋结算退回 by wes 每天晚上21点后运行1次
- * Class SettleBoxReturn
- * @package app\api\command
- */
- class SettleBoxReturn extends Command
- {
- protected $cacheTime = 86400; // 一天
- protected function configure()
- {
- $this->setName('settle_box_return')
- ->setDescription('the settle_box_return command');
- }
- /**
- * 处理分表
- * @param Input $input
- * @param Output $output
- * @return int
- */
- protected function execute(Input $input, Output $output)
- {
- $cacheKey = "caches:boxReturn:".date('YmdHi');
- if(RedisCache::get($cacheKey.'_lock')){
- echo json_encode(['code'=>'error','msg'=>'请不要频繁提交,正在结算中稍后再试~','date'=>date('Y-m-d H:i:s')])."\n";
- return false;
- }
- RedisCache::setnx($cacheKey.'_lock', date('Y-m-d H:i:s'), rand(5, 10));
- Db::startTrans();
- try {
- $startTime = microtime(true);
- if($result = $this->settleBoxReturn()){
- $endTime = microtime(true);
- $runTime = round(($endTime-$startTime)/1000, 3).'秒';
- $result['time'] = $runTime;
- echo json_encode($result, 256)."\n";
- Db::commit();
- }
- } catch (\Exception $e) {
- Db::rollback();
- $log = ['msg'=> $e->getMessage(),'trace'=>$e->getTrace(),'date'=>date('Y-m-d H:i:s')];
- RedisCache::set($cacheKey."_fail", $log, 5 * 3600);
- echo json_encode(['code'=>'error','msg'=>$e->getMessage(),'date'=>date('Y-m-d H:i:s')], 256)."\n";
- }
- return true;
- }
- /**
- * 结算空袋退回
- */
- public function settleBoxReturn()
- {
- // 空袋盒子
- $startTime = microtime(true);
- $date = date('Y-m-d H:i:s');
- $boxList = BoxMidHandleModel::where('box_settle_time','<=', $date)
- ->where(['goods_id'=>0,'status'=>1,'is_delete'=>2])
- ->field('id,h_sn,uid,rid,pay_type')
- ->order('uid')
- ->limit(2000)
- ->select();
- $boxList = $boxList? $boxList->toArray() : [];
- if(empty($boxList)){
- return ['code'=>500,'msg'=>'暂无数据处理','date'=>$date];
- }
- $scoreCount = $moneyCount = 0;
- $moneyLogs = $scoreLogs = $catchIds = [];
- $cacheKey = "caches:boxReturn:".date('YmdHi').'_';
- foreach ($boxList as $key=> $item){
- $boxMid = isset($item['id'])? $item['id'] : 0;
- // $rid = isset($item['rid'])? $item['rid'] : 0;
- $uid = isset($item['uid'])? $item['uid'] : 0;
- $payType = isset($item['pay_type'])? $item['pay_type'] : 0;
- $boxMoney = env('boxsetting.ONE_BOX_PRICE', 288);
- // 退回积分或余额
- $userInfo = UserModel::where('id', $uid)->field('score,money')->find();
- $userMoney = isset($userInfo['money'])? floatval($userInfo['money']) : 0;
- $userScore = isset($userInfo['score'])? intval($userInfo['score']) : 0;
- if($payType == 1){
- if(!UserModel::where('id', $uid)->inc('score', intval($boxMoney))->update()){
- RedisCache::set($cacheKey."{$uid}:{$boxMid}_error", ['msg'=>"退回用户[{$uid}]积分失败",'box'=> $item,'user'=>$userInfo,'date'=>$date], 7200);
- sr_throw("退回用户[{$uid}]积分失败");
- }
- $log = [
- 'uid'=>$uid,
- 'type'=> 2,
- 'score'=> $boxMoney,
- 'create_at'=> sr_getcurtime(time()),
- 'state'=> 1,
- 'before_score'=> $userScore,
- 'after_score'=> intval($userScore + $boxMoney),
- 'from_id'=> $boxMid,
- 'uid2'=> 0,
- 'remark'=> "空袋退回"
- ];
- $scoreLogs[] = $log;
- RedisCache::set($cacheKey."score_{$uid}:{$boxMid}_catch", ['msg'=>"退回用户[{$uid}]积分处理",'log'=>$log,'box'=> $item,'user'=>$userInfo,'date'=>$date], 7200);
- $scoreCount++;
- }
- // 退回余额
- else if($payType == 2){
- if(!UserModel::where('id', $uid)->inc('money', floatval($boxMoney))->update()){
- RedisCache::set($cacheKey."{$uid}:{$boxMid}_error", ['msg'=>"退回用户[{$uid}]余额失败",'box'=> $item,'user'=>$userInfo,'date'=>$date], 7200);
- sr_throw("退回用户[{$uid}]余额失败");
- }
- $log = [
- 'uid' => $uid,
- 'type' => 3,
- 'money' => $boxMoney,
- 'create_at' => sr_getcurtime(time()),
- 'state' => 1,
- 'before_money' => $userMoney,
- 'after_money' => floatval($userMoney + $boxMoney),
- 'from_id' => $boxMid,
- 'uid2' => 0,
- 'remark' => "空袋退回"
- ];
- $moneyLogs[] = $log;
- RedisCache::set($cacheKey."money_{$uid}:{$boxMid}_catch", ['msg'=>"退回用户[{$uid}]余额处理",'log'=>$log,'box'=> $item,'user'=>$userInfo,'date'=>$date], 7200);
- $moneyCount++;
- }
- $catchIds[] = $boxMid;
- }
- if($catchIds && !BoxMidHandleModel::whereIn('id', $catchIds)->update(['status'=> 2,'updated_time'=> $date])){
- sr_throw('处理盒子状态更新错误');
- }
- if(empty($scoreLogs) && empty($moneyLogs)){
- sr_throw('没有成功退回的盒子');
- }
- if($scoreLogs && !ScoreLogModel::insertAll(array_values($scoreLogs))){
- sr_throw('退还积分处理失败');
- }
- if($moneyLogs && !MoneyLogModel::insertAll(array_values($moneyLogs))){
- sr_throw('退还余额处理失败');
- }
- $endTime = microtime(true);
- $runTime = round(($endTime-$startTime)/1000, 3).'秒';
- RedisCache::set($cacheKey."_result", ['total'=> count($boxList),'score'=>count($scoreLogs),'money'=>count($moneyLogs),'time'=> $runTime], 3600);
- return ['code'=>200, 'msg'=>"成功退还".count($boxList)."个盒子,余额{$moneyCount}个,积分{$scoreCount}个",'time'=>$runTime,'date'=> $date];
- }
- }
|