Privilege.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * Author: 芸众商城 www.yunzshop.com
  5. * Date: 2017/2/28
  6. * Time: 上午10:54
  7. */
  8. namespace app\common\models\goods;
  9. use app\common\exceptions\AppException;
  10. use app\common\models\BaseModel;
  11. use app\common\models\Goods;
  12. use app\common\models\GoodsOption;
  13. use app\common\models\Member;
  14. use app\common\models\MemberGroup;
  15. use app\common\models\MemberLevel;
  16. use app\common\models\Order;
  17. use Carbon\Carbon;
  18. use Illuminate\Support\Facades\DB;
  19. use app\common\facades\Setting;
  20. /**
  21. * Class Privilege
  22. * @package app\common\models\goods
  23. * @property int goods_id
  24. * @property string option_buy_limit
  25. * @property array option_id_array
  26. * @property string show_levels
  27. * @property string show_groups
  28. * @property string buy_levels
  29. * @property string buy_groups
  30. * @property int once_buy_limit
  31. * @property int total_buy_limit
  32. * @property int day_buy_limit
  33. * @property Carbon time_begin_limit
  34. * @property Carbon time_end_limit
  35. * @property int enable_time_limit
  36. * @property int week_buy_limit
  37. * @property int month_buy_limit
  38. * @property Goods goods
  39. */
  40. class Privilege extends BaseModel
  41. {
  42. public $table = 'yz_goods_privilege';
  43. public $attributes = [
  44. 'show_levels' => '',
  45. 'show_groups' => '',
  46. 'buy_levels' => '',
  47. 'buy_groups' => '',
  48. 'option_buy_limit'=> '',
  49. 'once_buy_limit' => 0,
  50. 'total_buy_limit' => 0,
  51. 'day_buy_limit' => 0,
  52. 'week_buy_limit' => 0,
  53. 'month_buy_limit' => 0,
  54. 'time_begin_limit' => 0,
  55. 'time_end_limit' => 0,
  56. 'enable_time_limit' => 0,
  57. 'min_buy_limit' => 0,
  58. 'day_buy_total_limit' => 0,
  59. 'buy_multiple' => 0,
  60. ];
  61. /**
  62. * 不可填充字段.
  63. *
  64. * @var array
  65. */
  66. protected $guarded = ['created_at', 'updated_at','time_begin_limit','time_end_limit'];
  67. /**
  68. * 获取商品权限信息
  69. * @param $goodsId
  70. * @return self
  71. */
  72. public static function getGoodsPrivilegeInfo($goodsId)
  73. {
  74. $goodsPrivilegeInfo = self::where('goods_id', $goodsId)
  75. ->first();
  76. return $goodsPrivilegeInfo;
  77. }
  78. /**
  79. * 自定义字段名
  80. * 可使用
  81. * @return array
  82. */
  83. public function atributeNames()
  84. {
  85. return [
  86. 'show_levels' => '会员浏览等级',
  87. 'show_groups' => '会员浏览分组',
  88. 'buy_levels' => '会员购买等级',
  89. 'buy_groups' => '会员购买分组',
  90. 'once_buy_limit' => '单次购买限制',
  91. 'total_buy_limit' => '总购买限制',
  92. 'day_buy_limit' => '每天购买限制',
  93. 'week_buy_limit' => '每周购买限制',
  94. 'month_buy_limit' => '每月购买限制',
  95. 'time_begin_limit' => '限时起始时间',
  96. 'time_end_limit' => '限时结束时间',
  97. 'min_buy_limit' => '会员起购数量',
  98. 'buy_multiple' => '会员购买倍数',
  99. ];
  100. }
  101. public function rules()
  102. {
  103. return [
  104. 'show_levels' => '',
  105. 'show_groups' => '',
  106. 'buy_levels' => '',
  107. 'buy_groups' => '',
  108. 'once_buy_limit' => 'numeric',
  109. 'total_buy_limit' => 'numeric',
  110. 'day_buy_limit' => 'numeric',
  111. 'week_buy_limit' => 'numeric',
  112. 'month_buy_limit' => 'numeric',
  113. 'time_begin_limit' => '',
  114. 'time_end_limit' => '',
  115. 'min_buy_limit' => 'numeric',
  116. 'buy_multiple' => 'numeric',
  117. ];
  118. }
  119. protected $casts = [
  120. 'time_begin_limit' => 'datetime',
  121. 'time_end_limit' => 'datetime',
  122. ];
  123. public function goods()
  124. {
  125. return $this->belongsTo(Goods::class);
  126. }
  127. public function getOptionIdArrayAttribute()
  128. {
  129. return array_filter(explode(',', $this->option_buy_limit), function ($item) {
  130. return !empty($item);
  131. });
  132. }
  133. /**
  134. *
  135. * @param Member $member
  136. * @param $num
  137. * @throws AppException
  138. */
  139. public function validate(Member $member,$num)
  140. {
  141. $this->validateTimeLimit();
  142. $this->validateMinBuyLimit($num);
  143. $this->validateDayBuyTotalLimit($num);
  144. $this->validateOneBuyLimit($num);
  145. $this->validateDayBuyLimit($member,$num);
  146. $this->validateWeekBuyLimit($member,$num);
  147. $this->validateMonthBuyLimit($member,$num);
  148. $this->validateTotalBuyLimit($member,$num);
  149. $this->validateMemberLevelLimit($member);
  150. $this->validateMemberGroupLimit($member);
  151. $this->validateBuyMultipleLimit($num);
  152. }
  153. /**
  154. * 开启规格权限验证按指定商品规格判断
  155. * @param GoodsOption $goodsOption
  156. * @param Member $member
  157. * @param $num
  158. * @throws AppException
  159. */
  160. public function optionValidate(GoodsOption $goodsOption,Member $member,$num)
  161. {
  162. $this->validateTimeLimit();
  163. $this->validateMinBuyLimit($num);
  164. $this->validateDayBuyTotalLimit($num);
  165. $this->validateOneBuyLimit($num);
  166. $this->validateDayBuyLimit($member,$num);
  167. $this->validateWeekBuyLimit($member,$num);
  168. $this->validateMonthBuyLimit($member,$num);
  169. $this->validateTotalBuyLimit($member,$num);
  170. $this->validateMemberLevelLimit($member);
  171. $this->validateMemberGroupLimit($member);
  172. $this->validateBuyMultipleLimit($num);
  173. }
  174. /**
  175. * 商品单次购买最低数量
  176. * @param $num
  177. * @throws AppException
  178. */
  179. public function validateMinBuyLimit($num)
  180. {
  181. //只做平台商品验证,解除限制所以商品都会验证
  182. if (intval($this->min_buy_limit) > 0) {
  183. if ($num < $this->min_buy_limit) {
  184. throw new AppException('商品:(' . $this->goods->title . '),未到达最低购买数量' . $this->min_buy_limit . '件');
  185. }
  186. }
  187. }
  188. /**
  189. * todo 这个好像没用了,因限时购的数据记录不在这张表了,yz_goods_limitbuy 这张表记录和验证
  190. * 限时购
  191. * @throws AppException
  192. */
  193. public function validateTimeLimit()
  194. {
  195. if ($this->enable_time_limit) {
  196. if (Carbon::now()->lessThan($this->time_begin_limit)) {
  197. throw new AppException('商品(' . $this->goods->title . ')将于' . $this->time_begin_limit->toDateTimeString() . '开启限时购买');
  198. }
  199. if (Carbon::now()->greaterThanOrEqualTo($this->time_end_limit)) {
  200. throw new AppException('商品(' . $this->goods->title . ')该商品已于' . $this->time_end_limit->toDateTimeString() . '结束限时购买');
  201. }
  202. }
  203. }
  204. /**
  205. * 商品每日购买限制
  206. * @param Member $member
  207. * @param int $num
  208. * @throws AppException
  209. */
  210. public function validateDayBuyTotalLimit($num = 1)
  211. {
  212. if ($this->day_buy_total_limit > 0) {
  213. $start_time = Carbon::today()->timestamp;
  214. $end_time = Carbon::now()->timestamp;
  215. $rang = [$start_time,$end_time];
  216. $history_num =
  217. \app\common\models\OrderGoods::select('yz_order_goods.*')
  218. ->join('yz_order', 'yz_order_goods.order_id', '=', 'yz_order.id')
  219. ->where('yz_order_goods.goods_id', $this->goods_id)
  220. ->where('yz_order.status', '!=' ,Order::CLOSE)
  221. ->whereBetween('yz_order_goods.created_at',$rang)
  222. ->sum('yz_order_goods.total');
  223. if ($history_num + $num > $this->day_buy_total_limit) {
  224. throw new AppException('商品(' . $this->goods->title . ')每日最多售出' . $this->day_buy_total_limit . '件');
  225. }
  226. }
  227. }
  228. /**
  229. * 用户单次购买限制
  230. * @param $num
  231. * @throws AppException
  232. */
  233. public function validateOneBuyLimit($num = 1)
  234. {
  235. if ($this->once_buy_limit > 0) {
  236. if ($num > $this->once_buy_limit) {
  237. throw new AppException('商品(' . $this->goods->title . ')单次最多可购买' . $this->once_buy_limit . '件');
  238. }
  239. }
  240. }
  241. /**
  242. * 用户每日购买限制
  243. * @param Member $member
  244. * @param int $num
  245. * @throws AppException
  246. */
  247. public function validateDayBuyLimit(Member $member,$num = 1)
  248. {
  249. if ($this->day_buy_limit > 0) {
  250. $start_time = Carbon::today()->timestamp;
  251. $end_time = Carbon::now()->timestamp;
  252. $rang = [$start_time,$end_time];
  253. $history_num = $member
  254. ->orderGoods()
  255. ->join('yz_order', 'yz_order_goods.order_id', '=', 'yz_order.id')
  256. ->where('yz_order_goods.goods_id', $this->goods_id)
  257. ->where('yz_order.status', '!=' ,Order::CLOSE)
  258. ->whereBetween('yz_order_goods.created_at',$rang)
  259. ->sum('yz_order_goods.total');
  260. if ($history_num + $num > $this->day_buy_limit) {
  261. throw new AppException('您今天已购买' . $history_num . '件商品(' . $this->goods->title . '),该商品每天最多可购买' . $this->day_buy_limit . '件');
  262. }
  263. }
  264. }
  265. /**
  266. * 用户每周购买限制
  267. * @param Member $member
  268. * @param int $num
  269. * @throws AppException
  270. */
  271. public function validateWeekBuyLimit(Member $member,$num = 1)
  272. {
  273. if ($this->week_buy_limit > 0) {
  274. $start_time = Carbon::now()->startOfWeek()->timestamp;
  275. $end_time = Carbon::now()->timestamp;
  276. $rang = [$start_time,$end_time];
  277. $history_num = $member
  278. ->orderGoods()
  279. ->join('yz_order', 'yz_order_goods.order_id', '=', 'yz_order.id')
  280. ->where('yz_order_goods.goods_id', $this->goods_id)
  281. ->where('yz_order.status', '!=' ,Order::CLOSE)
  282. ->whereBetween('yz_order_goods.created_at',$rang)
  283. ->sum('yz_order_goods.total');
  284. if ($history_num + $num > $this->week_buy_limit) {
  285. throw new AppException('您这周已购买' . $history_num . '件商品(' . $this->goods->title . '),该商品每周最多可购买' . $this->week_buy_limit . '件');
  286. }
  287. }
  288. }
  289. /**
  290. * 用户每月购买限制
  291. * @param Member $member
  292. * @param int $num
  293. * @throws AppException
  294. */
  295. public function validateMonthBuyLimit(Member $member,$num = 1)
  296. {
  297. if ($this->month_buy_limit > 0) {
  298. $start_time = Carbon::now()->startOfMonth()->timestamp;
  299. $end_time = Carbon::now()->timestamp;
  300. $range = [$start_time,$end_time];
  301. // 购买限制不查询关闭的订单
  302. // $orderIds = Order::select(['id', 'uid', 'status', 'created_at'])
  303. // ->where('uid', $member->uid)
  304. // ->where('status', '!=' ,Order::CLOSE)
  305. // ->whereBetween('created_at',$range)
  306. // ->pluck('id');
  307. //
  308. // $history_num = $member
  309. // ->orderGoods()
  310. // ->where('goods_id', $this->goods_id)
  311. // ->whereBetween('created_at',$range)
  312. // ->whereIn('order_id', $orderIds)
  313. // ->sum('total');
  314. $history_num = $member
  315. ->orderGoods()
  316. ->join('yz_order', 'yz_order_goods.order_id', '=', 'yz_order.id')
  317. ->where('yz_order_goods.goods_id', $this->goods_id)
  318. ->where('yz_order.status', '!=' ,Order::CLOSE)
  319. ->whereBetween('yz_order_goods.created_at',$range)
  320. ->sum('yz_order_goods.total');
  321. if ($history_num + $num > $this->month_buy_limit) {
  322. throw new AppException('您这个月已购买' . $history_num . '件商品(' . $this->goods->title . '),该商品每月最多可购买' . $this->month_buy_limit . '件');
  323. }
  324. }
  325. }
  326. /**
  327. * 用户购买总数限制
  328. * @param Member $member
  329. * @param int $num
  330. * @throws AppException
  331. */
  332. public function validateTotalBuyLimit(Member $member,$num = 1)
  333. {
  334. if ($this->total_buy_limit > 0) {
  335. $history_num = $member->orderGoods()
  336. ->join('yz_order', 'yz_order_goods.order_id', '=', 'yz_order.id')
  337. ->where('yz_order_goods.goods_id', $this->goods_id)
  338. ->where('yz_order.status', '!=' ,Order::CLOSE)
  339. ->sum('yz_order_goods.total');
  340. if ($history_num + $num > $this->total_buy_limit) {
  341. throw new AppException('您已购买' . $history_num . '件商品(' . $this->goods->title . '),最多可购买' . $this->total_buy_limit . '件');
  342. }
  343. }
  344. // if ($this->total_buy_limit > 0) {
  345. // $history_num = $member
  346. // ->orderGoods()
  347. // ->leftJoin('yz_order', 'yz_order.id', '=', 'order_id')
  348. // ->where('goods_id', $this->goods_id)
  349. // ->where('yz_order.status','!=' ,Order::CLOSE)
  350. // ->sum('total');
  351. // }
  352. }
  353. /**
  354. * 用户等级限制
  355. * @param Member $member
  356. * @throws AppException
  357. */
  358. public function validateMemberLevelLimit(Member $member)
  359. {
  360. if (empty($this->buy_levels) && $this->buy_levels !== '0') {
  361. return;
  362. }
  363. $buy_levels = explode(',', $this->buy_levels);
  364. if ($this->buy_levels !== '0') {
  365. $level_names = MemberLevel::select(DB::raw('group_concat(level_name) as level_name'))->whereIn('id', $buy_levels)->value('level_name');
  366. if (empty($level_names)) {
  367. return;
  368. }
  369. }
  370. if (!in_array($member->yzMember->level_id, $buy_levels)) {
  371. $ordinaryMember = in_array('0', $buy_levels)? '普通会员 ':'';
  372. throw new AppException('商品(' . $this->goods->title . ')仅限' . $ordinaryMember.$level_names . '购买');
  373. }
  374. }
  375. /**
  376. * 用户组限购
  377. * @param Member $member
  378. * @throws AppException
  379. */
  380. public function validateMemberGroupLimit(Member $member)
  381. {
  382. if (empty($this->buy_groups)) {
  383. return;
  384. }
  385. $buy_groups = explode(',', $this->buy_groups);
  386. $group_names = MemberGroup::select(DB::raw('group_concat(group_name) as level_name'))->whereIn('id', $buy_groups)->value('level_name');
  387. if (empty($group_names)) {
  388. return;
  389. }
  390. if (!in_array($member->yzMember->group_id, $buy_groups)) {
  391. throw new AppException('(' . $this->goods->title . ')该商品仅限[' . $group_names . ']购买');
  392. }
  393. }
  394. /**
  395. * 用户等級限制浏览
  396. * @param $goodsModel
  397. * @param $member
  398. * @throws AppException
  399. */
  400. public static function validatePrivilegeLevel($goodsModel, $member)
  401. {
  402. if (empty($goodsModel->hasOnePrivilege->show_levels) && $goodsModel->hasOnePrivilege->show_levels !== '0') {
  403. return;
  404. }
  405. $show_levels = explode(',', $goodsModel->hasOnePrivilege->show_levels);
  406. if (!is_array($show_levels)) {
  407. $show_levels[0] = intval($show_levels);
  408. }
  409. $level_names = MemberLevel::select(DB::raw('group_concat(level_name) as level_name'))
  410. ->whereIn('id', $show_levels)
  411. ->pluck('level_name')
  412. ->toArray();
  413. $ordinary_name = '';
  414. if(Setting::get('shop.member')['level_name'] != ''){
  415. $level_name = Setting::get('shop.member')['level_name'];
  416. $member_name = $level_name;
  417. }else{
  418. $member_name = '普通会员';
  419. }
  420. if (count($show_levels) > 1 && in_array(0, $show_levels)) {
  421. $ordinary_name = $member_name;
  422. }
  423. if (count($show_levels) == 1 && in_array(0, $show_levels)) {
  424. $level_names = [
  425. 0 => $member_name,
  426. ];
  427. }
  428. if (empty($level_names)) {
  429. return;
  430. }
  431. if (!in_array($member->level_id, $show_levels)) {
  432. throw new AppException('商品(' . $goodsModel->title . ')仅限' . $ordinary_name . implode(',', $level_names) . '浏览');
  433. }
  434. }
  435. /**
  436. * 用户组限制浏览
  437. * @param $goodsModel
  438. * @param $member
  439. * @throws AppException
  440. */
  441. public static function validatePrivilegeGroup($goodsModel, $member)
  442. {
  443. if (empty($goodsModel->hasOnePrivilege->show_groups) && $goodsModel->hasOnePrivilege->show_groups !== '0') {
  444. return;
  445. }
  446. $show_groups = explode(',', $goodsModel->hasOnePrivilege->show_groups);
  447. if ($goodsModel->hasOnePrivilege->show_groups === '0') {
  448. $group_names = '无分组';
  449. } else {
  450. $group_names = MemberGroup::select(DB::raw('group_concat(group_name) as group_name'))->whereIn('id', $show_groups)->value('group_name');
  451. if (empty($group_names)) {
  452. return;
  453. }
  454. }
  455. if (!in_array($member->group_id, $show_groups)) {
  456. throw new AppException('(' . $goodsModel->title . ')该商品仅限[' . $group_names . ']浏览');
  457. }
  458. }
  459. /**
  460. * 用户单次购买倍数限制
  461. * @param $num
  462. * @throws AppException
  463. */
  464. public function validateBuyMultipleLimit($num = 1)
  465. {
  466. //只做平台商品验证,解除限制所以商品都会验证
  467. if (intval($this->buy_multiple) > 0) {
  468. if ($num % $this->buy_multiple != 0) {
  469. throw new AppException('商品:(' . $this->goods->title . '),购买数量需为' . $this->buy_multiple . '的倍数');
  470. }
  471. }
  472. }
  473. }