DistributionLevelLogic.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeshop100%开源免费商用商城系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | 商业版本务必购买商业授权,以免引起法律纠纷
  8. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  9. // | gitee下载:https://gitee.com/likeshop_gitee
  10. // | github下载:https://github.com/likeshop-github
  11. // | 访问官网:https://www.likeshop.cn
  12. // | 访问社区:https://home.likeshop.cn
  13. // | 访问手册:http://doc.likeshop.cn
  14. // | 微信公众号:likeshop技术社区
  15. // | likeshop团队 版权所有 拥有最终解释权
  16. // +----------------------------------------------------------------------
  17. // | author: likeshopTeam
  18. // +----------------------------------------------------------------------
  19. namespace app\adminapi\logic\distribution;
  20. use app\common\enum\DistributionLevelEnum;
  21. use app\common\enum\DistributionOrderGoodsEnum;
  22. use app\common\enum\YesNoEnum;
  23. use app\common\logic\BaseLogic;
  24. use app\common\model\Distribution;
  25. use app\common\model\DistributionGoods;
  26. use app\common\model\DistributionLevel;
  27. use app\common\model\DistributionLevelUpdate;
  28. use app\common\model\DistributionOrderGoods;
  29. use app\common\model\Order;
  30. use think\facade\Db;
  31. /**
  32. * 分销会员等级逻辑层
  33. * Class DistributionLevelLogic
  34. * @package app\adminapi\logic\distribution
  35. */
  36. class DistributionLevelLogic extends BaseLogic
  37. {
  38. /**
  39. * @notes 添加分销会员等级
  40. * @param $params
  41. * @author Tab
  42. * @date 2021/7/22 11:22
  43. */
  44. public static function add($params)
  45. {
  46. Db::startTrans();
  47. try{
  48. // 写入等级主表
  49. $params['remark'] = $params['remark'] ?? '';
  50. $newLevel = DistributionLevel::create($params);
  51. // 写入升级条件表
  52. self::addUpdateCondition($params['update_condition'], $newLevel->id);
  53. // 处理分销商品比例
  54. self::updateDistributionGoods($newLevel->id);
  55. Db::commit();
  56. return true;
  57. }catch(\Exception $e) {
  58. Db::rollback();
  59. self::setError($e->getMessage());
  60. return false;
  61. }
  62. }
  63. /**
  64. * @notes 写入升级条件表
  65. * @param $updateCondition
  66. * @param $level_id
  67. * @throws \Exception
  68. * @author Tab
  69. * @date 2021/7/22 14:28
  70. */
  71. public static function addUpdateCondition($updateCondition, $level_id)
  72. {
  73. $updateConditionData = [];
  74. foreach($updateCondition as $item) {
  75. // 判断是否在规定的条件字段
  76. $key = key($item);
  77. if(!in_array($key, DistributionLevelEnum::UPDATE_CONDITION_FIELDS, true)) {
  78. continue;
  79. }
  80. // 如果值为空跳过
  81. if (empty($item[$key])) {
  82. continue;
  83. }
  84. // 获取键对应值的字段名
  85. $valueField = DistributionLevelEnum::getValueFiled($key);
  86. $updateConditionData[] = [
  87. 'level_id' => $level_id,
  88. 'key' => key($item),
  89. $valueField => $item[$key]
  90. ];
  91. }
  92. (new DistributionLevelUpdate())->saveAll($updateConditionData);
  93. }
  94. /**
  95. * @notes 查看分销会员等级详情
  96. * @param $params
  97. * @return array
  98. * @author Tab
  99. * @date 2021/7/22 15:30
  100. */
  101. public static function detail($params)
  102. {
  103. $level = DistributionLevel::withoutField('create_time,update_time,delete_time')->findOrEmpty($params['id']);
  104. if($level->isEmpty()) {
  105. return [];
  106. }
  107. $level = $level->toArray();
  108. // 默认等级
  109. if($level['is_default']) {
  110. unset($level['third_ratio']);
  111. unset($level['is_default']);
  112. unset($level['update_relation']);
  113. return $level;
  114. }
  115. // 自定义等级
  116. $level['update_condition'] = self::getUpdateCondition($level);
  117. unset($level['third_ratio']);
  118. unset($level['is_default']);
  119. return $level;
  120. }
  121. /**
  122. * @notes 获取升级条件
  123. * @param $level
  124. * @return array
  125. * @author Tab
  126. * @date 2021/7/22 15:29
  127. */
  128. public static function getUpdateCondition($level)
  129. {
  130. $updateCondition = DistributionLevelUpdate::where('level_id', $level['id'])->column('key,value_int,value_decimal,value_text');
  131. $updateConditionData = [];
  132. foreach($updateCondition as $item) {
  133. if($item['value_int']) {
  134. $updateConditionData[$item['key']] = $item['value_int'];
  135. continue;
  136. }
  137. if($item['value_decimal']) {
  138. $updateConditionData[$item['key']] = $item['value_decimal'];
  139. continue;
  140. }
  141. if($item['value_text']) {
  142. $updateConditionData[$item['key']] = $item['value_text'];
  143. continue;
  144. }
  145. }
  146. return $updateConditionData;
  147. }
  148. /**
  149. * @notes 编辑分销会员等级
  150. * @param $params
  151. * @return bool
  152. * @author Tab
  153. * @date 2021/7/22 16:22
  154. */
  155. public static function edit($params)
  156. {
  157. Db::startTrans();
  158. try{
  159. $params['remark'] = $params['remark'] ?? '';
  160. $level = DistributionLevel::findOrEmpty($params['id']);
  161. if($level->isEmpty()) {
  162. throw new \Exception('等级不存在');
  163. }
  164. // 默认等级
  165. if($level->is_default) {
  166. $level->allowField(['name', 'self_ratio', 'first_ratio', 'second_ratio','remark'])->save($params);
  167. Db::commit();
  168. return true;
  169. }
  170. // 自定义等级 - 更新主表信息
  171. if(!$params['weights'] > 1) {
  172. throw new \Exception('级别须大于1');
  173. }
  174. if(!isset($params['update_relation'])) {
  175. throw new \Exception('请选择升级关系');
  176. }
  177. if(!isset($params['update_condition']) || !count($params['update_condition'])) {
  178. throw new \Exception('请选择升级条件');
  179. }
  180. $level->allowField(['name', 'weights', 'self_ratio', 'first_ratio', 'second_ratio','remark', 'update_relation'])->save($params);
  181. // 自定义等级 - 删除旧升级条件
  182. $deleteIds = DistributionLevelUpdate::where('level_id', $level->id)->column('id');
  183. DistributionLevelUpdate::destroy($deleteIds);
  184. // 自定义等级 - 添加新的升级条件
  185. self::addUpdateCondition($params['update_condition'], $level->id);
  186. Db::commit();
  187. return true;
  188. }catch(\Exception $e) {
  189. Db::rollback();
  190. self::setError($e->getMessage());
  191. return false;
  192. }
  193. }
  194. /**
  195. * @notes 删除分销会员等级
  196. * @param $params
  197. * @return false
  198. * @author Tab
  199. * @date 2021/7/22 16:49
  200. */
  201. public static function delete($params)
  202. {
  203. Db::startTrans();
  204. try{
  205. $level = DistributionLevel::findOrEmpty($params['id']);
  206. if($level->isEmpty()) {
  207. throw new \Exception('等级不存在');
  208. }
  209. if($level->is_default) {
  210. throw new \Exception('系统默认等级不允许删除');
  211. }
  212. // 重置该等级下的分销会员为系统默认等级
  213. $defaultId = DistributionLevel::where('is_default', DistributionLevelEnum::IS_DEFAULT_YES)->value('id');
  214. Distribution::where('level_id', $level->id)->update(['level_id' => $defaultId]);
  215. // 删除升级条件
  216. $deleteIds = DistributionLevelUpdate::where('level_id', $level->id)->column('id');
  217. DistributionLevelUpdate::destroy($deleteIds);
  218. // 删除该等级下的分销商品比例
  219. $deleteIds = DistributionGoods::where('level_id', $level->id)->column('id');
  220. DistributionGoods::destroy($deleteIds);
  221. // 删除等级
  222. $level->delete();
  223. Db::commit();
  224. return true;
  225. }catch(\Exception $e) {
  226. Db::rollback();
  227. self::setError($e->getMessage());
  228. return false;
  229. }
  230. }
  231. /**
  232. * @notes 更新分销商等级
  233. * @param $userId
  234. * @author Tab
  235. * @date 2021/7/26 19:14
  236. */
  237. public static function updateDistributionLevel($userId)
  238. {
  239. // 非默认等级
  240. $levels = DistributionLevel::where('is_default', YesNoEnum::NO)
  241. ->order('weights', 'desc')
  242. ->column('id,name,weights,update_relation', 'id');
  243. $userInfo = Distribution::alias('d')
  244. ->leftJoin('distribution_level dl', 'dl.id = d.level_id')
  245. ->field('d.is_distribution,d.level_id,dl.weights')
  246. ->where('d.user_id', $userId)
  247. ->findOrEmpty()
  248. ->toArray();
  249. // 非分销会员直接返回false
  250. if(empty($userInfo['is_distribution'])) {
  251. return false;
  252. }
  253. foreach($levels as $level) {
  254. if(self::isMeetConditions($userId, $level) && $level['weights'] > $userInfo['weights']) {
  255. // 满足升级条件且是升更高的等级
  256. Distribution::where(['user_id' => $userId])->update(['level_id' => $level['id']]);
  257. break;
  258. }
  259. }
  260. }
  261. /**
  262. * @notes 判断是否满足当前等级的升级条件
  263. * @param $userId
  264. * @param $level
  265. * @return bool
  266. * @author Tab
  267. * @date 2021/7/26 19:10
  268. */
  269. public static function isMeetConditions($userId, $level)
  270. {
  271. // 任一条件满足升级
  272. $updateRelation = $level['update_relation'];
  273. if($updateRelation == DistributionLevelEnum::UPDATE_RELATION_OR) {
  274. $flagOr = self::singleConsumptionAmountFlag($userId, $level, $updateRelation)
  275. || self::cumulativeConsumptionAmountFlag($userId, $level, $updateRelation)
  276. || self::cumulativeConsumptionTimesFlag($userId, $level, $updateRelation)
  277. || self::returnedCommissionFlag($userId, $level, $updateRelation);
  278. return $flagOr;
  279. }
  280. // 全部条件满足升级
  281. if($updateRelation == DistributionLevelEnum::UPDATE_RELATION_AND) {
  282. $flagAnd = self::singleConsumptionAmountFlag($userId, $level, $updateRelation)
  283. && self::cumulativeConsumptionAmountFlag($userId, $level, $updateRelation)
  284. && self::cumulativeConsumptionTimesFlag($userId, $level, $updateRelation)
  285. && self::returnedCommissionFlag($userId, $level, $updateRelation);
  286. return $flagAnd;
  287. }
  288. }
  289. /**
  290. * @notes 判断是否满足单笔消费金额条件
  291. * @param $userId
  292. * @param $level
  293. * @return bool
  294. * @author Tab
  295. * @date 2021/7/26 18:55
  296. */
  297. public static function singleConsumptionAmountFlag($userId, $level, $updateRelation)
  298. {
  299. $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text')
  300. ->where([
  301. 'level_id' => $level['id'],
  302. 'key' => 'singleConsumptionAmount'
  303. ])
  304. ->findOrEmpty();
  305. if($condition->isEmpty()) {
  306. // 等级条件为满足任一条件(updateRelation=1) 返回false (满足已设置的任一条件时才升级,未设置的条件归为未满足,返回false)
  307. // 等级条件为满足全部条件(updateRelation=2) 返回true (满足已设置的所有条件时才升级,未设置的条件归为已满足,返回true)
  308. return $updateRelation == DistributionLevelEnum::UPDATE_RELATION_AND;
  309. }
  310. $singleConsumptionAmount = Order::where([
  311. 'user_id' => $userId,
  312. 'pay_status' => YesNoEnum::YES
  313. ])
  314. ->order('id', 'desc')
  315. ->findOrEmpty();
  316. if($singleConsumptionAmount->isEmpty()) {
  317. return false;
  318. }
  319. if($singleConsumptionAmount->order_amount >= $condition->value_decimal) {
  320. return true;
  321. }
  322. return false;
  323. }
  324. /**
  325. * @notes 判断是否满足累计消费金额条件
  326. * @param $userId
  327. * @param $level
  328. * @return bool
  329. * @author Tab
  330. * @date 2021/7/26 18:55
  331. */
  332. public static function cumulativeConsumptionAmountFlag($userId, $level, $updateRelation)
  333. {
  334. $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text')
  335. ->where([
  336. 'level_id' => $level['id'],
  337. 'key' => 'cumulativeConsumptionAmount'
  338. ])
  339. ->findOrEmpty();
  340. if($condition->isEmpty()) {
  341. // 等级条件为满足任一条件(updateRelation=1) 返回false (满足已设置的任一条件时才升级,未设置的条件归为未满足,返回false)
  342. // 等级条件为满足全部条件(updateRelation=2) 返回true (满足已设置的所有条件时才升级,未设置的条件归为已满足,返回true)
  343. return $updateRelation == DistributionLevelEnum::UPDATE_RELATION_AND;
  344. }
  345. $cumulativeConsumptionAmount = Order::where([
  346. 'user_id' => $userId,
  347. 'pay_status' => YesNoEnum::YES
  348. ])->sum('order_amount');
  349. if($cumulativeConsumptionAmount >= $condition->value_decimal) {
  350. return true;
  351. }
  352. return false;
  353. }
  354. /**
  355. * @notes 判断是否满足累计消费次数条件
  356. * @param $userId
  357. * @param $level
  358. * @return bool
  359. * @author Tab
  360. * @date 2021/7/26 18:56
  361. */
  362. public static function cumulativeConsumptionTimesFlag($userId, $level, $updateRelation)
  363. {
  364. $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text')
  365. ->where([
  366. 'level_id' => $level['id'],
  367. 'key' => 'cumulativeConsumptionTimes'
  368. ])
  369. ->findOrEmpty();
  370. if($condition->isEmpty()) {
  371. // 等级条件为满足任一条件(updateRelation=1) 返回false (满足已设置的任一条件时才升级,未设置的条件归为未满足,返回false)
  372. // 等级条件为满足全部条件(updateRelation=2) 返回true (满足已设置的所有条件时才升级,未设置的条件归为已满足,返回true)
  373. return $updateRelation == DistributionLevelEnum::UPDATE_RELATION_AND;
  374. }
  375. $cumulativeConsumptionTimes = Order::where([
  376. 'user_id' => $userId,
  377. 'pay_status' => YesNoEnum::YES
  378. ])->count();
  379. if($cumulativeConsumptionTimes >= $condition->value_int) {
  380. return true;
  381. }
  382. return false;
  383. }
  384. /**
  385. * @notes 判断是否消费已返佣金条件
  386. * @param $userId
  387. * @param $level
  388. * @return bool
  389. * @author Tab
  390. * @date 2021/7/26 18:56
  391. */
  392. public static function returnedCommissionFlag($userId, $level, $updateRelation)
  393. {
  394. $condition = DistributionLevelUpdate::field('value_int,value_decimal,value_text')
  395. ->where([
  396. 'level_id' => $level['id'],
  397. 'key' => 'returnedCommission'
  398. ])
  399. ->findOrEmpty();
  400. if($condition->isEmpty()) {
  401. // 等级条件为满足任一条件(updateRelation=1) 返回false (满足已设置的任一条件时才升级,未设置的条件归为未满足,返回false)
  402. // 等级条件为满足全部条件(updateRelation=2) 返回true (满足已设置的所有条件时才升级,未设置的条件归为已满足,返回true)
  403. return $updateRelation == DistributionLevelEnum::UPDATE_RELATION_AND;
  404. }
  405. $returnedCommission = DistributionOrderGoods::where([
  406. 'user_id' => $userId,
  407. 'status' => DistributionOrderGoodsEnum::RETURNED
  408. ])->sum('earnings');
  409. if($returnedCommission >= $condition->value_decimal) {
  410. return true;
  411. }
  412. return false;
  413. }
  414. /**
  415. * @notes 更新分销商品比例
  416. * @param $levelId
  417. * @author Tab
  418. * @date 2021/9/11 16:04
  419. */
  420. public static function updateDistributionGoods($levelId)
  421. {
  422. // 处理单独设置比例的商品,新增分销会等级佣金比例初始化为0
  423. $field = [
  424. 'goods_id',
  425. 'item_id',
  426. ];
  427. $distribution = DistributionGoods::distinct(true)->field($field)->where('rule', 2)->select()->toArray();
  428. $addData = [];
  429. foreach($distribution as $item) {
  430. $temp = [
  431. 'goods_id' => $item['goods_id'],
  432. 'item_id' => $item['item_id'],
  433. 'level_id' => $levelId,
  434. 'first_ratio' => 0,
  435. 'second_ratio' => 0,
  436. 'rule' => 2,
  437. ];
  438. $addData[] = $temp;
  439. }
  440. (new DistributionGoods())->saveAll($addData);
  441. }
  442. }