DepositPresaleActive.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. <?php
  2. namespace addons\DepositPresale\common\models;
  3. use addons\DepositPresale\common\enums\DepositPresaleEnum;
  4. use addons\DepositPresale\common\helpers\TimeHelper;
  5. use common\enums\OrderStatusEnum;
  6. use common\enums\StatusEnum;
  7. use common\models\base\BaseActiveRecord;
  8. use common\models\common\AddonsMarketingSetting;
  9. use common\models\goods\Goods;
  10. use common\models\goods\GoodsAttr;
  11. use common\models\goods\GoodsCollect;
  12. use common\models\goods\GoodsMarketing;
  13. use Exception;
  14. use Yii;
  15. /**
  16. * This is the model class for table "qimall_addons_deposit_presale_goods".
  17. *
  18. * @property int $id 定金预售商品活动id
  19. * @property int $mall_id 商城id
  20. * @property int $cate_id 定金预售分类
  21. * @property int $goods_id 商品id;对应goods主表
  22. * @property string $start_at 定金预售开始时间
  23. * @property string $end_at 定金预售结束时间
  24. * @property string $deposit_start_at 定金开始时间
  25. * @property string $deposit_end_at 定金结束时间
  26. * @property string $final_payment_start_at 尾款开始时间
  27. * @property string $final_payment_end_at 尾款结束时间
  28. * @property string $send_goods_start_at 发货开始时间
  29. * @property string $send_goods_end_at 发货结束时间
  30. * @property int $effective_time 定金预售有效时间(分钟)
  31. * @property int $group_size 成团人数
  32. * @property int $give_score 团长赠送积分
  33. * @property int $give_balance 团长赠送余额
  34. * @property int $virtual_group_type 虚拟成团类型【1全部 2定金预售人数大于】
  35. * @property int $virtual_group_size 虚拟成团人数
  36. * @property int $gt_group_size 定金预售人数大于N,则虚拟成团
  37. * @property int $goods_stock 定金预售库存
  38. * @property int $limit_buy_num 限制购买数量
  39. * @property string $commander_level_limit 团长等级限制
  40. * @property string $user_level_limit 团员等级限制
  41. * @property int $is_virtual 是否开启虚拟成团
  42. * @property int $group_status 定金预售商品状态;0未开始;1开团中;已结束2
  43. * @property int $total_num 已团件数
  44. * @property int $total_orders 成团订单数
  45. * @property int $total_orders_price 成团订单金额
  46. * @property int $status 状态[-1:删除;0:禁用;1启用]
  47. * @property int $created_at
  48. * @property int $updated_at
  49. * @property string $presale_name 活动名称
  50. * @property string $presale_price 预售价格
  51. * @property string $deposit_price 定金
  52. * @property string $virtual_payment_num 虚拟付款人数
  53. * @property string $virtual_paid_num 虚拟已付款人数
  54. * @property string $purchase_limit_num 限购
  55. * @property string $presale_total 预定人数
  56. * @property string $presale_rules 预售规则
  57. * @property int $shipping_days 多少天后发货
  58. * @property int $delivery_time_way 发货方式
  59. * @property int $minimum_purchase 最低起购
  60. * @property int $activity_start_at 活动开始时间
  61. * @property int $activity_end_at 活动开始时间
  62. * @property int $sales_num 销量
  63. */
  64. class DepositPresaleActive extends BaseActiveRecord
  65. {
  66. /**
  67. * {@inheritdoc}
  68. */
  69. public static function tableName()
  70. {
  71. return '{{%addons_deposit_presale_active}}';
  72. }
  73. /**
  74. * {@inheritdoc}
  75. */
  76. public function rules()
  77. {
  78. return [
  79. [['mall_id', 'cate_id', 'goods_id'], 'required'],
  80. [['mall_id', 'cate_id', 'goods_id', 'effective_time', 'group_size', 'give_score', 'give_balance', 'virtual_group_type', 'virtual_group_size', 'gt_group_size', 'goods_stock', 'limit_buy_num', 'is_virtual', 'group_status', 'total_num', 'total_orders', 'status', 'created_at', 'updated_at', 'start_at', 'end_at', 'deposit_start_at', 'deposit_end_at', 'final_payment_start_at', 'final_payment_end_at', 'send_goods_start_at', 'send_goods_end_at', 'presale_total', 'activity_start_at', 'activity_end_at', 'sales_num'], 'integer'],
  81. [['total_orders_price', 'presale_price', 'deposit_price', 'purchase_limit_num', 'shipping_days', 'delivery_time_way', 'minimum_purchase'], 'number'],
  82. [['commander_level_limit', 'user_level_limit', 'presale_name'], 'string', 'max' => 255],
  83. [['presale_rules'], 'string'],
  84. [['minimum_purchase','purchase_limit_num'], 'number','min' => 0],
  85. [['minimum_purchase','purchase_limit_num'], 'default', 'value' => 0],
  86. [['virtual_payment_num', 'virtual_paid_num'], 'number','min' => 0],
  87. [['virtual_payment_num','virtual_paid_num'], 'default', 'value' => 0],
  88. ];
  89. }
  90. /**
  91. * {@inheritdoc}
  92. */
  93. public function attributeLabels()
  94. {
  95. return [
  96. 'id' => '定金预售商品活动id',
  97. 'mall_id' => '商城id',
  98. 'cate_id' => '定金预售分类',
  99. 'goods_id' => '商品id;对应goods主表',
  100. 'start_at' => '开始时间',
  101. 'end_at' => '结束时间',
  102. 'deposit_start_at' => '定金开始时间',
  103. 'deposit_end_at' => '定金结束时间',
  104. 'final_payment_start_at' => '尾款开始时间',
  105. 'final_payment_end_at' => '尾款结束时间',
  106. 'send_goods_start_at' => '发货开始时间',
  107. 'send_goods_end_at' => '发货结束时间',
  108. 'effective_time' => '定金预售有效时间(分钟)',
  109. 'group_size' => '成团人数',
  110. 'give_score' => '团长赠送积分',
  111. 'give_balance' => '团长赠送余额',
  112. 'virtual_group_type' => '虚拟成团类型【1全部 2定金预售人数大于】',
  113. 'virtual_group_size' => '虚拟成团人数',
  114. 'gt_group_size' => '定金预售人数大于N,则虚拟成团',
  115. 'goods_stock' => '定金预售库存',
  116. 'limit_buy_num' => '限制购买数量',
  117. 'commander_level_limit' => '团长等级限制',
  118. 'user_level_limit' => '团员等级限制',
  119. 'is_virtual' => '是否开启虚拟成团',
  120. 'group_status' => '定金预售商品状态;0未开始;1开团中;已结束2',
  121. 'status' => '状态[-1:删除;0:禁用;1启用]',
  122. 'created_at' => 'Created At',
  123. 'updated_at' => 'Update At',
  124. 'presale_name' => '活动名称',
  125. 'presale_price' => '预售价',
  126. 'deposit_price' => '定金',
  127. 'virtual_payment_num' => '虚拟付款人数',
  128. 'virtual_paid_num' => '虚拟已付款人数',
  129. 'purchase_limit_num' => '限购',
  130. 'presale_rules' => '预售规则',
  131. 'presale_total' => '预定人数',
  132. 'minimum_purchase' => '最低起购',
  133. 'activity_end_at' => '活动结束时间',
  134. 'activity_start_at' => '活动开始时间',
  135. 'sales_num' => '销量',
  136. ];
  137. }
  138. // 关联模型
  139. public function getGoods()
  140. {
  141. return $this->hasOne(Goods::class, ['id' => 'goods_id']);
  142. }
  143. public function getActiveGoodsAttr()
  144. {
  145. return $this->hasMany(DepositPresaleActiveGoodsAttr::class, ['deposit_presale_active_id' => 'id'])->andWhere(['status' => [StatusEnum::ENABLED]]);
  146. }
  147. public function getCollect()
  148. {
  149. return $this->hasOne(GoodsCollect::class, ['goods_id' => 'goods_id'])->andWhere(['status' => [StatusEnum::ENABLED]]);
  150. }
  151. public function getCategory()
  152. {
  153. return $this->hasOne(DepositPresaleCate::class, ['id' => 'cate_id'])->andWhere(['status' => [StatusEnum::ENABLED]]);
  154. }
  155. public static function setData(array $params)
  156. {
  157. $t = Yii::$app->db->beginTransaction();
  158. try {
  159. $param = $params['deposit_presale_goods'];
  160. $param['mall_id'] = $params['mall_id'];
  161. if (empty($param['id'])) {
  162. $model = new self();
  163. } else {
  164. $model = self::findOne(['id' => $param['id'], ['mall_id' => $params['mall_id']]]);
  165. if (!$model) throw new Exception('活动不存在');
  166. }
  167. $model->loadDefaultValues();
  168. if (!empty($param['start_at'])) $param['start_at'] = strtotime($param['start_at']);
  169. if (!empty($param['end_at'])) $param['end_at'] = strtotime($param['end_at']);
  170. if (!empty($param['deposit_start_at'])) $param['deposit_start_at'] = strtotime($param['deposit_start_at']);
  171. if (!empty($param['deposit_end_at'])) $param['deposit_end_at'] = strtotime($param['deposit_end_at']);
  172. if (!empty($param['final_payment_start_at'])) $param['final_payment_start_at'] = strtotime($param['final_payment_start_at']);
  173. if (!empty($param['final_payment_end_at'])) $param['final_payment_end_at'] = strtotime($param['final_payment_end_at']);
  174. if (!empty($param['send_goods_start_at'])) $param['send_goods_start_at'] = strtotime($param['send_goods_start_at']);
  175. if (!empty($param['send_goods_end_at'])) $param['send_goods_end_at'] = strtotime($param['send_goods_end_at']);
  176. if (!empty($param['activity_start_at'])) $param['activity_start_at'] = strtotime($param['activity_start_at']);
  177. if (!empty($param['activity_end_at'])) $param['activity_end_at'] = strtotime($param['activity_end_at']);
  178. if ($param['is_attr'] == 1) {
  179. $param['presale_price'] = $params['form']['select_attr_groups'][0]['deposit_presale_price'];
  180. $param['deposit_price'] = $params['form']['select_attr_groups'][0]['deposit_price'];
  181. $param['goods_stock'] = array_sum(array_column($params['form']['select_attr_groups'], 'deposit_stock'));
  182. }
  183. if (!$model->load($param, '')) throw new \Exception($model->getErrorMessage()); //可能问题出在这里,没有加载进去
  184. if ($model->deposit_start_at <= time()) $model->group_status = DepositPresaleEnum::OPEN_GROUP;
  185. if ($model->deposit_start_at > time()) $model->group_status = DepositPresaleEnum::NOT_STARTED;
  186. if ($model->final_payment_end_at < time()) $model->group_status = DepositPresaleEnum::GROUP_FINISH;
  187. if ($param['is_virtual']) {
  188. if ($param['virtual_group_type'] == 1) {
  189. $model->virtual_group_size = $param['group_size'] - 1;
  190. } else {
  191. $model->virtual_group_size = $param['group_size'] - $param['gt_group_size'];
  192. }
  193. }
  194. // if(isset($params['form']['is_attr']) && $params['form']['is_attr']) $model->goods_stock = array_sum(array_column($params['form']['attr'],'stock'));
  195. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  196. $params['deposit_presale_active_id'] = $model->id;
  197. $res = DepositPresaleActiveGoodsAttr::setData($params);
  198. if ($res == false) throw new \Exception(DepositPresaleActiveGoodsAttr::getStaticError());
  199. $param['marketing_id'] = $model->id;
  200. $param['marketing_type'] = DepositPresaleEnum::ADDONS_NAME;
  201. $res = GoodsMarketing::setData($param);
  202. if ($res == false) throw new \Exception(GoodsMarketing::getStaticError());
  203. $t->commit();
  204. return $model;
  205. } catch (\Exception $e) {
  206. $t->rollBack();
  207. self::$static_error = $e->getMessage();
  208. return false;
  209. }
  210. }
  211. public static function delData($params)
  212. {
  213. $t = Yii::$app->db->beginTransaction();
  214. try {
  215. $res = DepositPresaleOrder::findOne(['deposit_presale_active_id' => $params['id'], 'order_status' => [DepositPresaleEnum::JOINING], 'status' => StatusEnum::ENABLED]);
  216. if ($res) throw new \Exception('该预售活动有用户未付尾款');
  217. $res = self::updateAll(['status' => StatusEnum::DELETE], ['mall_id' => $params['mall_id'], 'id' => $params['id']]);
  218. if ($res === false) throw new \Exception(self::getStaticError());
  219. $res = DepositPresaleActiveGoodsAttr::updateAll(['status' => StatusEnum::DELETE], ['mall_id' => $params['mall_id'], 'deposit_presale_active_id' => $params['id']]);
  220. if ($res === false) throw new \Exception(DepositPresaleActiveGoodsAttr::getStaticError());
  221. $params['marketing_id'] = $params['id'];
  222. $params['marketing_type'] = DepositPresaleEnum::ADDONS_NAME;
  223. $params['status'] = StatusEnum::DELETE;
  224. $res = GoodsMarketing::setData($params);
  225. if ($res === false) throw new \Exception(GoodsMarketing::getStaticError());
  226. $result = self::delDiyGoods($params);
  227. if ($result === false) throw new \Exception(self::getStaticError());
  228. $t->commit();
  229. return true;
  230. } catch (\Exception $e) {
  231. $t->rollBack();
  232. self::$static_error = $e->getMessage();
  233. return false;
  234. }
  235. }
  236. public static function delDiyGoods($params)
  237. {
  238. try {
  239. $setting = AddonsMarketingSetting::findOne(['mall_id' => $params['mall_id'], 'addons_name' => 'DepositPresale']);
  240. if (!$setting) return true;
  241. $content = json_decode($setting->content, true);
  242. $is_update = 0;
  243. foreach ($content as &$item) {
  244. if (!isset($item['data']['goods'])) continue;
  245. $all_goods = $item['data']['goods'];
  246. foreach ($all_goods as $k => $goods) {
  247. if ($goods['params']['id'] == $params['id']) {
  248. unset($all_goods[$k]);
  249. $is_update += 1;
  250. }
  251. }
  252. $all_goods = array_values($all_goods);
  253. $item['data']['goods'] = $all_goods ?? [];
  254. }
  255. if ($is_update <= 0) return true;
  256. $setting->content = json_encode($content);
  257. $result = $setting->save();
  258. if (!$result) throw new Exception($setting->getErrorMessage());
  259. return true;
  260. } catch (\Exception $e) {
  261. self::$static_error = $e->getMessage();
  262. return false;
  263. }
  264. }
  265. public static function getActiveListByDiy($mall_id, $post)
  266. {
  267. $where[] = ['mall_id' => $mall_id];
  268. $where[] = ['status' => StatusEnum::ENABLED];
  269. if (!empty($post['keyword'])) {
  270. $goods_list = Goods::lists(['where' => [['mall_id' => $mall_id], ['like', 'goods_name', trim($post['keyword']) . '%', false], ['status' => StatusEnum::ENABLED]], 'select' => 'id']);
  271. $goods_id_arr = array_column($goods_list, 'id');
  272. $where[] = ['goods_id' => $goods_id_arr];
  273. }
  274. $params['where'] = $where;
  275. $params['order'] = 'id DESC';
  276. $params['with'] = ['goods' => function ($query) {
  277. $query->where(['status' => StatusEnum::ENABLED]);
  278. }];
  279. $params['limit'] = 10;
  280. $params['select'] = 'id,goods_id,created_at,presale_price,deposit_price,presale_total,deposit_start_at,deposit_end_at,total_num,virtual_payment_num,virtual_paid_num';
  281. $list = DepositPresaleActive::listPage($params, false, true);
  282. if (!empty($list['list'])) {
  283. foreach ($list['list'] as &$item) {
  284. $item['img'] = $item['goods']['cover_pic'];
  285. $item['title'] = $item['goods']['goods_name'];
  286. $item['sales_num'] = $item['goods']['sales_num'];
  287. $item['deposit_start_at'] = date('Y-m-d h:i:s', $item['deposit_start_at']);
  288. $item['deposit_end_at'] = date('Y-m-d h:i:s', $item['deposit_end_at']);
  289. $item['price'] = $item['goods']['price'];
  290. $item['original_price'] = '';
  291. $item['subtitle'] = '';
  292. $item['total_num'] = $item['presale_total'];
  293. unset($item['goods']);
  294. unset($item['goods_id']);
  295. }
  296. }
  297. return $list;
  298. }
  299. public static function checkActive($id, $mall_id)
  300. {
  301. $active = self::findOne(['mall_id' => $mall_id, 'id' => $id]);
  302. if ($active->deposit_start_at < time()) $active->group_status = DepositPresaleEnum::OPEN_GROUP;
  303. if ($active->deposit_end_at < time()) $active->group_status = DepositPresaleEnum::GROUP_FINISH;
  304. $active->save();
  305. }
  306. /**
  307. * @desc:活动列表
  308. * @Author: hua
  309. * @Date: 2021/12/22
  310. * @Time: 18:41
  311. * @Copyright: copyright (c) 2021 广东七件事集团
  312. * @param $where
  313. * @param false $is_page
  314. * @return array|mixed|void
  315. */
  316. public static function getActiveList($where, $is_page = false)
  317. {
  318. $params['where'] = $where;
  319. $params['order'] = 'id DESC';
  320. $params['select'] = 'id,goods_id,start_at,end_at,group_size,total_num,group_status,presale_price,
  321. deposit_price,deposit_start_at,deposit_end_at,virtual_payment_num,virtual_paid_num';
  322. $params['with'] = [
  323. 'goods' => function ($query) {
  324. $query->where(['status' => StatusEnum::ENABLED])->select('id,goods_name,cover_pic');
  325. },
  326. 'activeGoodsAttr' => function ($query) {
  327. $query->where(['status' => StatusEnum::ENABLED])->select('attr_id,deposit_presale_active_id,deposit_presale_price,deposit_price,goods_id')
  328. ->with(['goodsAttr']);
  329. }
  330. ];
  331. $function = function (&$item) {
  332. $item['deposit_presale_price'] = $item['activeGoodsAttr'][0]['deposit_presale_price'];
  333. $item['deposit_price'] = $item['activeGoodsAttr'][0]['deposit_price'];
  334. $item['price'] = $item['activeGoodsAttr'][0]['goodsAttr']['price'];
  335. $item['sheng'] = $item['price'] > $item['deposit_presale_price'] ? $item['price'] - $item['deposit_presale_price'] : 0;
  336. $item['goods_name'] = $item['goods']['goods_name'];
  337. $item['cover_pic'] = $item['goods']['cover_pic'];
  338. $item['goods_id'] = $item['goods']['id'];
  339. $item['time_distance'] = ['days' => 0, 'hours' => 0, 'minutes' => 0, 'seconds' => 0];
  340. if ($item['group_status'] == 0) {
  341. $item['time_distance'] = TimeHelper::getTwoTimeDistance(time(), $item['deposit_start_at']);
  342. }
  343. if ($item['group_status'] == 1) {
  344. $item['time_distance'] = TimeHelper::getTwoTimeDistance(time(), $item['deposit_end_at']);
  345. }
  346. $item['deposit_start_at'] = date('Y-m-d h:i:s', $item['deposit_start_at']);
  347. $item['deposit_end_at'] = date('Y-m-d h:i:s', $item['deposit_end_at']);
  348. unset($item['activeGoodsAttr']);
  349. unset($item['goods']);
  350. return $item;
  351. };
  352. if ($is_page) {
  353. $list = DepositPresaleActive::listPage($params, false);
  354. if ($list === false) return [];
  355. if (!empty($list['list'])) {
  356. foreach ($list['list'] as &$item) {
  357. $function($item);
  358. }
  359. }
  360. } else {
  361. // $params['index']= 'id';
  362. $list = DepositPresaleActive::lists($params);
  363. if ($list === false) return [];
  364. if (!empty($list)) {
  365. foreach ($list as &$item) {
  366. $function($item);
  367. }
  368. }
  369. }
  370. return $list;
  371. }
  372. /**
  373. * @Description: 更新装修页商品预定人数
  374. * @Author: observer3
  375. * @DateTime 2022-05-27 10:06:05
  376. * @param [type] $params
  377. * @return void
  378. */
  379. public static function updateDiyGoods($params)
  380. {
  381. try {
  382. $setting = AddonsMarketingSetting::findOne(['mall_id' => $params['mall_id'], 'addons_name' => 'DepositPresale']);
  383. if (!$setting) return true;
  384. $content = json_decode($setting->content, true);
  385. $is_update = 0;
  386. foreach ($content as &$item) {
  387. if (!isset($item['data']['goods'])) continue;
  388. $all_goods = $item['data']['goods'];
  389. foreach ($all_goods as $k => &$goods) {
  390. if ($goods['params']['id'] == $params['id']) {
  391. $goods['params']['total_num'] = $params['presale_total'];
  392. $goods['params']['presale_total'] = $params['presale_total'];
  393. $is_update += 1;
  394. }
  395. }
  396. $item['data']['goods'] = $all_goods ?? [];
  397. }
  398. if ($is_update <= 0) return true;
  399. $setting->content = json_encode($content);
  400. $result = $setting->save();
  401. if (!$result) throw new Exception($setting->getErrorMessage());
  402. return true;
  403. } catch (\Exception $e) {
  404. self::$static_error = $e->getMessage();
  405. return false;
  406. }
  407. }
  408. public static function getAcitvityStatistics($mall_id){
  409. $all_activity_number = 0;
  410. $not_start_activity_number = 0;
  411. $doing_activity_number = 0;
  412. $end_activity_number = 0;
  413. $all_activity = DepositPresaleActive::find()
  414. ->where(['and', ['mall_id' => $mall_id], ['status' => StatusEnum::ENABLED]])
  415. ->select('id, group_status')
  416. ->asArray()
  417. ->all();
  418. foreach($all_activity as $item) {
  419. $all_activity_number += 1;
  420. if($item['group_status'] == DepositPresaleEnum::NOT_STARTED){
  421. $not_start_activity_number += 1;
  422. }
  423. if($item['group_status'] == DepositPresaleEnum::OPEN_GROUP){
  424. $doing_activity_number += 1;
  425. }
  426. if($item['group_status'] == DepositPresaleEnum::GROUP_FINISH){
  427. $end_activity_number += 1;
  428. }
  429. }
  430. return compact('all_activity_number', 'not_start_activity_number', 'doing_activity_number', 'end_activity_number');
  431. }
  432. }