activity_helper.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 16/8/14
  6. * Time: 下午5:27
  7. */
  8. require_once (BASE_ROOT_PATH . '/helper/activity/groupbuy.php');
  9. require_once (BASE_ROOT_PATH . '/helper/activity/limitime.php');
  10. require_once (BASE_ROOT_PATH . '/helper/activity/bundling.php');
  11. require_once (BASE_ROOT_PATH . '/helper/activity/recommend_combo.php');
  12. require_once (BASE_ROOT_PATH . '/helper/activity/full_sent.php');
  13. require_once (BASE_ROOT_PATH . '/helper/activity/recommend_goods.php');
  14. require_once (BASE_ROOT_PATH . '/helper/activity/goods_gift.php');
  15. require_once (BASE_ROOT_PATH . '/helper/activity/optional_goods.php');
  16. require_once (BASE_ROOT_PATH . '/helper/activity/goods_sampler.php');
  17. require_once (BASE_ROOT_PATH . '/helper/activity/bargain_goods.php');
  18. require_once (BASE_ROOT_PATH . '/helper/algorithm.php');
  19. require_once (BASE_ROOT_PATH . '/helper/message/msgutil.php');
  20. require_once (BASE_ROOT_PATH . '/helper/activity_helper.php');
  21. function less_endtime($left,$right)
  22. {
  23. $l_end = intval($left['end_time']);
  24. $r_end = intval($right['end_time']);
  25. $l_type = intval($left['time_type']);
  26. $r_type = intval($right['time_type']);
  27. $l_actype = $left['act_type'];
  28. $r_actype = $left['act_type'];
  29. if($l_end > $r_end) {
  30. return 1;
  31. }
  32. elseif($l_end == $r_end)
  33. {
  34. if($l_type > $r_type) return 1;
  35. elseif($l_type < $r_type) return -1;
  36. else
  37. {
  38. if($l_actype > $r_actype) return 1;
  39. elseif($l_actype < $r_actype) return -1;
  40. else return 0;
  41. }
  42. }
  43. else {
  44. return -1;
  45. }
  46. }
  47. function less_startime($left,$right)
  48. {
  49. $l_start = intval($left['start_time']);
  50. $r_start = intval($right['start_time']);
  51. $l_type = intval($left['time_type']);
  52. $r_type = intval($right['time_type']);
  53. $l_actype = $left['act_type'];
  54. $r_actype = $left['act_type'];
  55. if($l_start > $r_start) {
  56. return 1;
  57. }
  58. elseif($l_start == $r_start) {
  59. if($l_type > $r_type) return 1;
  60. elseif($l_type < $r_type) return -1;
  61. else
  62. {
  63. if($l_actype > $r_actype) return 1;
  64. elseif($l_actype < $r_actype) return -1;
  65. else return 0;
  66. }
  67. }
  68. else {
  69. return -1;
  70. }
  71. }
  72. //抢,限,推,套装,三个信息会出现在商品的summary 中,其余的出现在商品的详细信息中
  73. class activity_helper
  74. {
  75. const ACTIVITY_NONE = 0;
  76. const ACTIVITY_GROUPBUY = 1; //抢
  77. const ACTIVITY_LIMITTIME = 2; //限
  78. const ACTIVITY_BUNDLING = 3; //套装
  79. public static function take_parted($goods_id,&$act_type)
  80. {
  81. if(activity\groupbuy::instance()->isTakepart($goods_id,$act_id)) { //抢购
  82. $act_type = self::ACTIVITY_GROUPBUY;
  83. return $act_id;
  84. }
  85. elseif(activity\limitime::instance()->isTakepart($goods_id,$act_id)) { //
  86. $act_type = self::ACTIVITY_LIMITTIME;
  87. return $act_id;
  88. }
  89. else {
  90. $act_type = self::ACTIVITY_NONE;
  91. return false;
  92. }
  93. }
  94. public static function have_recommend($goods_id)
  95. {
  96. if (activity\recommend_goods::instance()->isTakepart($goods_id)) {
  97. return true;
  98. } else {
  99. return false;
  100. }
  101. }
  102. public static function have_bundling($goods_id) {
  103. return activity\bundling::instance()->have_bundling($goods_id);
  104. }
  105. public static function bundling_goods($bl_id) {
  106. return activity\bundling::instance()->bundling_goods($bl_id);
  107. }
  108. //赠品信息
  109. public static function have_gift($goods_id) {
  110. return activity\goods_gift::instance()->have_gift($goods_id);
  111. }
  112. public static function goods_gifts($goods_id) {
  113. return activity\goods_gift::instance()->gifts($goods_id);
  114. }
  115. public static function goods_giftids($goods_id) {
  116. return activity\goods_gift::instance()->goods_giftids($goods_id);
  117. }
  118. //商品组合
  119. public static function have_combo($goods_id) {
  120. return activity\recommend_combo::instance()->have_combo($goods_id);
  121. }
  122. public static function combo_goods($goods_id) {
  123. return activity\recommend_combo::instance()->combo_goods($goods_id);
  124. }
  125. //满赠活动
  126. public static function fullsent_rules() {
  127. return activity\full_sent::instance()->rules();
  128. }
  129. //包邮信息
  130. public static function free_ship() {
  131. return activity\full_sent::instance()->free_price();
  132. }
  133. //推荐商品列表
  134. public static function recomoned_goodsids()
  135. {
  136. return activity\recommend_goods::instance()->goods_ids();
  137. }
  138. public static function limit_goods($limit_id)
  139. {
  140. return activity\limitime::instance()->goods($limit_id);
  141. }
  142. public static function groupbuy_goods($group_id)
  143. {
  144. return activity\groupbuy::instance()->goods($group_id);
  145. }
  146. public static function acting()
  147. {
  148. $limits = activity\limitime::instance()->acting();
  149. $groupbuys = activity\groupbuy::instance()->acting();
  150. $values = [];
  151. foreach ($limits as $val) {
  152. $val['time_type'] = $val['xianshi_type'];
  153. $val['act_type'] = 1;
  154. $values[] = $val;
  155. }
  156. foreach ($groupbuys as $val) {
  157. $val['time_type'] = $val['groupbuy_type'];
  158. $val['act_type'] = 2;
  159. $values[] = $val;
  160. }
  161. $result = [];
  162. if(!empty($values))
  163. {
  164. uasort($values,'less_endtime');
  165. foreach ($values as $value) {
  166. $result[] = $value;
  167. }
  168. }
  169. return $result;
  170. }
  171. public static function groupbuy_price($limit_id,&$price)
  172. {
  173. return activity\groupbuy::instance()->promotion_price($limit_id,$price);
  174. }
  175. public static function limit_price($limit_id,$goods_id,&$price)
  176. {
  177. return activity\limitime::instance()->promotion_price($limit_id,$goods_id,$price);
  178. }
  179. public static function unstart()
  180. {
  181. $limits = activity\limitime::instance()->unstart();
  182. $groupbuys = activity\groupbuy::instance()->unstart();
  183. $values = [];
  184. foreach ($limits as $val) {
  185. $values[] = $val;
  186. }
  187. foreach ($groupbuys as $val) {
  188. $values[] = $val;
  189. }
  190. $result = [];
  191. if(!empty($values))
  192. {
  193. uasort($values,'less_startime');
  194. foreach ($values as $value) {
  195. $result[] = $value;
  196. }
  197. }
  198. return $result;
  199. }
  200. public static function take_part_opgoods($goods_id)
  201. {
  202. return activity\optional_goods::instance()->info($goods_id);
  203. }
  204. public static function optional_goods_check($goods_id,&$err)
  205. {
  206. if(self::take_parted($goods_id,$type)) {
  207. $err['msg'] = '该商品已经参加其它活动';
  208. return false;
  209. }
  210. elseif(self::have_bundling($goods_id)) {
  211. $err['msg'] = '该商品已经参加套装活动';
  212. return false;
  213. }
  214. return true;
  215. }
  216. public static function optional_goods_match($gids)
  217. {
  218. $result = activity\optional_goods::instance()->match($gids);
  219. return $result;
  220. }
  221. }
  222. class price_matcher
  223. {
  224. private $mGoodsNums;
  225. private $mOptions;
  226. private $mPrice;
  227. private $mRepeat;
  228. private $mGoodsList;
  229. private $mResult;
  230. public function __construct($content,$goods_list)
  231. {
  232. $goods_nums = $content['goods_nums'];
  233. $this->mOptions = $content['options'];
  234. $this->mPrice = $content['price'];
  235. $this->mRepeat = $content['repeat'];
  236. $this->mGoodsList = [];
  237. $goodses = [];
  238. foreach ($goods_nums as $gid => $num) {
  239. $this->mGoodsList[$gid] = $goods_list[$gid];
  240. $goodses[] = $goods_list[$gid];
  241. }
  242. usort($goodses,['optional_match','price_desc']);
  243. $this->mGoodsNums = [];
  244. foreach($goodses as $val) {
  245. $goods_id = intval($val['goods_id']);
  246. $this->mGoodsNums[$goods_id] = $goods_nums[$goods_id];
  247. }
  248. $this->mResult = false;
  249. }
  250. public function match(&$total_price_cent)
  251. {
  252. if($this->mRepeat) {
  253. $match_goods = $this->repeat();
  254. }
  255. else {
  256. $match_goods = $this->nonrepeat();
  257. }
  258. if(empty($match_goods)) {
  259. $total_price_cent = 0;
  260. return false;
  261. }
  262. else {
  263. $total_count = $this->goods_count($match_goods);
  264. $total_price_cent = $this->mPrice * ($total_count / $this->mOptions);
  265. return $match_goods;
  266. }
  267. }
  268. private function repeat()
  269. {
  270. $match_goods = [];
  271. $goods_num = $this->mGoodsNums;
  272. while ($this->goods_count($goods_num) >= $this->mOptions)
  273. {
  274. $left = $this->mOptions;
  275. foreach($goods_num as $gid => &$num)
  276. {
  277. if($left > $num) {
  278. $sel = $num;
  279. } else {
  280. $sel = $left;
  281. }
  282. if(array_key_exists($gid,$match_goods)) {
  283. $match_goods[$gid] += $sel;
  284. } else {
  285. $match_goods[$gid] = $sel;
  286. }
  287. $left -= $sel;
  288. $num -= $sel;
  289. if($num == 0) {
  290. unset($goods_num[$gid]);
  291. }
  292. if($left == 0) {
  293. break;
  294. }
  295. }
  296. }
  297. return $match_goods;
  298. }
  299. private function goods_count($goods_nums)
  300. {
  301. $count = 0;
  302. foreach ($goods_nums as $gid => $num) {
  303. $count += $num;
  304. }
  305. return $count;
  306. }
  307. private function nonrepeat()
  308. {
  309. $match_goods = [];
  310. $goods_num = $this->mGoodsNums;
  311. while (count($goods_num) >= $this->mOptions)
  312. {
  313. $i = 0;
  314. foreach($goods_num as $gid => &$num)
  315. {
  316. if($i < $this->mOptions)
  317. {
  318. if(array_key_exists($gid,$match_goods)) {
  319. $match_goods[$gid] += 1;
  320. } else {
  321. $match_goods[$gid] = 1;
  322. }
  323. ++$i;
  324. --$num;
  325. if($num == 0) {
  326. unset($goods_num[$gid]);
  327. }
  328. }
  329. else {
  330. break;
  331. }
  332. }
  333. }
  334. return $match_goods;
  335. }
  336. }
  337. class optional_match
  338. {
  339. private $mPregids;
  340. private $mAllGoods;
  341. public function __construct($cart_list)
  342. {
  343. $this->mPregids = [];
  344. $this->mAllGoods = [];
  345. foreach ($cart_list as $cart)
  346. {
  347. $bl_id = intval($cart['bl_id']);
  348. $goods_id = intval($cart['goods_id']);
  349. $goods_num = intval($cart['goods_num']);
  350. if($bl_id == 0 && $goods_id > 0)
  351. {
  352. $this->mPregids[$goods_id] = $goods_num;
  353. $this->mAllGoods[$goods_id] = $cart;
  354. }
  355. }
  356. }
  357. public function match()
  358. {
  359. if(!empty($this->mPregids)) {
  360. $matchs = activity\optional_goods::instance()->match($this->mPregids);
  361. if($matchs == false) return false;
  362. }
  363. else {
  364. return false;
  365. }
  366. $discount_cent = 0;
  367. $goods_nums = [];
  368. $total_cent = 0;
  369. foreach ($matchs as $item)
  370. {
  371. $matcher = new price_matcher($item,$this->mAllGoods);
  372. $match_goods = $matcher->match($total_oprice_cent);
  373. if(!empty($match_goods))
  374. {
  375. $total_price = $this->total_price_cent($match_goods);
  376. $total_cent += $total_price;
  377. $discount_cent += $total_price - $total_oprice_cent;
  378. foreach ($match_goods as $gid => $num) {
  379. $goods_nums[$gid] = $num;
  380. }
  381. }
  382. }
  383. return ['total_amount' => $total_cent / 100,'discount' => $discount_cent / 100, 'goods_nums' => $goods_nums];
  384. }
  385. private function total_price_cent($match_goods)
  386. {
  387. $total_price = 0;
  388. foreach ($match_goods as $gid => $num) {
  389. $total_price += intval($this->mAllGoods[$gid]['goods_price'] * 100 * $num + 0.5);
  390. }
  391. return $total_price;
  392. }
  393. public static function price_desc($left,$right)
  394. {
  395. $l_price = intval($left['goods_price'] * 100 + 0.5);
  396. $r_price = intval($right['goods_price'] * 100 + 0.5);
  397. if($l_price > $r_price) return -1;
  398. elseif($l_price < $r_price) return 1;
  399. else return 0;
  400. }
  401. }