diff --git a/app/common/services/income/IncomeService.php b/app/common/services/income/IncomeService.php index 4fa4aadb..66031925 100644 --- a/app/common/services/income/IncomeService.php +++ b/app/common/services/income/IncomeService.php @@ -208,6 +208,7 @@ class IncomeService const REWARD_POOL_DIVIDEND = 191;//奖金池分红 const STORE_MANAGER = 200;// 经销商店长-店补 const CULTURAL_SPACE_CONTRIBUTION_BONUS = 201;// 文创空间 - 贡献分享分红 + const CULTURAL_SPACE_AREA_BONUS = 202;// 文创空间 - 市场津贴 /** * @param $data 会员id:member_id,分红类型:dividend_code,分红表id:dividend_table_id,金额:amount,订单号:order_sn,详情:detail @@ -679,6 +680,7 @@ class IncomeService self::REWARD_POOL_DIVIDEND => defined('REWARD_POOL_DIVIDEND_DIY_NAME') ? REWARD_POOL_DIVIDEND_DIY_NAME : "奖金池分红", self::STORE_MANAGER => '店补', self::CULTURAL_SPACE_CONTRIBUTION_BONUS => '贡献分享分红', + self::CULTURAL_SPACE_AREA_BONUS => '市场津贴', ]; if (empty($income_config_desc[$code])) { if ($func = app('ShopAsset')->getData('income')[$code]) { @@ -879,7 +881,8 @@ class IncomeService self::QUICKEN_INCOME_REWARD => 'Yunshop\QuickenIncome\models\EquityDetailModel', self::REWARD_POOL_DIVIDEND => 'Yunshop\RewardPoolDividend\common\models\DividendUpgradeRecord', self::STORE_MANAGER => 'Yunshop\TeamDividend\Common\models\StoreManagerRecordModel', - self::CULTURAL_SPACE_CONTRIBUTION_BONUS => 'Yunshop\CulturalSpace\models\ContributionBonusLog' + self::CULTURAL_SPACE_CONTRIBUTION_BONUS => 'Yunshop\CulturalSpace\models\ContributionBonusLog', + self::CULTURAL_SPACE_AREA_BONUS => 'Yunshop\CulturalSpace\models\CulturalSpaceAreaBonus', ]; if (empty($income_config_class[$code])) { if ($func = app('ShopAsset')->getData('income')[$code]) { diff --git a/plugins/cultural-space/src/PluginApplication.php b/plugins/cultural-space/src/PluginApplication.php index e5d3b918..0fcd3463 100644 --- a/plugins/cultural-space/src/PluginApplication.php +++ b/plugins/cultural-space/src/PluginApplication.php @@ -5,6 +5,8 @@ namespace Yunshop\CulturalSpace; use Yunshop\CulturalSpace\listener\OrderPaidListener; use Yunshop\CulturalSpace\models\ContributionBonusLog; +use Yunshop\CulturalSpace\models\CulturalSpaceAreaBonus; +use Yunshop\CulturalSpace\models\CulturalSpaceAreaCycle; class PluginApplication extends \app\common\services\PluginApplication{ @@ -92,8 +94,29 @@ class PluginApplication extends \app\common\services\PluginApplication{ ], ] ], - - + 'plugin_cultural_space_area_bonus' => [ + 'name' => '市场津贴', + 'permit' => 1, + 'menu' => 1, + 'icon' => '', + 'url' => 'plugin.cultural-space.admin.area_bonus.index', + 'url_params' => '', + 'item' => 'plugin_cultural_space_area_bonus', + 'parents' => ['cultural-space'], + 'child' => [ + // 权限补充 + 'plugin_cultural_space_area_bonus_index' => [ + 'name' => '市场津贴', + 'url' => 'plugin.cultural-space.admin.area_bonus.index', + 'url_params' => '', + 'permit' => 1, + 'menu' => 0, + 'icon' => '', + 'item' => 'plugin_cultural_space_area_bonus_index', + 'parents' => ['cultural-space','plugin_cultural_space_area_bonus'] + ], + ] + ], 'plugin_cultural_space_set' => [ 'name' => '基本设置', 'permit' => 1, @@ -163,18 +186,32 @@ class PluginApplication extends \app\common\services\PluginApplication{ public function cronConfig(){ \Event::listen('cron.collectJobs', function () { - // 每天0点30 执行一次贡献分享分红处理 + // 每天0点30分 执行一次贡献分享分红处理 \Cron::add('cultural-space-contribution-bonus', '30 0 * * *', function () { \Log::debug('--- 文创空间 - 贡献分享分红 - 开始 ----'); (new ContributionBonusLog())->bonusInit(); return; }); - // 每天1点30 执行一次贡献分享分红结算 + // 每天1点30分 执行一次贡献分享分红结算 \Cron::add('cultural-space-contribution-bonus-settlement', '30 1 * * *', function () { \Log::debug('--- 文创空间 - 贡献分享分红 - 结算开始 ----'); (new ContributionBonusLog())->contributionBonusSettlement(); return; }); + // 每天0点5分 执行一次市场津贴 + \Cron::add('cultural-space-area-cycle', '5 0 * * *', function () { + \Log::debug('--- 文创空间 - 市场津贴 - 开启处理 ----'); + (new CulturalSpaceAreaCycle())->bonusInit(); + return; + }); + // 每天1点30分 执行一次市场津贴结算 todo:不结算到提现 + /*\Cron::add('cultural-space-area-bonus', '30 1 * * *', function () { + \Log::debug('--- 文创空间 - 市场津贴 - 开启结算 ----'); + (new CulturalSpaceAreaBonus())->bonusSettlement(); + return; + });*/ + + }); } diff --git a/plugins/cultural-space/src/admin/AreaBonusController.php b/plugins/cultural-space/src/admin/AreaBonusController.php new file mode 100644 index 00000000..d9ab1733 --- /dev/null +++ b/plugins/cultural-space/src/admin/AreaBonusController.php @@ -0,0 +1,42 @@ +isMethod('post')){ + // 参数获取 + $search = request()->input('search'); + $tabsActive = request()->input('tabs_active'); + // 获取变更记录 + switch($tabsActive){ + case 'show_cycle':$result = CulturalSpaceAreaCycle::getList();break;// 周期信息 + case 'show_bonus':$result = CulturalSpaceAreaBonus::getList($search);break;// 分红明细 + case 'show_hold':$result = CulturalSpaceAreaBonus::getHoldList($search);break;// 用户持有 + } + + return $this->successJson('success',[ + 'current_page' => $result['current_page'], + 'data' => $result['data'], + 'last_page' => $result['last_page'], + ]); + } + + return view('Yunshop\CulturalSpace::area_bonus.index')->render(); + } + + + + + +} diff --git a/plugins/cultural-space/src/admin/IndexController.php b/plugins/cultural-space/src/admin/IndexController.php index 5a7c889d..b0892dbc 100644 --- a/plugins/cultural-space/src/admin/IndexController.php +++ b/plugins/cultural-space/src/admin/IndexController.php @@ -6,6 +6,8 @@ use app\common\facades\Setting; use app\common\models\Order; use Yunshop\CulturalSpace\models\ContributionBonusLog; use Yunshop\CulturalSpace\models\CulturalSpace; +use Yunshop\CulturalSpace\models\CulturalSpaceAreaBonus; +use Yunshop\CulturalSpace\models\CulturalSpaceAreaCycle; use Yunshop\NewPoster\models\Poster; class IndexController extends BaseController{ @@ -69,6 +71,11 @@ class IndexController extends BaseController{ // } while ($endTime <= time()); + + // 市场津贴处理 模拟 + // (new CulturalSpaceAreaCycle())->bonusInit(); + // (new CulturalSpaceAreaBonus())->bonusSettlement(); + debug(["结束,," => time()]); } diff --git a/plugins/cultural-space/src/models/CulturalSpaceAreaBonus.php b/plugins/cultural-space/src/models/CulturalSpaceAreaBonus.php new file mode 100644 index 00000000..3cd1a637 --- /dev/null +++ b/plugins/cultural-space/src/models/CulturalSpaceAreaBonus.php @@ -0,0 +1,154 @@ + 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s' + ]; + protected $fillable = [ + 'uniacid', + 'uid', + 'cycle_id', + 'area_amount', + 'area_rate', + 'get_amount', + 'status', + 'created_at', + 'updated_at', + ]; + + /** + * Common: 获取信息列表 + * Author: wu-hui + * Time: 2024/01/05 16:52 + * @param $search + * @return mixed + */ + public function getList($search){ + // 条件生成 + $where = []; + if ($search['uid'] > 0) $where[] = ['uid', '=', $search['uid']]; + if ($search['cycle_id'] > 0) $where[] = ['cycle_id', '=', $search['cycle_id']]; + if($search['status'] >= 0 && $search['status'] != '') $where[] = ['status','=',(int)$search['status']]; + // 查询model + return self::uniacid() + ->where($where) + ->with([ + 'member' => function ($query) { + $query->select(['uid', 'nickname', 'realname', 'avatar']); + }, + 'cycle' => function ($query) { + $query->select(['id', 'total_price', 'allocation_price', 'total_amount']); + } + ]) + ->orderBy('id', 'DESC') + ->paginate(10) + ->toArray(); + } + /** + * Common: 用户持有统计 + * Author: wu-hui + * Time: 2024/01/05 17:20 + * @param $search + * @return mixed + */ + public function getHoldList($search){ + // 条件生成 + $where = []; + if ($search['uid'] > 0) $where[] = ['uid', '=', $search['uid']]; + // 查询model + return self::uniacid() + ->select([ + 'uid', + DB::raw('sum(get_amount) as total_get_amount'), + ]) + ->where($where) + ->with([ + 'member' => function ($query) { + $query->select(['uid', 'nickname', 'realname', 'avatar']); + } + ]) + ->orderBy('uid', 'DESC') + ->paginate(10) + ->toArray(); + } + + + + /** + * Common: 市场津贴结算 + * Author: wu-hui + * Time: 2024/01/05 17:11 + */ + public function bonusSettlement(){ + set_time_limit(0); + DB::beginTransaction(); + try{ + // 循环平台 进行处理 + $uniAccount = UniAccount::getEnable() ?: []; + foreach ($uniAccount as $u) { + Setting::$uniqueAccountId = \YunShop::app()->uniacid = $u->uniacid; + // 获取未结算列表 + $list = self::uniacid() + ->select(['id','uid','get_amount']) + ->where('status',0) + ->get() + ->toArray(); + if($list){ + // 循环处理数据 + $incomeData = []; + foreach($list as $item){ + $incomeData[] = [ + 'uniacid' => \YunShop::app()->uniacid, + 'member_id' => $item['uid'], + 'amount' => $item['get_amount'], + 'detail' => '', + 'dividend_table_id' => $item['id'], + 'dividend_code' => IncomeService::CULTURAL_SPACE_AREA_BONUS, + 'order_sn' => '', + ]; + } + IncomeService::insertIncome($incomeData); + // 修改为已经结算 + $ids = array_column($list,'id'); + self::whereIn('id',$ids)->update([ + 'status' => 1 + ]); + } + } + DB::commit(); + }catch(\Exception $e){ + \Log::debug('--- 文创空间 - 市场津贴结算 - 错误:'.$e->getMessage()); + DB::rollBack(); + } + } + + /** + * Common: 一对一关联 用户信息 + * Author: wu-hui + * Time: 2024/01/05 16:49 + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function member(){ + return $this->hasOne(Member::class, 'uid', 'uid'); + } + /** + * Common: 一对一关联 周期信息 + * Author: wu-hui + * Time: 2024/01/05 16:51 + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function cycle(){ + return $this->hasOne(CulturalSpaceAreaCycle::class, 'id', 'cycle_id'); + } +} diff --git a/plugins/cultural-space/src/models/CulturalSpaceAreaCycle.php b/plugins/cultural-space/src/models/CulturalSpaceAreaCycle.php new file mode 100644 index 00000000..4b21f040 --- /dev/null +++ b/plugins/cultural-space/src/models/CulturalSpaceAreaCycle.php @@ -0,0 +1,177 @@ + 'datetime:Y-m-d H:i:s', + 'end_time' => 'datetime:Y-m-d H:i:s' + ]; + protected $fillable = [ + 'uniacid', + 'uid', + 'total_price', + 'allocation_price', + 'total_amount', + 'start_time', + 'end_time', + 'created_at', + ]; + private $startTime,$endTime,$set,$orderTotalMoney,$bonusTotalMoney; + /** + * Common: 获取列表 + * Author: wu-hui + * Time: 2024/01/05 16:47 + * @param int $limit + * @return array + */ + public function getList(){ + $list = self::uniacid() + ->orderBy('created_at','DESC') + ->orderBy('id','DESC') + ->paginate(10); + + return $list ? $list->toArray() : []; + } + + + /** + * Common: 分红处理开始 + * Author: wu-hui + * Time: 2024/01/05 16:22 + */ + public function bonusInit(){ + set_time_limit(0); + DB::beginTransaction(); + try{ + [$this->startTime,$this->endTime] = getTimeStamp('yesterday');// yesterday 计算前一天信息 + // 循环平台 进行处理 + $uniAccount = UniAccount::getEnable() ?: []; + foreach ($uniAccount as $u) { + Setting::$uniqueAccountId = \YunShop::app()->uniacid = $u->uniacid; + $this->set = Setting::get('plugin.cultural_space_set'); + // 判断:是否符合执行条件 + $isRun = (boolean)$this->isRun(); + // 判断:允许下一步 + if ($isRun) $this->bonusHandle(); + } + + \Log::debug('--- 文创空间 - 市场津贴 - 结束 end----'); + DB::commit(); + }catch(\Exception $e){ + \Log::debug('--- 文创空间 - 市场津贴 - 错误:'.$e->getMessage()); + DB::rollBack(); + } + } + /** + * Common: 判断是否允许继续执行 + * Author: wu-hui + * Time: 2024/01/05 16:24 + * @return bool + */ + private function isRun(){ + $time = time(); + // 判断:设置是否开启市场津贴 + if((int)$this->set['area_bonus_switch'] != 1 || (float)$this->set['area_bonus_ratio'] <= 0) { + \Log::debug("未开启市场津贴 || 总业绩比例为0或未设置",\YunShop::app()->uniacid); + return false; + } + // 判断:时间上是否允许继续执行(上一个周期结束时间存在 & 当前时间小于下一个周期开始时间 禁止继续执行) + $upCycleEndTime = self::uniacid()->max('end_time'); + $lastRunTime = strtotime(date("Y-m-d H:i:s",$upCycleEndTime)." +1 day");// 下一个周期结束时间 + if($upCycleEndTime > 0 && $time < $lastRunTime) { + \Log::debug("执行时间错误(上一个周期结束时间{$upCycleEndTime},下一个周期结束时间{$lastRunTime})",\YunShop::app()->uniacid); + return false; + } + // 判断:是否存在分红总金额 分红总金额,仅计算参与文创空间的商品的销售额 + $this->orderTotalMoney = (float)OrderGoods::uniacid() + ->leftjoin('yz_order','yz_order.id','=','yz_order_goods.order_id') + ->leftjoin('yz_goods_cultural_space','yz_goods_cultural_space.goods_id','=','yz_order_goods.goods_id') + ->where('yz_goods_cultural_space.is_open',1) + ->where('yz_order.pay_time','>=',$this->startTime) + ->where('yz_order.pay_time','<',$this->endTime) + ->where('yz_order.price','>',0) + ->where('yz_order.status','>',0) + ->sum('yz_order_goods.payment_amount'); + + $this->bonusTotalMoney = (float)sprintf("%.2f",$this->orderTotalMoney * (float)$this->set['area_bonus_ratio'] / 100); + if($this->bonusTotalMoney <= 0) { + \Log::debug("分红总金额为0",\YunShop::app()->uniacid); + return false; + } + + return true; + } + /** + * Common: 处理每个站点所有用户的分红 + * Author: wu-hui + * Time: 2024/01/05 16:24 + * @return bool|void + */ + private function bonusHandle(){ + // 获取当前站点参与分红的经销商等级id + $teamLevelIds = TeamDividendLevelModel::uniacid()->where('is_join_bonus',1)->pluck('id')->toArray(); + if(count($teamLevelIds) <= 0) return true; + // 获取参与的经销商列表 + $teamAgentIds = TeamDividendAgencyModel::uniacid() + ->where(function($query) use ($teamLevelIds){ + $query->whereIn('level',$teamLevelIds) + ->orWhereIn('cultural_level_id',$teamLevelIds); + }) + ->pluck('uid') + ->toArray(); + if(count($teamAgentIds) <= 0) return true; + // 获取全部团队的小区业绩总和 + $minAreaSumAmount = (float)TeamDividendAgencyModel::teamMinAreaSumAmount(); + if($minAreaSumAmount <= 0) return true; + // 记录周期分红信息 + $cycleId = self::insertGetId([ + 'uniacid' => \YunShop::app()->uniacid, + 'total_price' => $this->orderTotalMoney, + 'allocation_price' => $this->bonusTotalMoney, + 'total_amount' => $minAreaSumAmount, + 'start_time' => $this->startTime, + 'end_time' => $this->endTime, + 'created_at' => time(), + ]); + // 循环处理信息 + $logInsertData = [];// 明细记录 + $uniacid = \YunShop::app()->uniacid; + foreach($teamAgentIds as $currentUid){ + // 获取当前用户小区业绩 + $teamPerformance = (new CulturalSpace())->getTeamOrderAmount($currentUid); + if($teamPerformance['area_amount'] <= 0) continue; + // 添加市场津贴信息记录 这里必须进行100的偏移计算 + $radio = (float)sprintf("%.2f",$teamPerformance['area_amount'] / $minAreaSumAmount * 100);// 佣金比例 + $money = (float)sprintf("%.2f",$this->bonusTotalMoney * $radio / 100);// 实际获得佣金 + if($money > 0){ + $logInsertData[] = [ + 'uniacid' => $uniacid, + 'uid' => $currentUid, + 'cycle_id' => $cycleId, + 'area_amount' => $teamPerformance['area_amount'], + 'area_rate' => $radio, + 'get_amount' => $money, + ]; + } + } + + CulturalSpaceAreaBonus::insert($logInsertData); + } + + + + + + + +} diff --git a/plugins/cultural-space/views/area_bonus/index.blade.php b/plugins/cultural-space/views/area_bonus/index.blade.php new file mode 100644 index 00000000..19c52c11 --- /dev/null +++ b/plugins/cultural-space/views/area_bonus/index.blade.php @@ -0,0 +1,266 @@ +@extends('layouts.base') + +@section('content') +