TeamBonusForm.php 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models;
  8. use app\models\CashExt;
  9. use yii\base\Model;
  10. use app\models\Option;
  11. use app\constants\OptionSetting;
  12. use app\models\Order;
  13. use app\models\User;
  14. use app\models\SaasUser;
  15. use app\models\Cash;
  16. use app\models\ShareDetail;
  17. use app\models\TeamBonusLevel;
  18. use app\models\TeamBonusGoodsExt;
  19. use app\models\TeamBonusOrderExt;
  20. use app\models\Share;
  21. use app\models\OrderDetail;
  22. use app\utils\OrderNo;
  23. class TeamBonusForm extends Model {
  24. public function test($store_id, $user_id, $depth = 100) {
  25. $childUserIds = [];
  26. $cuids = [$user_id];
  27. $i = 0;
  28. $depthMax = 100;
  29. while ($i <= $depth) {
  30. $i++;
  31. $cuids = User::find()->where(['old_parent_id' => $cuids, 'store_id' => $store_id])
  32. // ->andWhere(['team_leader' => 0])
  33. ->select('id')->column();
  34. if (empty($cuids)) {
  35. break;
  36. }
  37. $childUserIds = array_unique(array_merge($childUserIds, $cuids));
  38. }
  39. if ($i >= $depthMax) {
  40. debug_log([__METHOD__, __LINE__, $user_id, count($childUserIds)]);
  41. \Yii::error([__METHOD__, __LINE__, $user_id, count($childUserIds), $cuids]);
  42. }
  43. return [
  44. 'depth' => $i,
  45. 'list' => array_unique($childUserIds)
  46. ];
  47. }
  48. public $store_id;
  49. public $saas_id;
  50. public $user_id;
  51. public $begin_time;
  52. public $end_time;
  53. public $mobile;
  54. public $id;
  55. public $ids;
  56. public $name;
  57. public $status;
  58. public $goods_id;
  59. public $is_delete;
  60. public $team_bonus_leader_level;
  61. public $team_bonus_leader_status;
  62. public static $_getTeamBonusChildrenIds;
  63. public static $_getTeamBonusParentIds;
  64. public static $_teamBonusSettings;
  65. public static $_teamBonusLevels;
  66. public function rules() {
  67. return [
  68. [['status', 'id'], 'integer'],
  69. [['ids', 'name'], 'string'],
  70. [[
  71. 'store_id', 'goods_id', 'saas_id', 'user_id', 'is_delete', 'mobile',
  72. 'begin_time', 'end_time',
  73. 'team_bonus_leader_level', 'team_bonus_leader_status',
  74. ], 'safe'],
  75. ];
  76. }
  77. public static function isOpen($store_id) {
  78. $conf = (new self(['store_id' => $store_id]))->teamBonusSetting()['conf'];
  79. return $conf['is_open'] ? true : false;
  80. }
  81. public static function afterCashSave($insert, $changedAttributes, $cash) {
  82. try{
  83. if($insert){
  84. return;
  85. }
  86. $store_id = $cash->store_id;
  87. if(!self::isOpen($store_id)){
  88. return;
  89. }
  90. $statusFinish = [2, 4];
  91. if ((in_array($cash->status, $statusFinish)) &&
  92. (isset($changedAttributes['status']) && ($changedAttributes['status'] != $cash->status))) {
  93. self::teamUpgrade($cash->user_id);
  94. }
  95. } catch (\Exception $ex) {
  96. \Yii::error($ex);
  97. debug_log([__FUNCTION__, __LINE__, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log');
  98. }
  99. }
  100. public static function afterUserSave($insert, $changedAttributes, $user) {
  101. try{
  102. $store_id = $user['store_id'];
  103. if(!self::isOpen($store_id)){
  104. return;
  105. }
  106. if (($user->init_parent_id > 0) &&
  107. (isset($changedAttributes['init_parent_id']) && ($changedAttributes['init_parent_id'] != $user->init_parent_id))) {
  108. self::teamUpgrade($user->init_parent_id);
  109. }
  110. if($insert){
  111. return;
  112. }
  113. if (($user->team_bonus_leader_level > 0) &&
  114. (isset($changedAttributes['team_bonus_leader_level']) && ($changedAttributes['team_bonus_leader_level'] != $user->team_bonus_leader_level))) {
  115. self::teamBonusUpgradePrice($user, $user->team_bonus_leader_level);
  116. }
  117. } catch (\Exception $ex) {
  118. \Yii::error($ex);
  119. debug_log([__FUNCTION__, __LINE__, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log');
  120. }
  121. }
  122. public static function afterShareSave($insert, $changedAttributes, $share) {
  123. try{
  124. $store_id = $share->store_id;
  125. if(!self::isOpen($store_id)){
  126. return;
  127. }
  128. if($insert){
  129. if($share->status == 1){
  130. self::teamUpgrade($share->user_id);
  131. }
  132. }else{
  133. if (($share->status == 1) &&
  134. (isset($changedAttributes['status']) && ($changedAttributes['status'] != $share->status))) {
  135. self::teamUpgrade($share->user_id);
  136. }
  137. }
  138. } catch (\Exception $ex) {
  139. \Yii::error($ex);
  140. debug_log([__FUNCTION__, __LINE__, $share->id, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log');
  141. }
  142. }
  143. //处理订单支付后逻辑
  144. public static function afterOrderComplete($order) {
  145. try{
  146. $store_id = $order->store_id;
  147. if(!self::isOpen($store_id)){
  148. debug_log([__FUNCTION__, __LINE__, $store_id, $order->id, '00000'], __CLASS__ . '.log');
  149. return;
  150. }
  151. self::teamBonusPrice($order);
  152. } catch (\Exception $ex) {
  153. \Yii::error($ex);
  154. debug_log([__FUNCTION__, __LINE__, $order->store_id, $order->id, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log');
  155. }
  156. }
  157. //处理订单过售后
  158. public static function afterOrderSales($order) {
  159. try{
  160. $store_id = $order->store_id;
  161. if(!self::isOpen($store_id)){
  162. return;
  163. }
  164. //冗余设计,如果没发放,再计算一次
  165. self::teamBonusPrice($order);
  166. self::sendTeamBonusShare($order->id);
  167. self::teamUpgrade($order->user_id);
  168. } catch (\Exception $ex) {
  169. \Yii::error($ex);
  170. debug_log([__FUNCTION__, __LINE__, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log');
  171. }
  172. }
  173. public static function getTeamBonusChildrenIds($store_id, $user_id, $depth = 25) {
  174. if(isset(self::$_getTeamBonusChildrenIds[$user_id])){
  175. return self::$_getTeamBonusChildrenIds[$user_id];
  176. }
  177. $childUserIds = [];
  178. $depthUserIds = [];
  179. $cuids = [$user_id];
  180. $i = 0;
  181. $depthMax = 15;
  182. $time1 = microtime(true);
  183. while ($i <= $depth) {
  184. $i++;
  185. $cuidArr = User::find()->where(['init_parent_id' => $cuids, 'store_id' => $store_id])
  186. ->select('id')->column();
  187. $cuids = array_diff($cuidArr, $childUserIds);
  188. if (empty($cuids)) {
  189. break;
  190. }
  191. $depthUserIds[$i] = $cuids;
  192. $childUserIds = array_unique(array_merge($childUserIds, $cuids));
  193. }
  194. $time2 = microtime(true);
  195. if ($i >= $depthMax) {
  196. debug_log([__METHOD__, __LINE__, $user_id, count($childUserIds)], __CLASS__ . '.log');
  197. \Yii::error([__METHOD__, __LINE__, $user_id, count($childUserIds), $cuids]);
  198. }
  199. return self::$_getTeamBonusChildrenIds[$user_id] = [
  200. 'usetime' => $time2 - $time1,
  201. 'depth' => $i,
  202. '$depthUserIds' => $depthUserIds,
  203. 'list' => array_unique($childUserIds)
  204. ];
  205. }
  206. /**
  207. *
  208. * @param type $user_id
  209. * @param type $onlyTeamBonusLeader
  210. * @param type $num
  211. * @param type $depth
  212. * @return type
  213. */
  214. public static function getTeamBonusParentIds($user_id, $onlyTeamBonusLeader = 0, $num = 0, $depth = 15) {
  215. if(isset(self::$_getTeamBonusParentIds[$user_id][$onlyTeamBonusLeader][$num])){
  216. return self::$_getTeamBonusParentIds[$user_id][$onlyTeamBonusLeader][$num];
  217. }
  218. $parentUserIds = [];
  219. $teamBonusLeaderUserIds = [];
  220. $puid = $user_id;
  221. $i = 0;
  222. $depthMax = 10;
  223. $time1 = microtime(true);
  224. while ($i <= $depth) {
  225. $i++;
  226. $pu = User::find()->where(['id' => $puid])
  227. ->select('id, init_parent_id, is_team_bonus_leader')->asArray()->limit(1)->one();
  228. if (empty($pu)) {
  229. break;
  230. }
  231. //排除自己
  232. if($pu['is_team_bonus_leader'] && $pu['id'] != $user_id){
  233. $teamBonusLeaderUserIds[] = $pu['id'];
  234. }
  235. $puid = $pu['init_parent_id'];
  236. if (empty($puid) || in_array($puid, $parentUserIds)) {
  237. break;
  238. }
  239. $parentUserIds[] = $puid;
  240. if($num > 0){
  241. if($onlyTeamBonusLeader){
  242. if(count($teamBonusLeaderUserIds) >= $num){
  243. break;
  244. }
  245. }else{
  246. if(count($parentUserIds) >= $num){
  247. break;
  248. }
  249. }
  250. }
  251. }
  252. //最后一个父级循环内没法查询,只能在循环外查询
  253. if($parentUserIds && $puid != $user_id){
  254. $pu = User::find()->where(['id' => $puid])
  255. ->select('id, init_parent_id, is_team_bonus_leader')->asArray()->limit(1)->one();
  256. if($pu['is_team_bonus_leader']){
  257. $teamBonusLeaderUserIds[] = $puid;
  258. }
  259. }
  260. $time2 = microtime(true);
  261. if ($i >= $depthMax) {
  262. debug_log([__METHOD__, __LINE__, $user_id, count($parentUserIds)], __CLASS__ . '.log');
  263. \Yii::error([__METHOD__, __LINE__, $user_id, count($parentUserIds), $puid]);
  264. }
  265. if($parentUserIds){
  266. $parentUserIds = array_unique($parentUserIds);
  267. }
  268. if($teamBonusLeaderUserIds){
  269. $teamBonusLeaderUserIds = array_unique($teamBonusLeaderUserIds);
  270. }
  271. return self::$_getTeamBonusParentIds[$user_id][$onlyTeamBonusLeader][$num] = [
  272. 'usetime' => $time2 - $time1,
  273. 'depth' => $i,
  274. 'parentUserIds' => $parentUserIds,
  275. 'teamBonusLeaderUserIds' => $teamBonusLeaderUserIds,
  276. 'list' => $onlyTeamBonusLeader ? $teamBonusLeaderUserIds : $parentUserIds,
  277. ];
  278. }
  279. public function teamBonusSetting() {
  280. $store_id = $this->store_id;
  281. if(isset(self::$_teamBonusSettings[$store_id])){
  282. return self::$_teamBonusSettings[$store_id];
  283. }
  284. $setting = json_decode(Option::get(OptionSetting::TEAM_BONUS_SETTING, $store_id, 'store', '{}')['value'], true);
  285. $line1 = __LINE__;
  286. $ret = [
  287. //基础设置
  288. 'is_open' => $setting['is_open'] ?? 0, //团队分红开关
  289. // 'bonus_rate_type' => $setting['bonus_rate_type'] ?? 1, //分红比例;0统一比例 1按队长等级
  290. // 'bonus_rate' => $setting['bonus_rate'] ?? 0, //统一比例
  291. 'goods_join_teambonus' => $setting['goods_join_teambonus'] ?? 1, //商品默认 1参与 0不参与
  292. 'mobile_menu_types' => $setting['mobile_menu_types'] ?? [ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT, ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL],
  293. //队长设置
  294. // 'need_apply' => $setting['need_apply'] ?? 1, //是否需要申请 1需要 0不需要
  295. // 'apply_check' => $setting['apply_check'] ?? 1, //是否需要审核 1需要 0不需要
  296. // 'apply_condition' => $setting['apply_condition'] ?? 1, //申请门槛 0无(不推荐) 1下线总人数 2下线分销商数 3累计分销佣金 4已提现佣金总额 5购买指定商品 6指定分销商等级
  297. // 'apply_child' => $setting['apply_child'] ?? 30, //下线总人数
  298. // 'apply_agent_child' => $setting['apply_agent_child'] ?? 30, //下线分销商数
  299. // 'apply_commission_total' => $setting['apply_commission_total'] ?? 100, //累计分销佣金
  300. // 'apply_withdraw_money' => $setting['apply_withdraw_money'] ?? 100, //已提现佣金总额
  301. // 'apply_commission_level' => $setting['apply_commission_level'] ?? [], //指定分销商等级 [1637, 1638]
  302. // 'apply_goodsid' => $setting['apply_goodsid'] ?? [], //购买指定商品 id是队长等级 [{id: 0, goods: "8403833,6297930"}, {id: "323", goods: "6995735"}]
  303. //申请设置
  304. // 'top_image' => $setting['top_image'] ?? '', //顶部图片
  305. // 'apply_content' => $setting['apply_content'] ?? '', //正文文本
  306. // 'apply_button_text' => $setting['apply_button_text'] ?? '立即申请', //申请按钮文案
  307. // 'need_apply_deal' => $setting['need_apply_deal'] ?? 0, //需要同意协议 1需要 0不需要
  308. // 'apply_deal_title' => $setting['apply_deal_title'] ?? '', //协议名称
  309. // 'apply_deal' => $setting['apply_deal'] ?? '', //协议内容
  310. // 'need_submit_info' => $setting['need_submit_info'] ?? 0, //需要申请人提交信息 1需要 0不需要
  311. // 'submit_info_form' => $setting['submit_info_form'] ?? [],
  312. //提现设置
  313. 'cash_min' => $setting['cash_min'] ?? 10, //最少提现
  314. 'cash_max_single_day' => $setting['cash_max_single_day'] ?? 100, //每人每日上限 0元表示不限制
  315. 'cash_max_day' => $setting['cash_max_day'] ?? 100, //平台每日上限 0元表示不限制
  316. 'cash_type' => $setting['cash_type'] ?? [0], //提现方式 0微信支付 1支付宝支付 2银行卡支付3余额4灵工
  317. 'cash_rate' => $setting['cash_rate'] ?? 10, //提现手续费佣金比例
  318. 'cash_price_type' => $setting['cash_price_type'] ?? '1',
  319. 'cash_price_amount' => $setting['cash_price_amount'] ?? 100,
  320. 'cash_price_integral' => $setting['cash_price_integral'] ?? 0,
  321. 'cash_price_balance' => $setting['cash_price_balance'] ?? 0,
  322. ];
  323. $line2 = __LINE__;
  324. $lines = file(__FILE__, FILE_IGNORE_NEW_LINES);
  325. $str = '';
  326. for ($i = $line1 + 1; $i < $line2 - 2; $i++) {
  327. $str .= trim($lines[$i]) . PHP_EOL;
  328. }
  329. $types = [
  330. ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT,
  331. ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL,
  332. ShareDetail::TYPE_TEAM_BONUS_PARENT,
  333. ShareDetail::TYPE_TEAM_BONUS_THANKS,
  334. ];
  335. return self::$_teamBonusSettings[$store_id] = [
  336. 'str' => $str,
  337. 'conf' => $ret,
  338. 'ShareDetailTypes' => ShareDetail::typeName($types),
  339. ];
  340. }
  341. public function teamBonusSettingSave($conf = []) {
  342. // $total_profit = 0;
  343. // $cash_price_type = explode(',', $conf['cash_price_type']);
  344. // if (in_array(CashExt::CASH_PRICE_TYPE_AMOUNT, $cash_price_type)) {
  345. // $total_profit = bcadd($total_profit, $conf['cash_price_amount'], 2);
  346. // }
  347. // if (in_array(CashExt::CASH_PRICE_TYPE_INTEGRAL, $cash_price_type)) {
  348. // $total_profit = bcadd($total_profit, $conf['cash_price_integral'], 2);
  349. // }
  350. // if (in_array(CashExt::CASH_PRICE_TYPE_BALANCE, $cash_price_type)) {
  351. // $total_profit = bcadd($total_profit, $conf['cash_price_balance'], 2);
  352. // }
  353. // if ($total_profit != 100) {
  354. // return [
  355. // 'code' => 1,
  356. // 'msg' => '佣金/积分/余额比例设置错误'
  357. // ];
  358. // }
  359. Option::set(OptionSetting::TEAM_BONUS_SETTING, json_encode($conf), $this->store_id, 'store');
  360. }
  361. public function teamBonusLevelList() {
  362. $store_id = $this->store_id;
  363. if(isset(self::$_teamBonusLevels[$store_id])){
  364. return self::$_teamBonusLevels[$store_id];
  365. }
  366. $query = TeamBonusLevel::find()->where(['store_id' => $store_id]);
  367. if (!is_null($this->status) && $this->status > -1) {
  368. $query->andWhere(['status' => $this->status]);
  369. }
  370. $query->orderBy('level ASC');
  371. $list = $query->asArray()->all();
  372. foreach($list as &$item){
  373. $item['conditionText'] = self::levelConditionText($item);
  374. }
  375. return self::$_teamBonusLevels[$store_id] = [
  376. 'code' => 0,
  377. 'msg' => 'success',
  378. 'data' => $list,
  379. ];
  380. }
  381. /**
  382. * 队长等级
  383. */
  384. public function teamBonusLevelInfo($id) {
  385. // $store_id = $this->store_id;
  386. $level = TeamBonusLevel::findOne($id);
  387. return [
  388. 'code' => 0,
  389. 'data' => $level,
  390. 'conditionText' => self::levelConditionText($level),
  391. ];
  392. }
  393. public static function levelConditionText($level){
  394. $conditionText = [];
  395. $condition_type = $level['condition_type'];
  396. $glue = $condition_type ? ' 并且 ' : ' 或者 ';
  397. $condition = json_decode($level['condition'], true);
  398. //团队交易
  399. if(isset($condition['teamOrderPrice'])){
  400. if(isset($condition['teamOrderPrice']['count'])){
  401. $conditionText[] = '团队订单数量大于' . $condition['teamOrderPrice']['count'];
  402. }
  403. if(isset($condition['teamOrderPrice']['price'])){
  404. $conditionText[] = '团队订单金额大于' . $condition['teamOrderPrice']['price'];
  405. }
  406. }
  407. //自购交易
  408. if(isset($condition['teamSelfOrderPrice'])){
  409. if(isset($condition['teamSelfOrderPrice']['count'])){
  410. $conditionText[] = '自购订单数量大于' . $condition['teamSelfOrderPrice']['count'];
  411. }
  412. if(isset($condition['teamSelfOrderPrice']['price'])){
  413. $conditionText[] = '自购订单金额大于' . $condition['teamSelfOrderPrice']['price'];
  414. }
  415. }
  416. //团队人数
  417. if(isset($condition['teamChildren'])){
  418. if(isset($condition['teamChildren']['countAll'])){
  419. $conditionText[] = '团队总人数大于' . $condition['teamChildren']['countAll'];
  420. }
  421. if(isset($condition['teamChildren']['countShare'])){
  422. $conditionText[] = '团队分销商人数大于' . $condition['teamChildren']['countShare'];
  423. }
  424. }
  425. //提现
  426. if(isset($condition['teamCash'])){
  427. if(isset($condition['teamCash']['cash_price'])){
  428. $conditionText[] = '已提现分红金额大于' . $condition['teamCash']['cash_price'];
  429. }
  430. }
  431. //购买指定商品
  432. if(isset($condition['teamHasGoods'])){
  433. // if(isset($condition['teamHasGoods']['goods_ids'])){
  434. // $conditionText[] = '购买指定商品' . implode(',', $condition['teamHasGoods']['goods_ids']);
  435. // }
  436. }
  437. return implode($glue, $conditionText);
  438. }
  439. public function teamBonusLevelSelectList($indexBy = 1) {
  440. $query = TeamBonusLevel::find()->where(['store_id' => $this->store_id])
  441. ->select('id,name,level,status,range_rate');
  442. if ($indexBy) {
  443. $query->indexBy('id');
  444. }
  445. $list = $query->orderBy('level ASC')->asArray()->all();
  446. foreach ($list as &$item) {
  447. if (!$item['status']) {
  448. $item['name'] .= '(已禁用)';
  449. }
  450. }
  451. return [
  452. 'code' => 0,
  453. 'msg' => 'success',
  454. 'data' => $list,
  455. ];
  456. }
  457. /**
  458. * 团队分红-升级触发分红
  459. * @param \app\models\User $child_user
  460. * @return type
  461. */
  462. public static function teamBonusUpgradePrice($child_user, $level_id) {
  463. //感恩奖
  464. $store_id = $child_user->store_id;
  465. $child_user_id = $child_user->id;
  466. $self = new self(['store_id' => $store_id]);
  467. $level = TeamBonusLevel::findOne(['id' => $level_id, 'status' => 1, 'is_delete' => 0]);
  468. if ($level && $level->price_thanks > 0) {
  469. $getTeamBonusParentIds = $self->getTeamBonusParentIds($child_user_id, 1, 1)['list'];
  470. if (count($getTeamBonusParentIds) > 0) {
  471. $parent_id = $getTeamBonusParentIds[0];
  472. $detail = ShareDetail::findOne(['is_delete' => 0, 'type_id' => $child_user_id, 'type' => ShareDetail::TYPE_TEAM_BONUS_THANKS, 'user_id' => $parent_id, 'type_id_ext' => $level['id']]);
  473. if (!$detail) {
  474. $detail = new ShareDetail();
  475. $detail->store_id = $store_id;
  476. $detail->type_id = $child_user_id;
  477. $detail->type_id_ext = $level['id'];
  478. $detail->type = ShareDetail::TYPE_TEAM_BONUS_THANKS;
  479. $detail->user_id = $parent_id;
  480. $detail->desc = '下级:' . $child_user->nickname . ';等级:' . $level->name . '(' . $level['id'] . ')' . ';';
  481. $detail->money = $level->price_thanks;
  482. $detail->is_send = 0;
  483. if (!$detail->save()) {
  484. \Yii::error(['---------------- 团队分红-感恩奖计算入库失败 -------------------', $detail->errors, $child_user, $level_id]);
  485. debug_log(['---------------- 团队分红-感恩奖计算入库失败 -------------------', $detail->errors, $child_user, $level_id], __CLASS__ . '.log');
  486. return;
  487. }
  488. self::_sendTeamBonusShareItem($detail);
  489. }
  490. }
  491. }
  492. }
  493. /**
  494. * 团队分红-订单触发分红
  495. * @param \app\models\Order $order |
  496. * @return type
  497. */
  498. public static function teamBonusPrice($order) {
  499. $t = \Yii::$app->db->beginTransaction();
  500. try{
  501. \Yii::warning('---------------- 团队分红-计算开始 -------------------' . $order->id);
  502. $order_id = $order->id;
  503. $store_id = $order->store_id;
  504. $self = new self(['store_id' => $store_id]);
  505. $levels = array_column($self->teamBonusLevelList()['data'], null, 'id');
  506. $user_id = $order->user_id;
  507. $base_price = 0;
  508. $goodsCanPrice = [];
  509. $ods = $order->detail;
  510. $conf = (new self(['store_id' => $store_id]))->teamBonusSetting()['conf'];
  511. //有独立分红商品
  512. $odsProfit = [];
  513. foreach($ods as $od){
  514. //有独立分红商品
  515. $goodsExt = TeamBonusGoodsExt::findOne(['store_id' => $store_id, 'goods_id' => $od['goods_id']]);
  516. if($goodsExt){
  517. if($goodsExt->status == 1 || ($goodsExt->status == 0 && $conf['goods_join_teambonus'] == 1)){
  518. $goodsCanPrice[$od['id']] = 1;
  519. }
  520. }else{
  521. if($conf['goods_join_teambonus'] == 1){
  522. $goodsCanPrice[$od['id']] = 1;
  523. }
  524. }
  525. if($goodsCanPrice[$od['id']]){
  526. $base_price += $od['total_price'];
  527. if($goodsExt->is_profit_self){
  528. $odsProfit[$od['id']] = array_column(json_decode($goodsExt->profit_rule, true), null, 'id');
  529. }
  530. }
  531. }
  532. if($base_price < 0.02){
  533. throw new \Exception($order_id . '分红基数小于0.02,或商品不参与分红');
  534. }
  535. $getTeamBonusParentIds = $self->getTeamBonusParentIds($user_id, 1)['list'];
  536. $getTeamBonusParentIds && self::_teamBonusOrderExtSave($order, $getTeamBonusParentIds);
  537. // 已分销比例
  538. $share_num = [];
  539. $level_id = 0;
  540. //上个用户总佣金
  541. $priceAllLast = 0;
  542. foreach($getTeamBonusParentIds as $parent_id) {
  543. $teamParent = User::findOne($parent_id);
  544. if ($teamParent->is_delete) {
  545. continue;
  546. }
  547. $level = $levels[$teamParent->team_bonus_leader_level];
  548. if(!$level || !$level['status'] || $level['is_delete']){
  549. continue;
  550. }
  551. if ($level) {
  552. // //上个用户总佣金
  553. // $priceAllLast = 0;
  554. //此用户总佣金
  555. $priceAll = 0;
  556. //是否符合平级奖(一个用户不能同时获得级差奖和平级奖)
  557. $hasPriceSameLevel = 0;
  558. //平级奖
  559. $priceSameLevel = 0;
  560. if ($level_id == $level['id']) {
  561. $hasPriceSameLevel = 1;
  562. $range_rate = $level['equal_rate'];
  563. $equal_price = round($base_price * $range_rate / 100, 2);
  564. if ($equal_price >= 0.01) {
  565. $priceSameLevel = $equal_price;
  566. $detail = ShareDetail::findOne(['type_id' => $order_id, 'type' => ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL, 'user_id' => $parent_id]);
  567. if (!$detail) {
  568. $detail = new ShareDetail();
  569. $detail->store_id = $order->store_id;
  570. $detail->type_id = $order_id;
  571. $detail->type = ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL;
  572. $detail->user_id = $parent_id;
  573. $detail->desc = '订单号:' . $order->order_no . ' | ' . $range_rate . '%';
  574. }
  575. $detail->money = $equal_price;
  576. $detail->is_send = 0;
  577. if (!$detail->save()) {
  578. $t->rollBack();
  579. \Yii::error(['---------------- 团队分红-平级奖计算入库失败 -------------------', $order_id, $parent_id, $detail->errors]);
  580. throw new \Exception(array_shift($detail->getFirstErrors()));
  581. }
  582. }
  583. $level_id = 0;
  584. }
  585. //级差奖
  586. $priceLevel = 0;
  587. if (!$hasPriceSameLevel) {
  588. $price = 0;
  589. $range_rates = [];
  590. foreach($ods as $od){
  591. $odPrice = $od['total_price'];
  592. $odId = $od['id'];
  593. $range_rate = $level['range_rate'] - $share_num[$odId];
  594. //有独立分红商品
  595. if($odsProfit[$odId]){
  596. $range_rate = (isset($odsProfit[$odId][$level['id']]) ? $odsProfit[$odId][$level['id']]['range_rate'] : 0) - $share_num[$odId];
  597. }
  598. $range_rates[] = $range_rate;
  599. if($range_rate <= 0){
  600. continue;
  601. }
  602. if(!$goodsCanPrice[$od['id']]){
  603. continue;
  604. }
  605. $share_num[$odId] += $range_rate;
  606. $price += round($odPrice * $range_rate / 100, 2);
  607. }
  608. if ($price >= 0.01) {
  609. $priceLevel = $price;
  610. $detail = ShareDetail::findOne(['type_id' => $order_id, 'type' => ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT, 'user_id' => $parent_id]);
  611. if (!$detail) {
  612. $detail = new ShareDetail();
  613. $detail->store_id = $order->store_id;
  614. $detail->type_id = $order_id;
  615. $detail->type = ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT;
  616. $detail->user_id = $parent_id;
  617. $detail->desc = '订单号:' . $order->order_no . ' | ' . implode('+', $range_rates) . '%';
  618. }
  619. $level_id = $level['id'];
  620. $detail->money = $price;
  621. $detail->is_send = 0;
  622. if (!$detail->save()) {
  623. $t->rollBack();
  624. \Yii::error(['---------------- 团队分红-级差分红计算入库失败 -------------------', $detail->errors]);
  625. throw new \Exception(array_shift($detail->getFirstErrors()));
  626. }
  627. }
  628. }
  629. //育人奖
  630. $priceParent = 0;
  631. if ($priceAllLast > 0 && $level['range_rate_parent'] > 0) {
  632. $range_rate = $level['range_rate_parent'];
  633. $price = round($priceAllLast * $range_rate / 100, 2);
  634. if ($price >= 0.1) {
  635. $priceParent = $price;
  636. $detail = ShareDetail::findOne(['type_id' => $order_id, 'type' => ShareDetail::TYPE_TEAM_BONUS_PARENT, 'user_id' => $parent_id]);
  637. if (!$detail) {
  638. $detail = new ShareDetail();
  639. $detail->store_id = $order->store_id;
  640. $detail->type_id = $order_id;
  641. $detail->type = ShareDetail::TYPE_TEAM_BONUS_PARENT;
  642. $detail->user_id = $parent_id;
  643. $detail->desc = '订单号:' . $order->order_no . ' | ' . $range_rate . '%';
  644. }
  645. $detail->money = $price;
  646. $detail->is_send = 0;
  647. if (!$detail->save()) {
  648. $t->rollBack();
  649. \Yii::error(['---------------- 团队分红-育人奖计算入库失败 -------------------', $detail->errors]);
  650. throw new \Exception(array_shift($detail->getFirstErrors()));
  651. }
  652. }
  653. }
  654. $priceAll += bcadd($priceSameLevel, $priceLevel + $priceParent, 2);
  655. $priceAllLast = $priceAll;
  656. }
  657. }
  658. $t->commit();
  659. \Yii::warning('---------------- 团队分红-计算结束 -------------------' . $order->id);
  660. } catch (\Exception $e) {
  661. $t->rollBack();
  662. \Yii::error($e);
  663. debug_log([__FUNCTION__, $order->store_id, $order->id, $e->getMessage()], __CLASS__ . '.log');
  664. }
  665. return;
  666. }
  667. /**
  668. * 发放团队分红 - 订单触发分红
  669. */
  670. public static function sendTeamBonusShare($order_id) {
  671. try{
  672. $types = [
  673. ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT,
  674. ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL,
  675. ShareDetail::TYPE_TEAM_BONUS_PARENT,
  676. ];
  677. $list = ShareDetail::find()->where(['type_id' => $order_id, 'type' => $types, 'is_send' => 0, 'is_delete' => 0])->all();
  678. if ($list) {
  679. foreach ($list as $share_detail) {
  680. $sendTeamBonusShareItem = self::_sendTeamBonusShareItem($share_detail);
  681. if ($sendTeamBonusShareItem['code']) {
  682. debug_log([__METHOD__, $order_id, $share_detail->id, $sendTeamBonusShareItem], __CLASS__ . '.log');
  683. }
  684. }
  685. }
  686. } catch (\Exception $e) {
  687. \Yii::error($e);
  688. debug_log([__METHOD__, $order_id, $e->getMessage()], __CLASS__ . '.log');
  689. }
  690. }
  691. /**
  692. * 发放分红到账户佣金
  693. */
  694. public static function _sendTeamBonusShareItem($share_detail) {
  695. $t = \Yii::$app->db->beginTransaction();
  696. try{
  697. $user = User::findOne($share_detail->user_id);
  698. $user->total_price += $share_detail->money;
  699. $user->price += $share_detail->money;
  700. if (!$user->save()) {
  701. $t->rollBack();
  702. throw new \Exception(array_shift($user->getFirstErrors()));
  703. }
  704. $share_detail->is_send = 1;
  705. $share_detail->send_time = time();
  706. if (!$share_detail->save()) {
  707. $t->rollBack();
  708. throw new \Exception(array_shift($share_detail->getFirstErrors()));
  709. }
  710. } catch (\Exception $e) {
  711. $t->rollBack();
  712. \Yii::error($e);
  713. debug_log([__METHOD__, $share_detail->user_id, $share_detail->type_id, $share_detail->id, $e->getMessage()], __CLASS__ . '.log');
  714. return [
  715. 'code' => 1,
  716. 'msg' => $e->getMessage()
  717. ];
  718. }
  719. $t->commit();
  720. return [
  721. 'code' => 0,
  722. ];
  723. }
  724. /**
  725. * 保存订单扩展信息
  726. */
  727. public static function _teamBonusOrderExtSave($order, $parent_ids = []) {
  728. $store_id = $order->store_id;
  729. $model = TeamBonusOrderExt::findOne(['store_id' => $store_id, 'order_id' => $order->id]);
  730. if($model){
  731. throw new \Exception('分红计算失败,订单已经存在分红' . $order->id);
  732. }
  733. $model = new TeamBonusOrderExt();
  734. $model->store_id = $store_id;
  735. $model->order_id = $order->id;
  736. $model->parent_ids = implode(',', $parent_ids);
  737. $save = $model->save();
  738. return $save;
  739. }
  740. /**
  741. * 团队内成员历史订单总数
  742. * @param type $user
  743. * @return type
  744. */
  745. public static function teamOrderPriceHistory($user) {
  746. $store_id = $user['store_id'];
  747. $user_id = $user['id'];
  748. $user_ids = self::getTeamBonusChildrenIds($store_id, $user_id)['list'];
  749. $query = Order::find()->where(['store_id' => $store_id])
  750. ->andWhere(['is_sale' => 1])
  751. ->andWhere(['user_id' => $user_ids]);
  752. $price = (float)(clone $query)->sum('pay_price');
  753. $count = (int)(clone $query)->count();
  754. return [
  755. 'price' => $price,
  756. 'count' => $count,
  757. ];
  758. }
  759. /**
  760. * 团队内订单数据
  761. * @param type $user
  762. * @param type $store_id
  763. * @param type $getList
  764. * @param type $queryParams
  765. * @param type $oneUserId 单个下级贡献数据
  766. * @return type
  767. */
  768. public static function teamOrderPrice($user, $store_id = null, $getList = 0, $queryParams = [], $oneUserId = null) {
  769. $types = [
  770. ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT,
  771. ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL,
  772. ShareDetail::TYPE_TEAM_BONUS_PARENT,
  773. ];
  774. if($store_id === null){
  775. $store_id = $user['store_id'];
  776. }
  777. $queryTb = TeamBonusOrderExt::find()->where(['store_id' => $store_id])->select('order_id');
  778. if($user){
  779. $queryTb->andWhere('FIND_IN_SET('. $user['id'] .', parent_ids)');
  780. }
  781. $query = Order::find()->where(['store_id' => $store_id])
  782. ->andWhere(['id' => $queryTb]);
  783. if($oneUserId){
  784. $query->andWhere(['user_id' => $oneUserId]);
  785. }
  786. $price = (float)(clone $query)->andWhere(['is_sale' => 1])->sum('pay_price');
  787. $count = (int)(clone $query)->andWhere(['is_sale' => 1])->count();
  788. if($getList){
  789. if(isset($queryParams['trade_status']) && $queryParams['trade_status'] > -1){
  790. $query->andWhere(['trade_status' => $queryParams['trade_status']]);
  791. }
  792. if($queryParams['order_no']){
  793. $query->andWhere(['order_no' => trim($queryParams['order_no'])]);
  794. }
  795. if($queryParams['name']){
  796. $query->andWhere(['like', 'name', trim($queryParams['name'])]);
  797. }
  798. if($queryParams['goods_name']){
  799. $query->andWhere(['id' => OrderDetail::find()->select('order_id')->where(['like', 'goods_name', trim($queryParams['goods_name'])])]);
  800. }
  801. if (!empty($queryParams['begin_time'])) {
  802. $query->andWhere(['>=', 'created_at', strtotime($queryParams['begin_time'])]);
  803. }
  804. if (!empty($queryParams['end_time'])) {
  805. $query->andWhere(['<=', 'created_at', strtotime($queryParams['end_time'])]);
  806. }
  807. if(isset($queryParams['price_is_send']) && $queryParams['price_is_send'] > -1){
  808. $query->andWhere(['id' => ShareDetail::find()->select('type_id')->groupBy('type_id')->where(['is_delete' => 0, 'is_send' => $queryParams['price_is_send']])]);
  809. }
  810. if($queryParams['team_leader_name']){
  811. $query->andWhere(['id' => ShareDetail::find()->select('type_id')->groupBy('type_id')->where(['is_delete' => 0, 'user_id' => User::find()->alias('u')->leftJoin(['su' => SaasUser::tableName()], 'u.binding=su.mobile')->select('u.id')->where(['like', 'su.name', trim($queryParams['team_leader_name'])])])]);
  812. }
  813. $query->orderBy('id DESC');
  814. $list = pagination_make($query);
  815. foreach($list['list'] as &$item){
  816. $item['od'] = OrderDetail::findAll(['order_id' => $item['id']]);
  817. $querySd = ShareDetail::find()->where(['store_id' => $store_id, 'is_delete' => 0, 'type' => $types])
  818. ->andWhere(['type_id' => $item['id']]);
  819. $item['sd'] = $querySd->asArray()->all();
  820. $user = User::findOne($item['user_id']);
  821. $saas_user = SaasUser::findOne(['mobile' => $user['binding']]);
  822. $item['saas_user'] = $saas_user;
  823. foreach($item['sd'] as &$sditem){
  824. $user = User::findOne($sditem['user_id']);
  825. $saas_user = SaasUser::findOne(['mobile' => $user['binding']]);
  826. $sditem['saas_user'] = $saas_user;
  827. $sditem['price_type'] = ShareDetail::typeName($sditem['type']);
  828. }
  829. }
  830. }
  831. return [
  832. '$query' => $query->createCommand()->getRawSql(),
  833. 'price' => $price,
  834. 'count' => $count,
  835. 'list' => $list,
  836. ];
  837. }
  838. /**
  839. * 自购
  840. * @param type $user
  841. * @return type
  842. */
  843. public static function teamSelfOrderPrice($user) {
  844. $store_id = $user['store_id'];
  845. $user_id = $user['id'];
  846. $query = Order::find()->where(['store_id' => $store_id, 'user_id' => $user_id])
  847. ->andWhere(['is_sale' => 1]);
  848. $price = (float)(clone $query)->sum('pay_price');
  849. $count = (int)(clone $query)->count();
  850. return [
  851. 'price' => $price,
  852. 'count' => $count,
  853. ];
  854. }
  855. /**
  856. * 下级人员
  857. * @param type $user
  858. * @return type
  859. */
  860. public static function teamChildren($user) {
  861. $store_id = $user['store_id'];
  862. $user_id = $user['id'];
  863. $user_ids = self::getTeamBonusChildrenIds($store_id, $user_id)['list'];
  864. $countShare = (int)Share::find()->where(['store_id' => $store_id, 'status' => 1, 'is_delete' => 0, 'user_id' => $user_ids])->count();
  865. return [
  866. 'countShare' => $countShare,
  867. 'countAll' => count($user_ids),
  868. ];
  869. }
  870. public static function teamCash($user) {
  871. $store_id = $user['store_id'];
  872. $user_id = $user['id'];
  873. $cash_price = (float)Cash::find()->where(['store_id' => $store_id, 'user_id' => $user_id])->andWhere(['status' => [2, 4, 5]])->sum('price');
  874. return [
  875. 'total_price' => $user['total_price'],
  876. 'price' => $user['price'],
  877. 'cash_price' => $cash_price,
  878. ];
  879. }
  880. /**
  881. * 佣金信息
  882. * @param type $user
  883. * @return type
  884. */
  885. public static function teamSharePrice($user) {
  886. $store_id = $user['store_id'];
  887. $user_id = $user['id'];
  888. $price = ShareDetail::find()->where(['store_id' => $store_id, 'is_delete' => 0, 'user_id' => $user_id, 'is_send' => 1])
  889. ->select('type, SUM(money) sum_money')
  890. ->groupBy('type')->asArray()->all();
  891. return [
  892. 'price' => $price,
  893. ];
  894. }
  895. /**
  896. * 队内成员贡献佣金信息
  897. * @param type $user
  898. * @return type
  899. */
  900. public static function teamChildrenSharePrice($user, $oneUserId = null) {
  901. $store_id = $user['store_id'];
  902. $queryTb = TeamBonusOrderExt::find()
  903. ->where(['store_id' => $store_id])
  904. ->andWhere('FIND_IN_SET('. $user->id .', parent_ids)')
  905. ->andWhere(['order_id' => Order::find()->select('id')->where(['user_id' => $oneUserId])])
  906. ->select('order_id');
  907. $price = ShareDetail::find()
  908. ->where(['store_id' => $store_id, 'is_delete' => 0, 'user_id' => $user->id, 'is_send' => 1])
  909. ->andWhere(['or', ['type_id' => $queryTb], ['type_id' => $oneUserId]])
  910. ->select('type, SUM(money) sum_money')
  911. ->groupBy('type')->asArray()->all();
  912. return [
  913. 'price' => $price,
  914. ];
  915. }
  916. public static function teamHasGoods($user, $goods_ids = []) {
  917. $store_id = $user['store_id'];
  918. $user_id = $user['id'];
  919. $orderOne = Order::find()->alias('o')
  920. ->leftJoin(['od' => OrderDetail::tableName()], 'o.id = od.order_id')
  921. ->where(['o.store_id' => $store_id, 'o.user_id' => $user_id, 'o.is_sale' => 1])
  922. ->andWhere(['od.goods_id' => $goods_ids])
  923. ->select('o.id')->limit(1)->scalar();
  924. return $orderOne ? true : false;
  925. }
  926. /**
  927. * 升级
  928. * @param type $user
  929. */
  930. public static function teamUpgrade($user) {
  931. if(!isset($user['id'])){
  932. $user = User::findOne($user);
  933. }
  934. $store_id = $user['store_id'];
  935. $user_id = $user['id'];
  936. $self = new self(['store_id' => $store_id]);
  937. $teamUserIds = array_merge([$user_id], $self->getTeamBonusParentIds($user_id, 1)['list']);
  938. $levels = $self->teamBonusLevelList()['data'];
  939. $levelsIndex = array_column($levels, null, 'id');
  940. foreach($teamUserIds as $uid){
  941. $userItem = User::findOne($uid);
  942. if($userItem->is_team_bonus_leader){
  943. if(!$userItem->team_bonus_leader_status){
  944. continue;
  945. }
  946. if($userItem->team_bonus_leader_level_lock){
  947. continue;
  948. }
  949. }else{
  950. $share = Share::find()->where(['store_id' => $store_id, 'status' => 1, 'is_delete' => 0, 'user_id' => $uid])->one();
  951. if(!$share){
  952. continue;
  953. }
  954. }
  955. foreach($levels as $level){
  956. if($userItem->team_bonus_leader_level && $levelsIndex[$userItem->team_bonus_leader_level] && $levelsIndex[$userItem->team_bonus_leader_level]['level'] >= $level['level']){
  957. continue;
  958. }
  959. if(!$level['status']){
  960. continue;
  961. }
  962. $canUpgrade = self::canUpgrade($level, $userItem);
  963. if(!$canUpgrade){
  964. break;
  965. }else{
  966. //升级
  967. if(!$userItem->is_team_bonus_leader){
  968. $userItem->is_team_bonus_leader = 1;
  969. $userItem->team_bonus_leader_status = 1;
  970. $userItem->team_bonus_leader_time = time();
  971. }
  972. $userItem->team_bonus_leader_level = $level['id'];
  973. $userSave = $userItem->save();
  974. if(!$userSave){
  975. debug_log([__METHOD__, $userItem->team_bonus_leader_time, $userItem->team_bonus_leader_level, $userItem->id, $userItem->getFirstErrors()], __CLASS__ . '.log');
  976. }
  977. }
  978. }
  979. }
  980. }
  981. /**
  982. * 检测是否符合升级条件
  983. */
  984. public static function canUpgrade($level, $userItem, &$userData = []) {
  985. $canUpgrade = 1;
  986. $condition_type = $level['condition_type'];
  987. $condition_type_one = $condition_type == 0;
  988. //升级逻辑判断
  989. $condition = json_decode($level['condition'], true);
  990. //团队交易
  991. if(isset($condition['teamOrderPrice'])){
  992. $teamOrderPrice = self::teamOrderPrice($userItem);
  993. $userData['teamOrderPrice']['count'] = $teamOrderPrice['count'];
  994. $userData['teamOrderPrice']['price'] = $teamOrderPrice['price'];
  995. if(isset($condition['teamOrderPrice']['count'])){
  996. if($condition['teamOrderPrice']['count'] > $teamOrderPrice['count']){
  997. $canUpgrade = 0;
  998. if(!$condition_type_one){
  999. // return $canUpgrade;
  1000. }
  1001. }else{
  1002. if($condition_type_one){
  1003. return true;
  1004. }
  1005. }
  1006. }
  1007. if(isset($condition['teamOrderPrice']['price'])){
  1008. if($condition['teamOrderPrice']['price'] > $teamOrderPrice['price']){
  1009. $canUpgrade = 0;
  1010. if(!$condition_type_one){
  1011. // return $canUpgrade;
  1012. }
  1013. }else{
  1014. if($condition_type_one){
  1015. return true;
  1016. }
  1017. }
  1018. }
  1019. }
  1020. //自购交易
  1021. if(isset($condition['teamSelfOrderPrice'])){
  1022. $teamSelfOrderPrice = self::teamSelfOrderPrice($userItem);
  1023. $userData['teamSelfOrderPrice']['count'] = $teamSelfOrderPrice['count'];
  1024. $userData['teamSelfOrderPrice']['price'] = $teamSelfOrderPrice['price'];
  1025. if(isset($condition['teamSelfOrderPrice']['count'])){
  1026. if($condition['teamSelfOrderPrice']['count'] > $teamSelfOrderPrice['count']){
  1027. $canUpgrade = 0;
  1028. if(!$condition_type_one){
  1029. // return $canUpgrade;
  1030. }
  1031. }else{
  1032. if($condition_type_one){
  1033. return true;
  1034. }
  1035. }
  1036. }
  1037. if(isset($condition['teamSelfOrderPrice']['price'])){
  1038. if($condition['teamSelfOrderPrice']['price'] > $teamSelfOrderPrice['price']){
  1039. $canUpgrade = 0;
  1040. if(!$condition_type_one){
  1041. // return $canUpgrade;
  1042. }
  1043. }else{
  1044. if($condition_type_one){
  1045. return true;
  1046. }
  1047. }
  1048. }
  1049. }
  1050. //团队人数
  1051. if(isset($condition['teamChildren'])){
  1052. $teamChildren = self::teamChildren($userItem);
  1053. $userData['teamChildren']['countAll'] = $teamChildren['countAll'];
  1054. $userData['teamChildren']['countShare'] = $teamChildren['countShare'];
  1055. if(isset($condition['teamChildren']['countAll'])){
  1056. if($condition['teamChildren']['countAll'] > $teamChildren['countAll']){
  1057. $canUpgrade = 0;
  1058. if(!$condition_type_one){
  1059. // return $canUpgrade;
  1060. }
  1061. }else{
  1062. if($condition_type_one){
  1063. return true;
  1064. }
  1065. }
  1066. }
  1067. if(isset($condition['teamChildren']['countShare'])){
  1068. if($condition['teamChildren']['countShare'] > $teamChildren['countShare']){
  1069. $canUpgrade = 0;
  1070. if(!$condition_type_one){
  1071. // return $canUpgrade;
  1072. }
  1073. }else{
  1074. if($condition_type_one){
  1075. return true;
  1076. }
  1077. }
  1078. }
  1079. }
  1080. //提现
  1081. if(isset($condition['teamCash'])){
  1082. $teamCash = self::teamCash($userItem);
  1083. $userData['teamCash']['cash_price'] = $teamCash['cash_price'];
  1084. if(isset($condition['teamCash']['cash_price'])){
  1085. if($condition['teamCash']['cash_price'] > $teamCash['cash_price']){
  1086. $canUpgrade = 0;
  1087. if(!$condition_type_one){
  1088. // return $canUpgrade;
  1089. }
  1090. }else{
  1091. if($condition_type_one){
  1092. return true;
  1093. }
  1094. }
  1095. }
  1096. }
  1097. //购买指定商品
  1098. if(isset($condition['teamHasGoods'])){
  1099. if(isset($condition['teamHasGoods']['goods_ids'])){
  1100. $teamHasGoods = self::teamHasGoods($userItem, $condition['teamHasGoods']['goods_ids']);
  1101. $userData['teamHasGoods']['teamHasGoods'] = $teamHasGoods;
  1102. if(!$teamHasGoods){
  1103. $canUpgrade = 0;
  1104. if(!$condition_type_one){
  1105. // return $canUpgrade;
  1106. }
  1107. }else{
  1108. if($condition_type_one){
  1109. return true;
  1110. }
  1111. }
  1112. }
  1113. }
  1114. return $canUpgrade;
  1115. }
  1116. /**
  1117. * 队长列表
  1118. */
  1119. public function teamLeaderList() {
  1120. try {
  1121. $is_delete = 0;
  1122. if ($this->is_delete == 1) {
  1123. $is_delete = 1;
  1124. }
  1125. $query = User::find()->alias('u')
  1126. ->leftJoin(['su' => SaasUser::tableName()], 'u.binding = su.mobile')
  1127. ->where(['u.is_delete' => $is_delete, 'u.store_id' => $this->store_id, 'u.is_team_bonus_leader' => 1]);
  1128. if (!is_null($this->team_bonus_leader_level) && $this->team_bonus_leader_level > 0) {
  1129. $query->andWhere(['u.team_bonus_leader_level' => $this->team_bonus_leader_level]);
  1130. }
  1131. if (!is_null($this->team_bonus_leader_status) && $this->team_bonus_leader_status > -1) {
  1132. $query->andWhere(['u.team_bonus_leader_status' => $this->team_bonus_leader_status]);
  1133. }
  1134. if ($this->id > 0) {
  1135. $query->andWhere(['u.id' => $this->id]);
  1136. }
  1137. if (!empty($this->name)) {
  1138. $query->andWhere(['like', 'su.name', trim($this->name)]);
  1139. }
  1140. if (!empty($this->mobile)) {
  1141. $query->andWhere(['like', 'u.binding', trim($this->binding)]);
  1142. }
  1143. if (!empty($this->begin_time)) {
  1144. $query->andWhere(['>=', 'u.team_bonus_leader_time', strtotime($this->begin_time)]);
  1145. }
  1146. if (!empty($this->end_time)) {
  1147. $query->andWhere(['<=', 'u.team_bonus_leader_time', strtotime($this->end_time)]);
  1148. }
  1149. $query->select('u.*, su.id saas_user_id, su.name, su.avatar');
  1150. $query->orderBy('u.team_bonus_leader_time DESC');
  1151. $pagination = pagination_make($query);
  1152. $teamLevels = array_column($this->teamBonusLevelSelectList()['data'], null, 'id');
  1153. foreach ($pagination['list'] as &$item) {
  1154. $item['team_bonus_leader_level_name'] = $teamLevels[$item['team_bonus_leader_level']] ? $teamLevels[$item['team_bonus_leader_level']]['name'] : '-';
  1155. $saasUser = SaasUser::findOne([$item['saas_user_id']]);
  1156. $item['saas_user'] = $saasUser;
  1157. $item['team_bonus_leader_time'] = date("Y-m-d H:i:s", $item['team_bonus_leader_time']);
  1158. $item['teamOrderPrice'] = self::teamOrderPrice($item);
  1159. $item['teamOrderPriceHistory'] = self::teamOrderPriceHistory($item);
  1160. $item['teamSelfOrderPrice'] = self::teamSelfOrderPrice($item);
  1161. $item['teamChildren'] = self::teamChildren($item);
  1162. $item['teamSharePrice'] = self::teamSharePrice($item);
  1163. $item['teamCash'] = self::teamCash($item);
  1164. }
  1165. return [
  1166. 'code' => 0,
  1167. 'msg' => 'success',
  1168. 'data' => $pagination,
  1169. 'q' => $query->createCommand()->getRawSql(),
  1170. ];
  1171. } catch (\Exception $e) {
  1172. \Yii::error($e);
  1173. return [
  1174. 'code' => 1,
  1175. 'msg' => $e->getMessage()
  1176. ];
  1177. }
  1178. }
  1179. /**
  1180. * 队长保存
  1181. */
  1182. public function teamLeaderSave($data) {
  1183. try {
  1184. $id = $data['id'];
  1185. $user = User::findOne($id);
  1186. if (empty($user)) {
  1187. throw new \Exception('参数错误' . $id);
  1188. }
  1189. if(!$user->is_team_bonus_leader){
  1190. $user->is_team_bonus_leader = 1;
  1191. $user->team_bonus_leader_status = 1;
  1192. $user->team_bonus_leader_time = time();
  1193. }
  1194. $user->team_bonus_leader_level = $data['team_bonus_leader_level'];
  1195. if(isset($data['team_bonus_leader_level_lock']) && $data['team_bonus_leader_level_lock'] > -1){
  1196. $user->team_bonus_leader_level_lock = $data['team_bonus_leader_level_lock'];
  1197. }
  1198. if (!$user->save()) {
  1199. \Yii::error([__METHOD__, $user->attributes]);
  1200. throw new \Exception('保存失败。' . array_shift($user->getFirstErrors()));
  1201. }
  1202. return [
  1203. 'code' => 0,
  1204. 'msg' => '操作成功!'
  1205. ];
  1206. } catch (\Exception $e) {
  1207. \Yii::error($e);
  1208. return [
  1209. 'code' => 1,
  1210. 'msg' => $e->getMessage()
  1211. ];
  1212. }
  1213. }
  1214. /**
  1215. * 队长状态
  1216. */
  1217. public function teamLeaderStatus() {
  1218. try {
  1219. $status = $this->status;
  1220. $id = $this->id;
  1221. if (!is_array($id)) {
  1222. $id = explode(',', $id);
  1223. }
  1224. foreach ($id as $item) {
  1225. $user = User::findOne($item);
  1226. if (!$user) {
  1227. throw new \Exception('参数错误' . $item);
  1228. }
  1229. $user->team_bonus_leader_status = $status;
  1230. if (!$user->save()) {
  1231. throw new \Exception('保存失败。' . $item . array_shift($user->getFirstErrors()));
  1232. }
  1233. }
  1234. return [
  1235. 'code' => 0,
  1236. 'msg' => 'success',
  1237. ];
  1238. } catch (\Exception $e) {
  1239. \Yii::error($e);
  1240. return [
  1241. 'code' => 1,
  1242. 'msg' => $e->getMessage()
  1243. ];
  1244. }
  1245. }
  1246. /**
  1247. * 团队成员
  1248. */
  1249. public function teamChildrenList() {
  1250. try {
  1251. $leader = User::findOne($this->user_id);
  1252. $getTeamBonusChildrenIds = self::getTeamBonusChildrenIds($this->store_id, $this->user_id);
  1253. $user_ids = $getTeamBonusChildrenIds['list'];
  1254. $is_delete = 0;
  1255. if ($this->is_delete == 1) {
  1256. $is_delete = 1;
  1257. }
  1258. $query = User::find()->alias('u')
  1259. ->leftJoin(['su' => SaasUser::tableName()], 'u.binding = su.mobile')
  1260. ->where(['u.is_delete' => $is_delete, 'u.store_id' => $this->store_id, 'u.id' => $user_ids]);
  1261. if (!is_null($this->team_bonus_leader_level) && $this->team_bonus_leader_level > -1) {
  1262. $query->andWhere(['u.team_bonus_leader_level' => $this->team_bonus_leader_level]);
  1263. }
  1264. if ($this->id > 0) {
  1265. $query->andWhere(['u.id' => $this->id]);
  1266. }
  1267. if (!empty($this->name)) {
  1268. $query->andWhere(['like', 'su.name', trim($this->name)]);
  1269. }
  1270. if (!empty($this->mobile)) {
  1271. $query->andWhere(['like', 'u.binding', trim($this->binding)]);
  1272. }
  1273. if (!empty($this->begin_time)) {
  1274. $query->andWhere(['>=', 'u.team_bonus_leader_time', strtotime($this->begin_time)]);
  1275. }
  1276. if (!empty($this->end_time)) {
  1277. $query->andWhere(['<=', 'u.team_bonus_leader_time', strtotime($this->end_time)]);
  1278. }
  1279. $query->select('u.*, su.id saas_user_id, su.name, su.avatar');
  1280. $query->orderBy('u.id DESC');
  1281. $pagination = pagination_make($query);
  1282. $teamLevels = array_column($this->teamBonusLevelSelectList()['data'], null, 'id');
  1283. $shareLevels = array_column(\app\models\ShareLevel::findAll(['store_id' => $this->store_id, 'is_delete' => 0]), null, 'level');
  1284. foreach ($pagination['list'] as &$item) {
  1285. $item['team_bonus_leader_level_name'] = $teamLevels[$item['team_bonus_leader_level']] ? $teamLevels[$item['team_bonus_leader_level']]['name'] : '-';
  1286. $share = Share::findOne(['user_id' => $item['id']]);
  1287. $item['share'] = $share;
  1288. $item['share_level_name'] = $share ? ($shareLevels[$share['level']] ? $shareLevels[$share['level']]['name'] : '无等级') : '非分销商';
  1289. $saasUser = SaasUser::findOne([$item['saas_user_id']]);
  1290. $item['saas_user'] = $saasUser;
  1291. $item['created_at'] = date("Y-m-d H:i:s", $item['created_at']);
  1292. $item['team_bonus_leader_time'] = date("Y-m-d H:i:s", $item['team_bonus_leader_time']);
  1293. $item['teamOrderPrice'] = self::teamOrderPrice($leader, null, 0, [], $item['id']);
  1294. $item['teamSharePrice'] = self::teamChildrenSharePrice($leader, $item['id']);
  1295. $item['teamCash'] = self::teamCash($item);
  1296. }
  1297. $teamOrderPrice = self::teamOrderPrice($leader);
  1298. return [
  1299. 'code' => 0,
  1300. 'msg' => 'success',
  1301. 'data' => $pagination,
  1302. '$shareLevels' => $shareLevels,
  1303. '$teamLevels' => $teamLevels,
  1304. '$getTeamBonusChildrenIds' => $getTeamBonusChildrenIds,
  1305. 'teamOrderPrice' => $teamOrderPrice,
  1306. // 'q' => $query->createCommand()->getRawSql(),
  1307. ];
  1308. } catch (\Exception $e) {
  1309. \Yii::error($e);
  1310. return [
  1311. 'code' => 1,
  1312. 'msg' => $e->getMessage()
  1313. ];
  1314. }
  1315. }
  1316. /**
  1317. * 队长等级保存
  1318. */
  1319. public function teamBonusLevelSave($data) {
  1320. try {
  1321. $id = $data['id'];
  1322. $teamBonusLevel = $id ? TeamBonusLevel::findOne(['id' => $id, 'store_id' => $this->store_id]) : new TeamBonusLevel();
  1323. if (empty($teamBonusLevel)) {
  1324. throw new \Exception('参数错误' . $id);
  1325. }
  1326. $teamBonusLevel->setAttributes($data, false);
  1327. $teamBonusLevel->store_id = $this->store_id;
  1328. if (!$teamBonusLevel->save()) {
  1329. \Yii::error([__METHOD__, $teamBonusLevel->attributes]);
  1330. throw new \Exception('保存失败。' . array_shift($teamBonusLevel->getFirstErrors()));
  1331. }
  1332. return [
  1333. 'code' => 0,
  1334. 'msg' => '操作成功!'
  1335. ];
  1336. } catch (\Exception $e) {
  1337. \Yii::error($e);
  1338. return [
  1339. 'code' => 1,
  1340. 'msg' => $e->getMessage()
  1341. ];
  1342. }
  1343. }
  1344. /**
  1345. * 队长等级状态变更
  1346. */
  1347. public function teamBonusLevelStatus($id, $status) {
  1348. try {
  1349. $teamBonusLevel = TeamBonusLevel::findOne($id);
  1350. if (!$teamBonusLevel) {
  1351. throw new \Exception('参数错误' . $id);
  1352. }
  1353. $teamBonusLevel->status = $status;
  1354. if (!$teamBonusLevel->save()) {
  1355. throw new \Exception('保存失败。' . $id . array_shift($teamBonusLevel->getFirstErrors()));
  1356. }
  1357. return [
  1358. 'code' => 0,
  1359. 'msg' => 'success',
  1360. ];
  1361. } catch (\Exception $e) {
  1362. \Yii::error($e);
  1363. return [
  1364. 'code' => 1,
  1365. 'msg' => $e->getMessage()
  1366. ];
  1367. }
  1368. }
  1369. /**
  1370. * 团队分红商品保存
  1371. */
  1372. public function teamBonusGoodsExtSave($data) {
  1373. try {
  1374. $goods_id = $data['goods_id'];
  1375. $TeamBonusGoodsExt = TeamBonusGoodsExt::findOne(['goods_id' => $goods_id, 'store_id' => $this->store_id]);
  1376. if (!$TeamBonusGoodsExt) {
  1377. $TeamBonusGoodsExt = new TeamBonusGoodsExt();
  1378. $TeamBonusGoodsExt->store_id = $this->store_id;
  1379. }
  1380. $TeamBonusGoodsExt->setAttributes($data, false);
  1381. $TeamBonusGoodsExt->store_id = $this->store_id;
  1382. if (!$TeamBonusGoodsExt->save(false)) {
  1383. \Yii::error([__METHOD__, $TeamBonusGoodsExt->attributes]);
  1384. throw new \Exception('保存失败。' . array_shift($TeamBonusGoodsExt->getFirstErrors()));
  1385. }
  1386. return [
  1387. 'code' => 0,
  1388. 'msg' => '操作成功!'
  1389. ];
  1390. } catch (\Exception $e) {
  1391. \Yii::error($e);
  1392. return [
  1393. 'code' => 1,
  1394. 'msg' => $e->getMessage()
  1395. ];
  1396. }
  1397. }
  1398. /**
  1399. * 团队分红商品分红状态
  1400. */
  1401. public function teamBonusGoodsExtStatus() {
  1402. try {
  1403. $status = $this->status;
  1404. $id = $this->goods_id;
  1405. if (!is_array($id)) {
  1406. $id = explode(',', $id);
  1407. }
  1408. foreach ($id as $item) {
  1409. $TeamBonusGoodsExt = TeamBonusGoodsExt::findOne(['goods_id' => $item, 'store_id' => $this->store_id]);
  1410. if (!$TeamBonusGoodsExt) {
  1411. $TeamBonusGoodsExt = new TeamBonusGoodsExt();
  1412. $TeamBonusGoodsExt->store_id = $this->store_id;
  1413. $TeamBonusGoodsExt->goods_id = $item;
  1414. }
  1415. $TeamBonusGoodsExt->status = $status;
  1416. if (!$TeamBonusGoodsExt->save()) {
  1417. throw new \Exception('保存失败。' . $item . array_shift($TeamBonusGoodsExt->getFirstErrors()));
  1418. }
  1419. }
  1420. return [
  1421. 'code' => 0,
  1422. 'msg' => 'success',
  1423. ];
  1424. } catch (\Exception $e) {
  1425. \Yii::error($e);
  1426. return [
  1427. 'code' => 1,
  1428. 'msg' => $e->getMessage()
  1429. ];
  1430. }
  1431. }
  1432. //商品分红比例最大值
  1433. public static function teamBonusGoodsProfit($store_id, $goods, $teamBonusGoodsExt = false) {
  1434. if(!$goods['id']){
  1435. $goods = \app\models\Goods::findOne($goods);
  1436. }
  1437. $goods_id = $goods['id'];
  1438. $self = new self(['store_id' => $store_id]);
  1439. $levels = $self->teamBonusLevelList()['data'];
  1440. $max = $levels ? max(array_column($levels, 'range_rate')) : 0;
  1441. if($teamBonusGoodsExt === false){
  1442. $teamBonusGoodsExt = TeamBonusGoodsExt::findOne(['goods_id' => $goods_id, 'store_id' => $store_id]);
  1443. }
  1444. if($teamBonusGoodsExt){
  1445. if($teamBonusGoodsExt['is_profit_self']){
  1446. $rule = json_decode($teamBonusGoodsExt['profit_rule'], true);
  1447. $max = $rule ? max(array_column($rule, 'range_rate')) : 0;
  1448. }
  1449. }
  1450. return floatval($max) / 100;
  1451. }
  1452. //提现
  1453. public function cashSubmit($price, $type, $user_id = 0, $name = '', $account = '', $bank = '') {
  1454. $t = \Yii::$app->db->beginTransaction();
  1455. try {
  1456. if ($price <= 0) {
  1457. throw new \Exception('提现金额非法' . $price);
  1458. }
  1459. $store_id = $this->store_id;
  1460. $exit = Cash::find()->andWhere(['=', 'status', 0])->andWhere(['store_id' => $store_id, 'user_id' => $user_id, 'cash_type' => Cash::IS_CASH_TYPE_TEAM_BONUS])->exists();
  1461. if ($exit) {
  1462. // throw new \Exception('尚有未完成的提现申请');
  1463. }
  1464. $user = User::findOne($user_id);
  1465. $conf = $this->teamBonusSetting()['conf'];
  1466. if($conf['cash_min'] > 0 && $price < $conf['cash_min']){
  1467. throw new \Exception('最少提现¥' . $conf['cash_min']);
  1468. }
  1469. if ($conf['cash_max_day']) {
  1470. $cash_sum = Cash::find()->where([
  1471. 'store_id' => $store_id,
  1472. 'is_delete' => 0,
  1473. 'status' => [0, 1, 2, 4, 5],
  1474. ])->andWhere([
  1475. 'AND',
  1476. ['>=', 'created_at', strtotime(date('Y-m-d 00:00:00'))],
  1477. ])->sum('price');
  1478. $cash_max_day = $conf['cash_max_day'] - ($cash_sum ? $cash_sum : 0);
  1479. if ($price > $cash_max_day) {
  1480. throw new \Exception('今日平台限制,提现金额不能超过¥' . $cash_max_day);
  1481. }
  1482. }
  1483. if ($conf['cash_max_single_day']) {
  1484. $cash_sum = Cash::find()->where([
  1485. 'store_id' => $store_id,
  1486. 'is_delete' => 0,
  1487. 'status' => [0, 1, 2, 4, 5],
  1488. 'user_id' => $user_id
  1489. ])->andWhere([
  1490. 'AND',
  1491. ['>=', 'created_at', strtotime(date('Y-m-d 00:00:00'))],
  1492. ])->sum('price');
  1493. $cash_max_single_day_ = $conf['cash_max_single_day'] - ($cash_sum ?: 0);
  1494. if ($price > $cash_max_single_day_) {
  1495. throw new \Exception('今日个人限制,提现金额不能超过¥' . $cash_max_single_day_);
  1496. }
  1497. }
  1498. // $service_charge = $price * $conf['cash_rate'] / 100;
  1499. $cash = new Cash();
  1500. $cash->order_no = OrderNo::getOrderNo(OrderNo::ORDER_CASH);
  1501. $cash->is_delete = 0;
  1502. $cash->status = 0;
  1503. $cash->price = $price;
  1504. $cash->created_at = time();
  1505. $cash->user_id = $user_id;
  1506. $cash->store_id = $store_id;
  1507. $cash->type = $type;
  1508. $cash->name = $name;
  1509. $cash->mobile = $account;
  1510. $cash->bank_name = $bank;
  1511. $cash->pay_time = 0;
  1512. $cash->service_charge = $conf['cash_rate'];
  1513. $cash->cash_type = Cash::IS_CASH_TYPE_TEAM_BONUS;
  1514. if (!$cash->save()) {
  1515. \Yii::error([__METHOD__, $cash->getErrors()]);
  1516. throw new \Exception('团队分红提现保存失败' . array_shift($cash->getFirstErrors()));
  1517. }
  1518. $user->price -= $price;
  1519. if($user->price < 0){
  1520. throw new \Exception('用户佣金不足');
  1521. }
  1522. if (!$user->save()) {
  1523. \Yii::error([__METHOD__, $user->getErrors()]);
  1524. throw new \Exception('用户佣金保存失败' . array_shift($user->getFirstErrors()));
  1525. }
  1526. $t->commit();
  1527. return [
  1528. 'code' => 0,
  1529. 'msg' => '操作成功'
  1530. ];
  1531. } catch (\Exception $e) {
  1532. \Yii::error($e);
  1533. debug_log([__FUNCTION__, __LINE__, $this->store_id, $price, $type, $user_id, $e->getMessage()], __CLASS__ . '.log');
  1534. $t->rollBack();
  1535. return [
  1536. 'code' => 1,
  1537. 'msg' => '操作失败,' . $e->getMessage()
  1538. ];
  1539. }
  1540. }
  1541. /**
  1542. * 手机端首页
  1543. */
  1544. public function teamBonusIndex($user) {
  1545. try{
  1546. $user_id = $this->user_id;
  1547. $store_id = $this->store_id;
  1548. if($user->is_team_bonus_leader){
  1549. if(!$user->team_bonus_leader_status){
  1550. throw new \Exception('队长状态异常');
  1551. }
  1552. }else{
  1553. throw new \Exception('不是队长,无法进入');
  1554. // $share = Share::find()->where(['store_id' => $store_id, 'status' => 1, 'is_delete' => 0, 'user_id' => $user_id])->one();
  1555. // if(!$share){
  1556. // throw new \Exception('不是队长和分销员,无法进入');
  1557. // }
  1558. }
  1559. $types = [
  1560. ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT,
  1561. ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL,
  1562. ShareDetail::TYPE_TEAM_BONUS_PARENT,
  1563. ShareDetail::TYPE_TEAM_BONUS_THANKS,
  1564. ];
  1565. $sumUnSend = (float)ShareDetail::find()->where(['store_id' => $store_id, 'is_delete' => 0, 'user_id' => $user_id, 'is_send' => 0, 'type' => $types])->sum('money');
  1566. $sumCash = (float)Cash::find()->where(['store_id' => $store_id, 'is_delete' => 0, 'cash_type' => Cash::IS_CASH_TYPE_TEAM_BONUS, 'status' => [0, 1, 2, 4, 5], 'user_id' => $user_id])->sum('price');
  1567. $levels = $this->teamBonusLevelSelectList()['data'];
  1568. $team_bonus_leader_level_name = $levels[$user->team_bonus_leader_level] ? $levels[$user->team_bonus_leader_level]['name'] : '-';
  1569. return [
  1570. 'code' => 0,
  1571. 'data' => [
  1572. 'user' => $user,
  1573. 'saas_user' => SaasUser::findOne(['mobile' => $user['binding']]),
  1574. 'sumUnSend' => $sumUnSend,
  1575. 'sumCash' => $sumCash,
  1576. 'team_bonus_leader_level_name' => $team_bonus_leader_level_name,
  1577. 'share' => $share,
  1578. ],
  1579. ];
  1580. } catch (\Exception $e) {
  1581. \Yii::error($e);
  1582. debug_log([__FUNCTION__, __LINE__, $this->store_id, $this->user_id, $e->getMessage()], __CLASS__ . '.log');
  1583. return [
  1584. 'code' => 1,
  1585. 'msg' => '操作失败,' . $e->getMessage()
  1586. ];
  1587. }
  1588. }
  1589. /**
  1590. * 分红记录
  1591. */
  1592. public function teamLeaderShareDetails($params = []) {
  1593. $user_id = $this->user_id;
  1594. if($params['user_id']){
  1595. $user_id = $params['user_id'];
  1596. }
  1597. $store_id = $this->store_id;
  1598. $type = $params['type'];
  1599. $is_send = $params['is_send'];
  1600. $_get_order = $params['_get_order'];
  1601. $types = [
  1602. ShareDetail::TYPE_TEAM_BONUS_RANGE_PROFIT,
  1603. ShareDetail::TYPE_TEAM_BONUS_SAME_LEVEL,
  1604. ShareDetail::TYPE_TEAM_BONUS_PARENT,
  1605. ShareDetail::TYPE_TEAM_BONUS_THANKS,
  1606. ];
  1607. $query = ShareDetail::find()->where(['store_id' => $store_id, 'is_delete' => 0]);
  1608. if($user_id){
  1609. $query->andWhere(['user_id' => $user_id]);
  1610. }
  1611. if($type){
  1612. $query->andWhere(['type' => $type]);
  1613. }else{
  1614. $query->andWhere(['type' => $types]);
  1615. }
  1616. if(isset($is_send) && $is_send > -1){
  1617. $query->andWhere(['is_send' => $is_send]);
  1618. }
  1619. if($params['team_leader_name']){
  1620. $query->andWhere(['user_id' => User::find()->alias('u')->leftJoin(['su' => SaasUser::tableName()], 'u.binding=su.mobile')->select('u.id')->where(['like', 'su.name', trim($params['team_leader_name'])])]);
  1621. }
  1622. if (!empty($params['begin_time'])) {
  1623. $query->andWhere(['>=', 'send_time', strtotime($params['begin_time'])]);
  1624. }
  1625. if (!empty($params['end_time'])) {
  1626. $query->andWhere(['<=', 'send_time', strtotime($params['end_time'])]);
  1627. }
  1628. $query->orderBy('id DESC');
  1629. $list = pagination_make($query);
  1630. if($user_id){
  1631. $user = User::findOne($user_id);
  1632. $saas_user = SaasUser::findOne(['mobile' => $user['binding']]);
  1633. $item_saas_user = $saas_user;
  1634. }
  1635. foreach($list['list'] as &$item){
  1636. $item['type_name'] = ShareDetail::typeName($item['type']);
  1637. if($_get_order){
  1638. $order = Order::findOne($item['type_id']);
  1639. $item['order'] = $order;
  1640. if($order){
  1641. $item['order_detail'] = $order->detail;
  1642. $order_user = User::findOne($order->user_id);
  1643. $item['order_saas_user'] = SaasUser::findOne(['mobile' => $order_user['binding']]);
  1644. }
  1645. }
  1646. if($user_id){
  1647. $item['saas_user'] = $item_saas_user;
  1648. }else{
  1649. $user = User::findOne($item['user_id']);
  1650. $saas_user = SaasUser::findOne(['mobile' => $user['binding']]);
  1651. $item['saas_user'] = $saas_user;
  1652. }
  1653. }
  1654. return [
  1655. 'q' => $query->createCommand()->getRawSql(),
  1656. 'code' => 0,
  1657. 'data' => $list,
  1658. 'types' => ShareDetail::typeName(),
  1659. ];
  1660. }
  1661. }