// +---------------------------------------------------------------------- namespace app\common\repositories\store\coupon; use app\common\dao\store\coupon\StoreCouponDao; use app\common\dao\store\coupon\StoreCouponProductDao; use app\common\model\store\coupon\StoreCoupon; use app\common\repositories\BaseRepository; use app\common\repositories\store\product\ProductRepository; use FormBuilder\Exception\FormBuilderException; use FormBuilder\Factory\Elm; use FormBuilder\Form; use think\db\exception\DataNotFoundException; use think\db\exception\DbException; use think\db\exception\ModelNotFoundException; use think\exception\ValidateException; use think\facade\Db; use think\facade\Route; /** * Class StoreCouponIssueRepository * @package app\common\repositories\store\coupon * @author xaboy * @day 2020-05-13 * @mixin StoreCouponDao */ class StoreCouponRepository extends BaseRepository { /** * @var StoreCouponDao */ protected $dao; /** * StoreCouponIssueRepository constructor. * @param StoreCouponDao $dao */ public function __construct(StoreCouponDao $dao) { $this->dao = $dao; } /** * @param int $merId * @param array $where * @param $page * @param $limit * @return array * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException * @author xaboy * @day 2020-05-14 */ public function getList(?int $merId, array $where, $page, $limit) { $baseQuery = $this->dao->search($merId, $where)->with(['merchant' => function ($query) { $query->field('mer_id,mer_name,is_trader'); }]); $count = $baseQuery->count($this->dao->getPk()); $list = $baseQuery->page($page, $limit)->select(); foreach ($list as $item) { $item->append(['used_num', 'send_num']); } return compact('count', 'list'); } /** * @param array $data * @author xaboy * @day 2020/5/26 */ public function create(array $data) { if (isset($data['total_count'])) $data['remain_count'] = $data['total_count']; Db::transaction(function () use ($data) { $products = array_column((array)$data['product_id'], 'id'); unset($data['product_id']); if ($data['type'] == 1 && !count($products)) throw new ValidateException('请选择产品'); $coupon = $this->dao->create($data); if (!count($products)) return $coupon; $lst = []; foreach ($products as $product) { $lst[] = [ 'product_id' => (int)$product, 'coupon_id' => $coupon->coupon_id ]; } app()->make(StoreCouponProductDao::class)->insertAll($lst); }); } /** * @param $id * @return Form * @throws DataNotFoundException * @throws DbException * @throws FormBuilderException * @throws ModelNotFoundException * @author xaboy * @day 2020/5/26 */ public function cloneCouponForm($id) { $couponInfo = $this->dao->getWith($id, ['product'])->toArray(); if ($couponInfo['is_timeout']) { $couponInfo['range_date'] = [$couponInfo['start_time'], $couponInfo['end_time']]; } if ($couponInfo['coupon_type']) { $couponInfo['use_start_time'] = [$couponInfo['use_start_time'], $couponInfo['use_end_time']]; } $couponInfo['product_id'] = []; if (count($couponInfo['product'])) { $productIds = array_column($couponInfo['product'], 'product_id'); /** @var ProductRepository $make */ $make = app()->make(ProductRepository::class); $products = $make->productIdByImage($couponInfo['mer_id'], $productIds); foreach ($products as $product) { $couponInfo['product_id'][] = ['id' => $product['product_id'], 'src' => $product['image']]; } } $couponInfo['use_type'] = $couponInfo['use_min_price'] > 0 ? 1 : 0; return $this->form()->formData($couponInfo)->setTitle('复制优惠券'); } /** * @return Form * @throws FormBuilderException * @author xaboy * @day 2020/5/20 */ public function form() { return Elm::createForm(Route::buildUrl('merchantCouponCreate')->build(), [ Elm::input('title', '优惠券名称')->required(), Elm::radio('type', '优惠券类型', 0) ->setOptions([ ['value' => 0, 'label' => '店铺券'], ['value' => 1, 'label' => '商品券'], ])->control([ [ 'value' => 1, 'rule' => [ Elm::frameImages('product_id', '商品', '/' . config('admin.merchant_prefix') . '/setting/storeProduct?field=product_id') ->width('680px')->height('480px')->modal(['modal' => false])->prop('srcKey', 'src')->required(), ] ], ]), Elm::number('coupon_price', '优惠券面值')->min(0)->precision(1)->required(), Elm::radio('use_type', ' 使用门槛', 0) ->setOptions([ ['value' => 0, 'label' => '无门槛'], ['value' => 1, 'label' => '有门槛'], ])->appendControl(0, [ Elm::hidden('use_min_price', 0) ])->appendControl(1, [ Elm::number('use_min_price', '优惠券最低消费')->min(0)->required(), ]), Elm::radio('coupon_type', '使用有效期', 0) ->setOptions([ ['value' => 0, 'label' => '天数'], ['value' => 1, 'label' => '时间段'], ])->control([ [ 'value' => 0, 'rule' => [ Elm::number('coupon_time', ' ', 0)->min(0)->required(), ] ], [ 'value' => 1, 'rule' => [ Elm::dateTimeRange('use_start_time', ' ')->required(), ] ], ]), Elm::radio('is_timeout', '领取时间', 0)->options([['label' => '限时', 'value' => 1], ['label' => '不限时', 'value' => 0]]) ->appendControl(1, [Elm::dateTimeRange('range_date', ' ')->placeholder('不填为永久有效')]), Elm::radio('send_type', '类型', 0)->setOptions([ ['value' => 0, 'label' => '领取'], // ['value' => 1, 'label' => '消费满赠'], ['value' => 2, 'label' => '新人券'], ['value' => 3, 'label' => '赠送券'] ])->appendControl(1, [Elm::number('full_reduction', '满赠金额', 0)->min(0)->placeholder('赠送优惠券的最低消费金额')]), Elm::radio('is_limited', '是否限量', 0)->options([['label' => '限量', 'value' => 1], ['label' => '不限量', 'value' => 0]]) ->appendControl(1, [Elm::number('total_count', '发布数量', 0)->min(0)]), Elm::number('sort', '排序', 0), Elm::radio('status', '状态', 1)->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]), ])->setTitle('发布优惠券'); } public function receiveCoupon($id, $uid) { $coupon = $this->dao->validCoupon($id, $uid); if (!$coupon) throw new ValidateException('优惠券失效'); if (!is_null($coupon['issue'])) throw new ValidateException('优惠券已领取'); $this->sendCoupon($coupon, $uid); } public function sendCoupon(StoreCoupon $coupon, $uid, $type = 'receive') { Db::transaction(function () use ($uid, $type, $coupon) { $this->preSendCoupon($coupon, $uid, $type); app()->make(StoreCouponIssueUserRepository::class)->issue($coupon['coupon_id'], $uid); if ($coupon->is_limited) { $coupon->remain_count--; $coupon->save(); } }); } public function preSendCoupon(StoreCoupon $coupon, $uid, $type = 'send') { $data = $this->createData($coupon, $uid, $type); return app()->make(StoreCouponUserRepository::class)->create($data); } public function createData(StoreCoupon $coupon, $uid, $type = 'send') { $data = [ 'uid' => $uid, 'coupon_title' => $coupon['title'], 'coupon_price' => $coupon['coupon_price'], 'use_min_price' => $coupon['use_min_price'], 'type' => $type, 'coupon_id' => $coupon['coupon_id'], 'mer_id' => $coupon['mer_id'] ]; if ($coupon['coupon_type'] == 1) { $data['start_time'] = $coupon['use_start_time']; $data['end_time'] = $coupon['use_end_time']; } else { $data['start_time'] = date('Y-m-d H:i:s'); $data['end_time'] = date('Y-m-d H:i:s', strtotime("+ {$coupon['coupon_time']}day")); } return $data; } /** * TODO 优惠券发送费多用户 * @param $uid * @param $id * @author Qinii * @day 2020-06-19 */ public function sendCouponByUser($uid, $id) { foreach ($uid as $item) { $coupon = $this->dao->validCoupon($id, $item); if (!$coupon || !is_null($coupon['issue'])) continue; if ($coupon->is_limited && 0 == $coupon->remain_count) continue; $this->sendCoupon($coupon, $item); } } }