diff --git a/app/common.php b/app/common.php index ba98d7f0..9ced673a 100644 --- a/app/common.php +++ b/app/common.php @@ -1207,3 +1207,26 @@ if (!function_exists('reset_index')) { } } +if (!function_exists('append_to_array')) { + /** + * 追加元素到数组 + * @param array $data + * @param array $append + * @return array + */ + function append_to_array(array $data, array $append) + { + $return = []; + foreach ($data as $item) { + if (isset($append['relation'])) { + $item[$append['value']] = $append['relation'][$item[$append['field']]]; + } else { + $item[$append['value']] = $item[$append['field']]; + } + $return[] = $item; + } + return $return; + } +} + + diff --git a/app/common/model/store/coupon/StoreCouponDetail.php b/app/common/model/store/coupon/StoreCouponDetail.php index 878b6bfd..fc108c7f 100644 --- a/app/common/model/store/coupon/StoreCouponDetail.php +++ b/app/common/model/store/coupon/StoreCouponDetail.php @@ -11,6 +11,9 @@ use app\common\model\BaseModel; class StoreCouponDetail extends BaseModel { + protected $json = ['extra']; + protected $jsonAssoc = true; + const TYPE_EXPEND = 1; //支出 const TYPE_INCOME = 2; //收入 const STATUS_VALID = 1; //有效的 diff --git a/app/common/repositories/store/coupon/StoreCouponRepository.php b/app/common/repositories/store/coupon/StoreCouponRepository.php index 7332ca7a..2a6af855 100644 --- a/app/common/repositories/store/coupon/StoreCouponRepository.php +++ b/app/common/repositories/store/coupon/StoreCouponRepository.php @@ -17,6 +17,7 @@ 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\model\store\coupon\StoreCouponUser; use app\common\repositories\BaseRepository; use app\common\repositories\store\product\ProductRepository; use app\common\repositories\store\StoreCategoryRepository; @@ -48,7 +49,7 @@ class StoreCouponRepository extends BaseRepository const TYPE_STORE_ALL = 0; //店铺商品券 const TYPE_STORE_PRODUCT = 1; - //店铺现金抵扣券,可结余,通过购买商品获得 + //店铺现金抵扣券,可结余,通过购买平台购物卡获得 const TYPE_STORE_COUPON = 2; //店铺现金抵扣券,可结余,通过销售补贴获得 const TYPE_SALE_SUBSIDY = 3; @@ -338,6 +339,61 @@ class StoreCouponRepository extends BaseRepository public function preSendCoupon(StoreCoupon $coupon, $uid, $type = 'send') { $data = $this->createData($coupon, $uid, $type); + +// $title = StoreCouponRepository::TYPE_MAP[$type]; +// $model = StoreCouponUser::where('uid', $uid)->where('type', StoreCouponRepository::TYPE_STORE_COUPON)->find(); +// $couponPrice = bcmul($amount, $rate, 2); +// if (!empty($model) && $model['type'] == $type) { +// if (!$this->onlyBill) { +// $model->coupon_price = bcadd($model->coupon_price, $couponPrice, 2); +// $model->balance = bcadd($model->balance, $couponPrice, 2); +// if ($model->status != StoreConsumptionUser::STATUS_UNUSED) { +// $model->status = StoreConsumptionUser::STATUS_UNUSED; +// } +// } +// } else { +// $model = new StoreConsumptionUser(); +// $model->coupon_id = $consumption['coupon_id']; +// $model->uid = $userId; +// $model->coupon_title = $title; +// $model->order_id_set = $groupOrderIds; +// $model->coupon_price = $couponPrice; +// $model->balance = $model->coupon_price; +// $model->order_amount = $amount; +// $model->create_time = date('Y-m-d H:i:s'); +// $model->start_time = $this->startTime ?: date('Y-m-d H:i:s', time() + 7 * 86400); +// $model->end_time = $this->endTime ?: '2026-01-15 23:59:59'; +// $model->type = $type; +// $model->status = $status; +// if ($this->onlyBill === true) { +// $model->status = StoreConsumptionUser::STATUS_REPEAL; +// } +// } +// if (!$model->save()) { +// throw new \Exception('发放失败'); +// } +// // 写入红包日志 +// /** @var $userBillRepository UserBillRepository */ +// $userBillRepository = app()->make(UserBillRepository::class); +// $extra = ['order_amount' => $amount, 'coupon_user_id' => $model['coupon_user_id']]; +// if ($this->orderType == 2) { +// $extra['order_id'] = $groupOrderIds; +// } else { +// $extra['group_order_id'] = $groupOrderIds; +// } +// if (!empty($this->billExtra)) { +// $extra = array_merge($extra, $this->billExtra); +// } +// $userBillRepository->incBill($userId, 'red_pack', "red_pack_{$type}", [ +// 'link_id' => $model['coupon_user_id'], +// 'status' => $status == -1 ?: 1, +// 'title' => '获得' . $title, +// 'number' => $couponPrice, +// 'mark' => '获得' . $title . $couponPrice . ",订单金额:{$amount}", +// 'extra' => json_encode($extra, JSON_UNESCAPED_UNICODE), +// 'balance' => 0 +// ]); + return app()->make(StoreCouponUserRepository::class)->create($data); } diff --git a/app/controller/admin/system/financial/Subsidy.php b/app/controller/admin/system/financial/Subsidy.php new file mode 100644 index 00000000..ca17cda5 --- /dev/null +++ b/app/controller/admin/system/financial/Subsidy.php @@ -0,0 +1,58 @@ +getPage(); + $query = StoreCouponDetail::where('status', StoreCouponDetail::STATUS_INVALID) + ->where('type', StoreCouponDetail::TYPE_INCOME); + $count = $query->count(); + $list = $query->page($page, $limit)->order('id desc')->select()->toArray(); + $append = ['field' => 'send_status', 'value' => 'send_status_name', 'relation' => StoreCouponDetail::SEND_STATUS_MAP]; + $list = append_to_array($list, $append); + return app('json')->success(['count' => $count, 'list'=> $list]); + } + + public function status($id) + { + $data = StoreCouponDetail::find($id); + if (empty($data)) { + return app('json')->fail('数据不存在'); + } + if ($data['status'] != StoreCouponDetail::SEND_AUDIT) { + return app('json')->fail('当前状态不支持操作'); + } + $data->status = StoreCouponDetail::SEND_CONFIRM; + $data->save(); + return app('json')->success('审核完成'); + } + + public function update($id) + { + $amount = $this->request->post('amount'); + $data = StoreCouponDetail::find($id); + if (empty($data)) { + return app('json')->fail('数据不存在'); + } + if ($data['status'] != StoreCouponDetail::SEND_AUDIT) { + return app('json')->fail('当前状态不支持操作'); + } + $data->amount = max($amount, 0); + $data->save(); + return app('json')->success('审核完成'); + } + +} diff --git a/app/event.php b/app/event.php index 3df7b9fe..84bdd715 100644 --- a/app/event.php +++ b/app/event.php @@ -56,7 +56,7 @@ return [ \crmeb\listens\SendSvipCouponListen::class, \crmeb\listens\SyncMerchantMarginStatusListen::class, \crmeb\listens\SyncQueueStatusListen::class, -// \crmeb\listens\ActivateCouponListen::class, + \crmeb\listens\ActivateCouponListen::class, \crmeb\listens\SetProductProfitRateListen::class, \crmeb\listens\SendSubsidyCouponListen::class, ] : [], diff --git a/crmeb/listens/ActivateCouponListen.php b/crmeb/listens/ActivateCouponListen.php index c4fadb1a..7bf875d0 100644 --- a/crmeb/listens/ActivateCouponListen.php +++ b/crmeb/listens/ActivateCouponListen.php @@ -2,16 +2,14 @@ namespace crmeb\listens; -use app\common\dao\store\order\StoreOrderDao; use app\common\model\store\coupon\StoreCoupon; use app\common\model\store\coupon\StoreCouponDetail; use app\common\model\store\coupon\StoreCouponUser; -use app\common\model\store\order\StoreOrder; use app\common\model\system\merchant\Merchant; use app\common\repositories\store\coupon\StoreCouponRepository; -use app\common\repositories\store\coupon\StoreCouponUserRepository; use crmeb\interfaces\ListenerInterface; use crmeb\services\TimerService; +use think\db\Query; use think\facade\Log; /** @@ -22,35 +20,47 @@ class ActivateCouponListen extends TimerService implements ListenerInterface public function handle($event): void { - $this->tick(1000 * 60, function () { + $this->tick(1000 * 60 * 60, function () { Log::info('定时任务:激活商户补贴'); try { - $couponId = StoreCoupon::where('type', StoreCouponRepository::TYPE_STORE_COUPON) - ->where('send_type', StoreCouponRepository::GET_COUPON_TYPE_PAY) - ->value('coupon_id'); - if (empty($couponId)) { - return; - } - $storeCouponUser = StoreCouponUser::where('coupon_id', $couponId) - ->where('coupon_type', StoreCouponRepository::TYPE_STORE_COUPON) - ->where('type', StoreCouponUserRepository::SEND_TYPE_BUY) - ->where('status', StoreCouponUserRepository::STATUS_REPEAL) - ->select(); - foreach ($storeCouponUser as $item) { - $mainCouponId = StoreCouponDetail::where('order_id', $item['order_id']) - ->where('type', StoreCouponDetail::TYPE_INCOME) - ->value('coupon_user_id'); - $couponBalance = StoreCouponUser::where('coupon_user_id', $mainCouponId)->value('coupon_price'); - $merchantId = Merchant::where('uid', $item['uid'])->value('mer_id'); - $saleTotal = StoreOrder::where('mer_id', $merchantId) - ->whereIn('status', [StoreOrderDao::ORDER_STATUS_REPLY, StoreOrderDao::ORDER_STATUS_SUCCESS]) - ->sum('total_price'); - if ($saleTotal >= $item['origin_price'] && $couponBalance <= 0) { - $item->status = StoreCouponUserRepository::STATUS_UNUSED; - $item->start_time = date('Y-m-d H:i:s'); - $item->end_time = date('Y-m-d H:i:s', strtotime('+1 year')); - $item->save(); - StoreCouponDetail::where('coupon_user_id', $item['coupon_user_id'])->update(['status', 1]); + //每月1号,更新所有未激活的优惠券为审核中 + if (date('d H:i:s') == '01 00:00:00') { + $list = StoreCouponDetail::with(['coupon' => function (Query $query) { + $query->field('coupon_id,type'); + }])->where('status', StoreCouponDetail::STATUS_INVALID) + ->where('send_status', StoreCouponDetail::SEND_REPEAL) + ->limit(100)->select(); + $platformCardId = StoreCoupon::where('type', StoreCouponRepository::TYPE_PLATFORM_CARD)->value('coupon_id'); + foreach ($list as $item) { + if (!in_array($item['coupon']['type'], [StoreCouponRepository::TYPE_STORE_COUPON, StoreCouponRepository::TYPE_SALE_SUBSIDY])) { + continue; + } + $merchant = Merchant::where('uid', $item['uid'])->field('mer_id,sale_amount,purchase_amount,official_purchase_amount')->find(); + if (empty($merchant)) { + continue; + } + if ($item['coupon']['type'] == StoreCouponRepository::TYPE_STORE_COUPON) { + $userCoupon = StoreCouponUser::where('coupon_id', $platformCardId) + ->where('uid', $item['uid']) + ->where('coupon_price', 0) + ->field('coupon_price,origin_price')->find(); + if (empty($userCoupon)) { + continue; + } + $saleTarget = $userCoupon['origin_price']; + $purchaseTarget = bcmul($saleTarget, 0.4, 2); + $officialPurchaseTarget = bcmul($saleTarget, 0.6, 2); + } else { + $saleTarget = $item['extra']['amount']; + $purchaseTarget = bcmul($saleTarget, 0.2, 2); + $officialPurchaseTarget = bcmul($saleTarget, 0.3, 2); + } + if ($merchant['sale_amount'] >= $saleTarget && + $merchant['purchase_amount'] >= $purchaseTarget && + $merchant['official_purchase_amount'] >= $officialPurchaseTarget) { + $item->send_status = StoreCouponDetail::SEND_AUDIT; + $item->save(); + } } } } catch (\Throwable $e) { diff --git a/crmeb/listens/SendSubsidyCouponListen.php b/crmeb/listens/SendSubsidyCouponListen.php index 4a8eefcf..0e9ade18 100644 --- a/crmeb/listens/SendSubsidyCouponListen.php +++ b/crmeb/listens/SendSubsidyCouponListen.php @@ -44,6 +44,7 @@ class SendSubsidyCouponListen extends TimerService implements ListenerInterface /** @var StoreCouponRepository $repo */ $repo = app()->make(StoreCouponRepository::class); $coupon->coupon_price = $amount; + $repo->status = StoreCouponUser::STATUS_REPEAL; $couponUser = $repo->sendCoupon($coupon, $merchant->uid, StoreCouponUserRepository::SEND_TYPE_SEND); $order = [ 'uid' => $merchant['uid'], diff --git a/route/admin/subsidy.php b/route/admin/subsidy.php new file mode 100644 index 00000000..642eb96b --- /dev/null +++ b/route/admin/subsidy.php @@ -0,0 +1,26 @@ +name('userSubsidy')->option([ + '_alias' => '补贴列表', + '_auth' => false, + '_form' => 'userSubsidyList', + ]); + })->prefix('admin.system.financial.Subsidy')->option([ + '_path' => '/cms/userSubsidy', + '_auth' => true, + ]); +})->middleware(AllowOriginMiddleware::class) + ->middleware(AdminTokenMiddleware::class, true) + ->middleware(AdminAuthMiddleware::class) + ->middleware(LogMiddleware::class);