BargainActive.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <?php
  2. namespace addons\Bargain\common\models;
  3. use addons\Bargain\common\enums\BargainEnum;
  4. use addons\GroupBuy\common\enums\GroupBuyEnum;
  5. use addons\GroupBuy\common\models\GroupBuyActiveGoodsAttr;
  6. use common\enums\StatusEnum;
  7. use common\models\base\BaseActiveRecord;
  8. use common\models\goods\Goods;
  9. use common\models\goods\GoodsAttr;
  10. use common\models\goods\GoodsMarketing;
  11. use Yii;
  12. /**
  13. * This is the model class for table "qimall_addons_bargain_active".
  14. *
  15. * @property int $id
  16. * @property int $cate_id 分类
  17. * @property int $goods_id
  18. * @property int $attr_id
  19. * @property int $mall_id
  20. * @property float $min_price 最低价
  21. * @property int $begin_time 活动开始时间
  22. * @property int $end_time 活动结束时间
  23. * @property int $time 砍价小时数
  24. * @property int $type 是否允许中途下单 1--允许 2--不允许
  25. * @property int $stock 活动库存
  26. * @property string $mode_data 砍价方式数据
  27. * @property int $active_status 活动状态, 0--未开始,1--进行中, 2 -- 已结束
  28. * @property int $initiator 发起人数
  29. * @property int $participant 参与人数
  30. * @property int $min_price_goods 砍到最小价格数
  31. * @property int $underway 进行中的
  32. * @property int $success 成功的
  33. * @property int $fail 失败的
  34. * @property int $status 状态[-1:删除;0:禁用;1启用]
  35. * @property int $created_at
  36. * @property int $updated_at
  37. * @property string title
  38. */
  39. class BargainActive extends BaseActiveRecord
  40. {
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public static function tableName()
  45. {
  46. return '{{%addons_bargain_active}}';
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function rules(): array
  52. {
  53. return [
  54. [['cate_id', 'attr_id', 'goods_id', 'mall_id', 'begin_time', 'end_time', 'time', 'type', 'stock', 'active_status', 'initiator', 'participant', 'min_price_goods', 'underway', 'success', 'fail', 'status', 'created_at', 'updated_at', 'is_repeat_bargain', 'bargain_time','join_time', 'is_creator_exempt'], 'integer'],
  55. [['min_price'], 'number'],
  56. [['mode_data'], 'string', 'max' => 255],
  57. [['introduction', 'description','title'], 'string'],
  58. [['join_limit_user_level', 'bargain_limit_user_level'], 'safe'],
  59. [['title'], 'required'],
  60. ];
  61. }
  62. /**
  63. * {@inheritdoc}
  64. */
  65. public function attributeLabels(): array
  66. {
  67. return [
  68. 'id' => 'ID',
  69. 'title' => '拼团活动名称',
  70. 'cate_id' => 'cate_id',
  71. 'goods_id' => 'Goods ID',
  72. 'attr_id' => 'Attr ID',
  73. 'mall_id' => 'Mall ID',
  74. 'min_price' => '最低价',
  75. 'begin_time' => '活动开始时间',
  76. 'end_time' => '活动结束时间',
  77. 'time' => '砍价小时数',
  78. 'type' => '是否允许中途下单 1--允许 2--不允许',
  79. 'stock' => '活动库存',
  80. 'mode_data' => '砍价方式数据',
  81. 'active_status' => '活动状态,-1 -- 已结束, 0--未开始,1--进行中',
  82. 'initiator' => '发起人数',
  83. 'participant' => '参与人数',
  84. 'min_price_goods' => '砍到最小价格数',
  85. 'underway' => '进行中的',
  86. 'success' => '成功的',
  87. 'fail' => '失败的',
  88. 'status' => '状态[-1:删除;0:禁用;1启用]',
  89. 'created_at' => 'Created At',
  90. 'updated_at' => 'Updated At',
  91. ];
  92. }
  93. // 关联模型
  94. public function getGoods(): \yii\db\ActiveQuery
  95. {
  96. return $this->hasOne(Goods::class, ['id' => 'goods_id']);
  97. }
  98. public function getGoodsAttr(): \yii\db\ActiveQuery
  99. {
  100. return $this->hasOne(GoodsAttr::class, ['id' => 'attr_id']);
  101. }
  102. public function getCate(): \yii\db\ActiveQuery
  103. {
  104. return $this->hasOne(BargainCate::class, ['id' => 'cate_id']);
  105. }
  106. /**
  107. * @desc:编辑
  108. * @Author: hua
  109. * @Date: 2022/1/3
  110. * @Time: 10:16
  111. * @Copyright: copyright (c) 2021 广东七件事集团
  112. * @param array $params
  113. * @return BargainActive|false
  114. */
  115. public static function setData(array $params)
  116. {
  117. $t = Yii::$app->db->beginTransaction();
  118. try {
  119. if (!empty($params['id'])) {
  120. $model = self::findOne(['id' => $params['id'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]);
  121. if (empty($model)) throw new \Exception('服务不存在或已删除');
  122. } else {
  123. $model = new self();
  124. $model->loadDefaultValues();
  125. }
  126. if(!empty($params['mode_data'])) $params['mode_data'] = json_encode($params['mode_data']);
  127. if (!empty($params['goods_id'])) {
  128. $attr = GoodsAttr::findOne(['goods_id' => $params['goods_id'], 'status' => StatusEnum::ENABLED]);
  129. $params['attr_id'] = $attr['id'] ?? 0;
  130. }
  131. if (!empty($params['active_date'][0])) $params['begin_time'] = strtotime($params['active_date'][0]);
  132. if (!empty($params['active_date'][1])) $params['end_time'] = strtotime($params['active_date'][1]);
  133. if (!$model->load($params, '')) throw new \Exception($model->getErrorMessage());
  134. if ($model->begin_time < time()) $model->active_status = BargainEnum::ACTIVE_HANDING;
  135. if ($model->end_time < time()) $model->active_status = BargainEnum::ACTIVE_FINISH;
  136. $res = $model->save();
  137. if ($res == false) throw new \Exception($model->getErrorMessage());
  138. if ($model->active_status == BargainEnum::ACTIVE_FINISH) $params['status'] = StatusEnum::DELETE;
  139. $params['marketing_id'] = $model->id;
  140. $params['marketing_type'] = BargainEnum::ADDONS_NAME;
  141. $res = GoodsMarketing::setData($params);
  142. if ($res == false) throw new \Exception($model->getErrorMessage());
  143. $t->commit();
  144. return $model;
  145. } catch (\Exception $e) {
  146. $t->rollBack();
  147. self::$static_error = $e->getMessage();
  148. return false;
  149. }
  150. }
  151. /**
  152. * @desc:失效操作
  153. * @Author: hua
  154. * @Date: 2022/1/3
  155. * @Time: 10:10
  156. * @Copyright: copyright (c) 2021 广东七件事集团
  157. * @param $params
  158. * @return bool
  159. */
  160. public static function invalidData($params): bool
  161. {
  162. $t = Yii::$app->db->beginTransaction();
  163. try {
  164. $res = BargainOrder::findOne(['bargain_active_id' => $params['id'], 'order_status' => [BargainEnum::ORDER_HANDING], 'status' => StatusEnum::ENABLED]);
  165. if ($res) throw new \Exception('该活动有会员参与中');
  166. $res = self::updateAll(['status' => StatusEnum::DISABLED, 'active_status' => BargainEnum::ACTIVE_FINISH], ['mall_id' => $params['mall_id'], 'id' => $params['id']]);
  167. if ($res == false) throw new \Exception(self::getStaticError());
  168. $params['marketing_id'] = $params['id'];
  169. $params['marketing_type'] = BargainEnum::ADDONS_NAME;
  170. $params['status'] = StatusEnum::DISABLED;
  171. $res = GoodsMarketing::setData($params);
  172. if ($res == false) throw new \Exception(GoodsMarketing::getStaticError());
  173. $t->commit();
  174. return true;
  175. } catch (\Exception $e) {
  176. $t->rollBack();
  177. self::$static_error = $e->getMessage();
  178. return false;
  179. }
  180. }
  181. /**
  182. * @desc:活动列表
  183. * @Author: hua
  184. * @Date: 2022/1/5
  185. * @Time: 15:50
  186. * @Copyright: copyright (c) 2021 广东七件事集团
  187. * @param $where
  188. * @param false $is_page
  189. * @return array
  190. */
  191. public static function getActiveList($where, $is_page = false): array
  192. {
  193. $params['where'] = $where;
  194. $params['order'] = 'status_order asc,id DESC';
  195. $params['select'] = 'id,title,goods_id,begin_time,end_time,active_status,min_price,stock,introduction,(CASE active_status WHEN 1 THEN 1 WHEN 0 THEN 2 ELSE 3 END) AS status_order';
  196. $params['with'] = [
  197. 'goods' => function ($query) {
  198. $query->where(['status' => StatusEnum::ENABLED])->select('id,goods_name,cover_pic')->with(['attr']);
  199. },
  200. ];
  201. $function = function (&$item) {
  202. $item['price'] = $item['goods']['attr'][0]['price'];
  203. $item['goods_name'] = $item['goods']['goods_name'];
  204. $item['cover_pic'] = $item['goods']['cover_pic'];
  205. $item['goods_id'] = $item['goods']['id'];
  206. $item['title'] = empty($item['title']) ? $item['goods_name'] : $item['title'];
  207. unset($item['goodsAttr']);
  208. unset($item['goods']);
  209. return $item;
  210. };
  211. if ($is_page) {
  212. $list = self::listPage($params, false);
  213. if ($list === false) return [];
  214. if (!empty($list['list'])) {
  215. foreach ($list['list'] as &$item) {
  216. $function($item);
  217. }
  218. }
  219. } else {
  220. $list = self::lists($params);
  221. if ($list === false) return [];
  222. if (!empty($list)) {
  223. foreach ($list as &$item) {
  224. $function($item);
  225. }
  226. }
  227. }
  228. return $list;
  229. }
  230. public static function getActiveListByDiy($mall_id, $post)
  231. {
  232. $where[] = ['mall_id' => $mall_id];
  233. $where[] = ['status' => StatusEnum::ENABLED];
  234. if (!empty($post['keyword'])) {
  235. $goods_list = Goods::lists(['where' => [['mall_id' => $mall_id], ['like', 'goods_name', trim($post['keyword']) . '%', false], ['status' => StatusEnum::ENABLED]], 'select' => 'id']);
  236. $goods_id_arr = array_column($goods_list, 'id');
  237. $where[] = ['goods_id' => $goods_id_arr];
  238. }
  239. $params['where'] = $where;
  240. $params['order'] = 'id DESC';
  241. $params['with'] = ['goods' => function ($query) {
  242. $query->where(['status' => StatusEnum::ENABLED]);
  243. }];
  244. $params['limit'] = 10;
  245. $params['select'] = 'id,goods_id,created_at';
  246. $list = self::listPage($params, false, true);
  247. if (!empty($list['list'])) {
  248. foreach ($list['list'] as &$item) {
  249. $item['img'] = $item['goods']['cover_pic'];
  250. $item['title'] = $item['goods']['goods_name'];
  251. $item['sales_num'] = $item['goods']['sales_num'];
  252. $item['price'] = '';
  253. $item['original_price'] = '';
  254. $item['subtitle'] = '';
  255. unset($item['goods']);
  256. unset($item['goods_id']);
  257. }
  258. }
  259. return $list;
  260. }
  261. /**
  262. * @desc:扣减规格库存
  263. * @Author: hua
  264. * @Date: 2022/1/5
  265. * @Time: 17:26
  266. * @Copyright: copyright (c) 2021 广东七件事集团
  267. * @param $mall_id
  268. * @param $active_id
  269. * @param $num
  270. * @return bool
  271. */
  272. public static function handleStock($mall_id, $active_id, $num): bool
  273. {
  274. try {
  275. $model = self::findOne(['mall_id' => $mall_id, 'id' => $active_id]);
  276. if (empty($model)) throw new \Exception('规格不存在');
  277. if (!is_int($num)) throw new \Exception('库存数量必须为整数');
  278. if ($num < 0 && $model->stock < abs($num)) throw new \Exception('库存不足');
  279. $model->stock += $num;
  280. $model->fail += 1;
  281. $res = $model->save();
  282. if ($res === false) throw new \Exception($model->getErrorMessage());
  283. return true;
  284. } catch (\Exception $e) {
  285. self::setStaticError($e->getMessage());
  286. return false;
  287. }
  288. }
  289. /**
  290. * @desc:分享砍价活动详情
  291. * @Author: hua
  292. * @Date: 2022/1/14
  293. * @Time: 17:14
  294. * @Copyright: copyright (c) 2021 广东七件事集团
  295. * @param $active_id
  296. * @param $mall_id
  297. * @return array
  298. */
  299. public static function getShareDetail($active_id, $mall_id): array
  300. {
  301. $active = self::getOne([['id' => $active_id, 'mall_id' => $mall_id]], true, ['goods']);
  302. $data['item_id'] = $active['id'];
  303. $data['price'] = $active['goods']['price'];
  304. $data['min_price'] = $active['min_price'];
  305. $data['share_title'] = $active['goods']['goods_name'];
  306. $data['share_img'] = $active['goods']['cover_pic'];
  307. return $data;
  308. }
  309. }