StoreCouponRepository.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. namespace app\common\repositories\store\coupon;
  3. use app\common\dao\store\coupon\StoreCouponDao;
  4. use app\common\dao\store\coupon\StoreCouponProductDao;
  5. use app\common\model\store\coupon\StoreCoupon;
  6. use app\common\repositories\BaseRepository;
  7. use app\common\repositories\store\product\ProductRepository;
  8. use FormBuilder\Exception\FormBuilderException;
  9. use FormBuilder\Factory\Elm;
  10. use FormBuilder\Form;
  11. use think\db\exception\DataNotFoundException;
  12. use think\db\exception\DbException;
  13. use think\db\exception\ModelNotFoundException;
  14. use think\exception\ValidateException;
  15. use think\facade\Db;
  16. use think\facade\Route;
  17. /**
  18. * Class StoreCouponIssueRepository
  19. * @package app\common\repositories\store\coupon
  20. * @author zfy
  21. * @day 2020-05-13
  22. * @mixin StoreCouponDao
  23. */
  24. class StoreCouponRepository extends BaseRepository
  25. {
  26. /**
  27. * @var StoreCouponDao
  28. */
  29. protected $dao;
  30. /**
  31. * StoreCouponIssueRepository constructor.
  32. * @param StoreCouponDao $dao
  33. */
  34. public function __construct(StoreCouponDao $dao)
  35. {
  36. $this->dao = $dao;
  37. }
  38. /**
  39. * @param int $merId
  40. * @param array $where
  41. * @param $page
  42. * @param $limit
  43. * @return array
  44. * @throws DataNotFoundException
  45. * @throws DbException
  46. * @throws ModelNotFoundException
  47. * @author zfy
  48. * @day 2020-05-14
  49. */
  50. public function getList(?int $merId, array $where, $page, $limit)
  51. {
  52. $baseQuery = $this->dao->search($merId, $where)->with(['merchant' => function ($query) {
  53. $query->field('mer_id,mer_name,is_trader');
  54. }]);
  55. $count = $baseQuery->count($this->dao->getPk());
  56. $list = $baseQuery->page($page, $limit)->select();
  57. foreach ($list as $item) {
  58. $item->append(['used_num', 'send_num']);
  59. }
  60. return compact('count', 'list');
  61. }
  62. /**
  63. * @param array $data
  64. * @author zfy
  65. * @day 2020/5/26
  66. */
  67. public function create(array $data)
  68. {
  69. if (isset($data['total_count'])) $data['remain_count'] = $data['total_count'];
  70. Db::transaction(function () use ($data) {
  71. $products = array_column((array)$data['product_id'], 'id');
  72. unset($data['product_id']);
  73. if ($data['type'] == 1 && !count($products))
  74. throw new ValidateException('请选择产品');
  75. $coupon = $this->dao->create($data);
  76. if (!count($products)) return $coupon;
  77. $lst = [];
  78. foreach ($products as $product) {
  79. $lst[] = [
  80. 'product_id' => (int)$product,
  81. 'coupon_id' => $coupon->coupon_id
  82. ];
  83. }
  84. app()->make(StoreCouponProductDao::class)->insertAll($lst);
  85. });
  86. }
  87. /**
  88. * @param $id
  89. * @return Form
  90. * @throws DataNotFoundException
  91. * @throws DbException
  92. * @throws FormBuilderException
  93. * @throws ModelNotFoundException
  94. * @author zfy
  95. * @day 2020/5/26
  96. */
  97. public function cloneCouponForm($id)
  98. {
  99. $couponInfo = $this->dao->getWith($id, ['product'])->toArray();
  100. if ($couponInfo['is_timeout']) {
  101. $couponInfo['range_date'] = [$couponInfo['start_time'], $couponInfo['end_time']];
  102. }
  103. if ($couponInfo['coupon_type']) {
  104. $couponInfo['use_start_time'] = [$couponInfo['use_start_time'], $couponInfo['use_end_time']];
  105. }
  106. $couponInfo['product_id'] = [];
  107. if (count($couponInfo['product'])) {
  108. $productIds = array_column($couponInfo['product'], 'product_id');
  109. /** @var ProductRepository $make */
  110. $make = app()->make(ProductRepository::class);
  111. $products = $make->productIdByImage($couponInfo['mer_id'], $productIds);
  112. foreach ($products as $product) {
  113. $couponInfo['product_id'][] = ['id' => $product['product_id'], 'src' => $product['image']];
  114. }
  115. }
  116. $couponInfo['use_type'] = $couponInfo['use_min_price'] > 0 ? 1 : 0;
  117. return $this->form()->formData($couponInfo)->setTitle('复制优惠券');
  118. }
  119. /**
  120. * @return Form
  121. * @throws FormBuilderException
  122. * @author zfy
  123. * @day 2020/5/20
  124. */
  125. public function form()
  126. {
  127. return Elm::createForm(Route::buildUrl('merchantCouponCreate')->build(), [
  128. Elm::input('title', '优惠券名称')->required(),
  129. Elm::radio('type', '优惠券类型', 0)
  130. ->setOptions([
  131. ['value' => 0, 'label' => '店铺券'],
  132. ['value' => 1, 'label' => '商品券'],
  133. ])->control([
  134. [
  135. 'value' => 1,
  136. 'rule' => [
  137. Elm::frameImages('product_id', '商品', '/' . config('admin.merchant_prefix') . '/setting/storeProduct?field=product_id')
  138. ->width('680px')->height('480px')->modal(['modal' => false])->prop('srcKey', 'src')->required(),
  139. ]
  140. ],
  141. ]),
  142. Elm::number('coupon_price', '优惠券面值')->min(0)->precision(1)->required(),
  143. Elm::radio('use_type', ' 使用门槛', 0)
  144. ->setOptions([
  145. ['value' => 0, 'label' => '无门槛'],
  146. ['value' => 1, 'label' => '有门槛'],
  147. ])->appendControl(0, [
  148. Elm::hidden('use_min_price', 0)
  149. ])->appendControl(1, [
  150. Elm::number('use_min_price', '优惠券最低消费')->min(0)->required(),
  151. ]),
  152. Elm::radio('coupon_type', '使用有效期', 0)
  153. ->setOptions([
  154. ['value' => 0, 'label' => '天数'],
  155. ['value' => 1, 'label' => '时间段'],
  156. ])->control([
  157. [
  158. 'value' => 0,
  159. 'rule' => [
  160. Elm::number('coupon_time', ' ', 0)->min(0)->required(),
  161. ]
  162. ],
  163. [
  164. 'value' => 1,
  165. 'rule' => [
  166. Elm::dateTimeRange('use_start_time', ' ')->required(),
  167. ]
  168. ],
  169. ]),
  170. Elm::radio('is_timeout', '领取时间', 0)->options([['label' => '限时', 'value' => 1], ['label' => '不限时', 'value' => 0]])
  171. ->appendControl(1, [Elm::dateTimeRange('range_date', ' ')->placeholder('不填为永久有效')]),
  172. Elm::radio('send_type', '类型', 0)->setOptions([
  173. ['value' => 0, 'label' => '领取'],
  174. // ['value' => 1, 'label' => '消费满赠'],
  175. ['value' => 2, 'label' => '新人券'],
  176. ['value' => 3, 'label' => '赠送券']
  177. ])->appendControl(1, [Elm::number('full_reduction', '满赠金额', 0)->min(0)->placeholder('赠送优惠券的最低消费金额')]),
  178. Elm::radio('is_limited', '是否限量', 0)->options([['label' => '限量', 'value' => 1], ['label' => '不限量', 'value' => 0]])
  179. ->appendControl(1, [Elm::number('total_count', '发布数量', 0)->min(0)]),
  180. Elm::number('sort', '排序', 0),
  181. Elm::radio('status', '状态', 1)->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]),
  182. ])->setTitle('发布优惠券');
  183. }
  184. public function receiveCoupon($id, $uid)
  185. {
  186. $coupon = $this->dao->validCoupon($id, $uid);
  187. if (!$coupon)
  188. throw new ValidateException('优惠券失效');
  189. if (!is_null($coupon['issue']))
  190. throw new ValidateException('优惠券已领取');
  191. $this->sendCoupon($coupon, $uid);
  192. }
  193. public function sendCoupon(StoreCoupon $coupon, $uid, $type = 'receive')
  194. {
  195. Db::transaction(function () use ($uid, $type, $coupon) {
  196. $this->preSendCoupon($coupon, $uid, $type);
  197. app()->make(StoreCouponIssueUserRepository::class)->issue($coupon['coupon_id'], $uid);
  198. if ($coupon->is_limited) {
  199. $coupon->remain_count--;
  200. $coupon->save();
  201. }
  202. });
  203. }
  204. public function preSendCoupon(StoreCoupon $coupon, $uid, $type = 'send')
  205. {
  206. $data = $this->createData($coupon, $uid, $type);
  207. return app()->make(StoreCouponUserRepository::class)->create($data);
  208. }
  209. public function createData(StoreCoupon $coupon, $uid, $type = 'send')
  210. {
  211. $data = [
  212. 'uid' => $uid,
  213. 'coupon_title' => $coupon['title'],
  214. 'coupon_price' => $coupon['coupon_price'],
  215. 'use_min_price' => $coupon['use_min_price'],
  216. 'type' => $type,
  217. 'coupon_id' => $coupon['coupon_id'],
  218. 'mer_id' => $coupon['mer_id']
  219. ];
  220. if ($coupon['coupon_type'] == 1) {
  221. $data['start_time'] = $coupon['use_start_time'];
  222. $data['end_time'] = $coupon['use_end_time'];
  223. } else {
  224. $data['start_time'] = date('Y-m-d H:i:s');
  225. $data['end_time'] = date('Y-m-d H:i:s', strtotime("+ {$coupon['coupon_time']}day"));
  226. }
  227. return $data;
  228. }
  229. /**
  230. * TODO 优惠券发送费多用户
  231. * @param $uid
  232. * @param $id
  233. * @author Qinii
  234. * @day 2020-06-19
  235. */
  236. public function sendCouponByUser($uid, $id)
  237. {
  238. foreach ($uid as $item) {
  239. $coupon = $this->dao->validCoupon($id, $item);
  240. if (!$coupon || !is_null($coupon['issue']))
  241. continue;
  242. if ($coupon->is_limited && 0 == $coupon->remain_count)
  243. continue;
  244. $this->sendCoupon($coupon, $item);
  245. }
  246. }
  247. }