first commit

This commit is contained in:
2026-04-15 20:16:52 +08:00
commit 8f45044411
1172 changed files with 329978 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Models\Carmis;
class CarmisService
{
/**
* 通过商品查询一些数量未使用的卡密
*
* @param int $goodsID 商品id
* @param int $byAmount 数量
* @return array|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function withGoodsByAmountAndStatusUnsold(int $goodsID, int $byAmount)
{
$carmis = Carmis::query()
->where('goods_id', $goodsID)
->where('status', Carmis::STATUS_UNSOLD)
->take($byAmount)
->get();
return $carmis ? $carmis->toArray() : null;
}
/**
* 通过id集合设置卡密已售出
*
* @param array $ids 卡密id集合
* @return bool
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function soldByIDS(array $ids): bool
{
return Carmis::query()->whereIn('id', $ids)->where('is_loop', 0)->update(['status' => Carmis::STATUS_SOLD]);
}
}
+80
View File
@@ -0,0 +1,80 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Models\Coupon;
class CouponService
{
/**
* 获得优惠码,通过商品关联
*
* @param string $coupon 优惠码
* @param int $goodsID 商品id
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function withHasGoods(string $coupon, int $goodsID)
{
$coupon = Coupon::query()->whereHas('goods', function ($query) use ($goodsID) {
$query->where('goods_id', $goodsID);
})->where('is_open', Coupon::STATUS_OPEN)->where('coupon', $coupon)->first();
return $coupon;
}
/**
* 设置优惠券已使用
* @param string $coupon
* @return bool
*/
public function used(string $coupon): bool
{
return Coupon::query()
->where('coupon', $coupon)
->update(['is_use' => Coupon::STATUS_USE]);
}
/**
* 设置优惠券使用次数 -1
* @param string $coupon
* @return int
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function retDecr(string $coupon)
{
return Coupon::query()
->where('coupon', $coupon)
->decrement('ret', 1);
}
/**
* 设置优惠券次数+1
*
* @param int $id
* @return int
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function retIncrByID(int $id)
{
return Coupon::query()->where('id', $id)->increment('ret', 1);
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Models\Emailtpl;
class EmailtplService
{
/**
* 通过邮件标识获得邮件模板
*
* @param string $token 邮件标识
* @return Emailtpl
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function detailByToken(string $token): Emailtpl
{
$tpl = Emailtpl::query()->where('tpl_token', $token)->first();
return $tpl;
}
}
+152
View File
@@ -0,0 +1,152 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Exceptions\RuleValidationException;
use App\Models\Carmis;
use App\Models\Goods;
use App\Models\GoodsGroup;
/**
* 商品服务层
*
* Class GoodsService
* @package App\Service
* @author: Assimon
* @email: Ashang@utf8.hk
* @blog: https://utf8.hk
* Date: 2021/5/30
*/
class GoodsService
{
/**
* 获取所有分类并加载该分类下的商品
*
* @return array|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function withGroup(): ?array
{
$goods = GoodsGroup::query()
->with(['goods' => function($query) {
$query->withCount(['carmis' => function($query) {
$query->where('status', Carmis::STATUS_UNSOLD);
}])->where('is_open', Goods::STATUS_OPEN)->orderBy('ord', 'DESC');
}])
->where('is_open', GoodsGroup::STATUS_OPEN)
->orderBy('ord', 'DESC')
->get();
// 将自动
return $goods ? $goods->toArray() : null;
}
/**
* 商品详情
*
* @param int $id 商品id
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function detail(int $id)
{
$goods = Goods::query()
->with(['coupon'])
->withCount(['carmis' => function($query) {
$query->where('status', Carmis::STATUS_UNSOLD);
}])->where('id', $id)->first();
return $goods;
}
/**
* 格式化商品信息
*
* @param Goods $goods 商品模型
* @return Goods
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function format(Goods $goods)
{
// 格式化批发配置以及输入框配置
$goods->wholesale_price_cnf = $goods->wholesale_price_cnf ?
format_wholesale_price($goods->wholesale_price_cnf) :
null;
// 如果存在其他配置输入框且为代充
$goods->other_ipu = $goods->other_ipu_cnf ?
format_charge_input($goods->other_ipu_cnf) :
null;
return $goods;
}
/**
* 验证商品状态
*
* @param Goods $goods
* @return Goods
* @throws RuleValidationException
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function validatorGoodsStatus(Goods $goods): Goods
{
if (empty($goods)) {
throw new RuleValidationException(__('dujiaoka.prompt.goods_does_not_exist'));
}
// 上架判断.
if ($goods->is_open != Goods::STATUS_OPEN) {
throw new RuleValidationException(__('dujiaoka.prompt.the_goods_is_not_on_the_shelves'));
}
return $goods;
}
/**
* 库存减去
*
* @param int $id 商品id
* @param int $number 出库数量
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function inStockDecr(int $id, int $number = 1): bool
{
return Goods::query()->where('id', $id)->decrement('in_stock', $number);
}
/**
* 商品销量加
*
* @param int $id 商品id
* @param int $number 数量
* @return bool
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function salesVolumeIncr(int $id, int $number = 1): bool
{
return Goods::query()->where('id', $id)->increment('sales_volume', $number);
}
}
+526
View File
@@ -0,0 +1,526 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Exceptions\RuleValidationException;
use App\Jobs\ApiHook;
use App\Jobs\MailSend;
use App\Jobs\OrderExpired;
use App\Jobs\ServerJiang;
use App\Jobs\TelegramPush;
use App\Jobs\BarkPush;
use App\Jobs\WorkWeiXinPush;
use App\Models\BaseModel;
use App\Models\Coupon;
use App\Models\Goods;
use App\Models\Order;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
/**
* 订单处理层
*
* Class OrderProcessService
* @package App\Service
* @author: Assimon
* @email: Ashang@utf8.hk
* @blog: https://utf8.hk
* Date: 2021/5/30
*/
class OrderProcessService
{
const PENDING_CACHE_KEY = 'PENDING_ORDERS_LIST';
/**
* 优惠码服务层
* @var \App\Service\CouponService
*/
private $couponService;
/**
* 订单服务层
* @var \App\Service\OrderService
*/
private $orderService;
/**
* 卡密服务层
* @var \App\Service\CarmisService
*/
private $carmisService;
/**
* 邮件服务层
* @var \App\Service\EmailtplService
*/
private $emailtplService;
/**
* 商品服务层.
* @var \App\Service\GoodsService
*/
private $goodsService;
/**
* 商品
* @var Goods
*/
private $goods;
/**
* 优惠码
* @var Coupon;
*/
private $coupon;
/**
* 其他输入框
* @var string
*/
private $otherIpt;
/**
* 购买数量
* @var int
*/
private $buyAmount;
/**
* 购买邮箱
* @var string
*/
private $email;
/**
* 查询密码
* @var string
*/
private $searchPwd;
/**
* 下单id
* @var string
*/
private $buyIP;
/**
* 支付方式
* @var int
*/
private $payID;
public function __construct()
{
$this->couponService = app('Service\CouponService');
$this->orderService = app('Service\OrderService');
$this->carmisService = app('Service\CarmisService');
$this->emailtplService = app('Service\EmailtplService');
$this->goodsService = app('Service\GoodsService');
}
/**
* 设置支付方式
* @param int $payID
*/
public function setPayID(int $payID): void
{
$this->payID = $payID;
}
/**
* 下单ip
* @param mixed $buyIP
*/
public function setBuyIP($buyIP): void
{
$this->buyIP = $buyIP;
}
/**
* 设置查询密码
* @param mixed $searchPwd
*/
public function setSearchPwd($searchPwd): void
{
$this->searchPwd = $searchPwd;
}
/**
* 设置购买数量
* @param mixed $buyAmount
*/
public function setBuyAmount($buyAmount): void
{
$this->buyAmount = $buyAmount;
}
/**
* 设置下单邮箱
* @param mixed $email
*/
public function setEmail($email): void
{
$this->email = $email;
}
/**
* 设置商品
*
* @param Goods $goods
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function setGoods(Goods $goods)
{
$this->goods = $goods;
}
/**
* 设置优惠码.
*
* @param ?Coupon $coupon
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function setCoupon(?Coupon $coupon)
{
$this->coupon = $coupon;
}
/**
* 其他输入框设置.
*
* @param ?string $otherIpt
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function setOtherIpt(?string $otherIpt)
{
$this->otherIpt = $otherIpt;
}
/**
* 计算优惠码价格
*
* @return float
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
private function calculateTheCouponPrice(): float
{
$couponPrice = 0;
// 优惠码优惠价格
if ($this->coupon) {
$couponPrice = $this->coupon->discount;
}
return $couponPrice;
}
/**
* 计算批发优惠
* @return float
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
private function calculateTheWholesalePrice(): float
{
$wholesalePrice = 0; // 优惠单价
$wholesaleTotalPrice = 0; // 优惠总价
if ($this->goods->wholesale_price_cnf) {
$formatWholesalePrice = format_wholesale_price($this->goods->wholesale_price_cnf);
foreach ($formatWholesalePrice as $item) {
if ($this->buyAmount >= $item['number']) {
$wholesalePrice = $item['price'];
}
}
}
if ($wholesalePrice > 0 ) {
$totalPrice = $this->calculateTheTotalPrice(); // 实际原总价
$newTotalPrice = bcmul($wholesalePrice, $this->buyAmount, 2); // 批发价优惠后的总价
$wholesaleTotalPrice = bcsub($totalPrice, $newTotalPrice, 2); // 批发总优惠
}
return $wholesaleTotalPrice;
}
/**
* 订单总价
* @return float
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
private function calculateTheTotalPrice(): float
{
$price = $this->goods->actual_price;
return bcmul($price, $this->buyAmount, 2);
}
/**
* 计算实际需要支付的价格
*
* @param float $totalPrice 总价
* @param float $couponPrice 优惠码优惠价
* @param float $wholesalePrice 批发优惠
* @return float
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
private function calculateTheActualPrice(float $totalPrice, float $couponPrice, float $wholesalePrice): float
{
$actualPrice = bcsub($totalPrice, $couponPrice, 2);
$actualPrice = bcsub($actualPrice, $wholesalePrice, 2);
if ($actualPrice <= 0) {
$actualPrice = 0;
}
return $actualPrice;
}
/**
* 创建订单.
* @return Order
* @throws RuleValidationException
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function createOrder(): Order
{
try {
$order = new Order();
// 生成订单号
$order->order_sn = strtoupper(Str::random(16));
// 设置商品
$order->goods_id = $this->goods->id;
// 标题
$order->title = $this->goods->gd_name . ' x ' . $this->buyAmount;
// 订单类型
$order->type = $this->goods->type;
// 查询密码
$order->search_pwd = $this->searchPwd;
// 邮箱
$order->email = $this->email;
// 支付方式.
$order->pay_id = $this->payID;
// 商品单价
$order->goods_price = $this->goods->actual_price;
// 购买数量
$order->buy_amount = $this->buyAmount;
// 订单详情
$order->info = $this->otherIpt;
// ip地址
$order->buy_ip = $this->buyIP;
// 优惠码优惠价格
$order->coupon_discount_price = $this->calculateTheCouponPrice();
if ($this->coupon) {
$order->coupon_id = $this->coupon->id;
}
// 批发价
$order->wholesale_discount_price = $this->calculateTheWholesalePrice();
// 订单总价
$order->total_price = $this->calculateTheTotalPrice();
// 订单实际需要支付价格
$order->actual_price = $this->calculateTheActualPrice(
$this->calculateTheTotalPrice(),
$this->calculateTheCouponPrice(),
$this->calculateTheWholesalePrice()
);
// 保存订单
$order->save();
// 如果有用到优惠券
if ($this->coupon) {
// 设置优惠码已经使用
$this->couponService->used($this->coupon->coupon);
// 使用次数-1
$this->couponService->retDecr($this->coupon->coupon);
}
// 将订单加入队列 x分钟后过期
$expiredOrderDate = dujiaoka_config_get('order_expire_time', 5);
OrderExpired::dispatch($order->order_sn)->delay(Carbon::now()->addMinutes($expiredOrderDate));
return $order;
} catch (\Exception $exception) {
throw new RuleValidationException($exception->getMessage());
}
}
/**
* 订单成功方法
*
* @param string $orderSN 订单号
* @param float $actualPrice 实际支付金额
* @param string $tradeNo 第三方订单号
* @return Order
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function completedOrder(string $orderSN, float $actualPrice, string $tradeNo = '')
{
DB::beginTransaction();
try {
// 得到订单详情
$order = $this->orderService->detailOrderSN($orderSN);
if (!$order) {
throw new \Exception(__('dujiaoka.prompt.order_does_not_exist'));
}
// 订单已经处理
if ($order->status == Order::STATUS_COMPLETED) {
throw new \Exception(__('dujiaoka.prompt.order_status_completed'));
}
$bccomp = bccomp($order->actual_price, $actualPrice, 2);
// 金额不一致
if ($bccomp != 0) {
throw new \Exception(__('dujiaoka.prompt.order_inconsistent_amounts'));
}
$order->actual_price = $actualPrice;
$order->trade_no = $tradeNo;
// 区分订单类型
// 自动发货
if ($order->type == Order::AUTOMATIC_DELIVERY) {
$completedOrder = $this->processAuto($order);
} else {
$completedOrder = $this->processManual($order);
}
// 销量加上
$this->goodsService->salesVolumeIncr($order->goods_id, $order->buy_amount);
DB::commit();
// 如果开启了server酱
if (dujiaoka_config_get('is_open_server_jiang', 0) == BaseModel::STATUS_OPEN) {
ServerJiang::dispatch($order);
}
// 如果开启了TG推送
if (dujiaoka_config_get('is_open_telegram_push', 0) == BaseModel::STATUS_OPEN) {
TelegramPush::dispatch($order);
}
// 如果开启了Bark推送
if (dujiaoka_config_get('is_open_bark_push', 0) == BaseModel::STATUS_OPEN) {
BarkPush::dispatch($order);
}
// 如果开启了企业微信Bot推送
if (dujiaoka_config_get('is_open_qywxbot_push', 0) == BaseModel::STATUS_OPEN) {
WorkWeiXinPush::dispatch($order);
}
// 回调事件
ApiHook::dispatch($order);
return $completedOrder;
} catch (\Exception $exception) {
DB::rollBack();
throw new RuleValidationException($exception->getMessage());
}
}
/**
* 手动处理的订单.
*
* @param Order $order 订单
* @return Order 订单
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function processManual(Order $order)
{
// 设置订单为待处理
$order->status = Order::STATUS_PENDING;
// 保存订单
$order->save();
// 商品库存减去
$this->goodsService->inStockDecr($order->goods_id, $order->buy_amount);
// 邮件数据
$mailData = [
'created_at' => $order->create_at,
'product_name' => $order->goods->gd_name,
'webname' => dujiaoka_config_get('text_logo', '独角数卡'),
'weburl' => config('app.url') ?? 'http://dujiaoka.com',
'ord_info' => str_replace(PHP_EOL, '<br/>', $order->info),
'ord_title' => $order->title,
'order_id' => $order->order_sn,
'buy_amount' => $order->buy_amount,
'ord_price' => $order->actual_price,
'created_at' => $order->created_at,
];
$tpl = $this->emailtplService->detailByToken('manual_send_manage_mail');
$mailBody = replace_mail_tpl($tpl, $mailData);
$manageMail = dujiaoka_config_get('manage_email', '');
// 邮件发送
MailSend::dispatch($manageMail, $mailBody['tpl_name'], $mailBody['tpl_content']);
return $order;
}
/**
* 处理自动发货.
*
* @param Order $order 订单
* @return Order 订单
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function processAuto(Order $order): Order
{
// 获得卡密
$carmis = $this->carmisService->withGoodsByAmountAndStatusUnsold($order->goods_id, $order->buy_amount);
// 实际可使用的库存已经少于购买数量了
if (count($carmis) != $order->buy_amount) {
$order->info = __('dujiaoka.prompt.order_carmis_insufficient_quantity_available');
$order->status = Order::STATUS_ABNORMAL;
$order->save();
return $order;
}
$carmisInfo = array_column($carmis, 'carmi');
$ids = array_column($carmis, 'id');
$order->info = implode(PHP_EOL, $carmisInfo);
$order->status = Order::STATUS_COMPLETED;
$order->save();
// 将卡密设置为已售出
$this->carmisService->soldByIDS($ids);
// 邮件数据
$mailData = [
'created_at' => $order->create_at,
'product_name' => $order->goods->gd_name,
'webname' => dujiaoka_config_get('text_logo', '独角数卡'),
'weburl' => config('app.url') ?? 'http://dujiaoka.com',
'ord_info' => implode('<br/>', $carmisInfo),
'ord_title' => $order->title,
'order_id' => $order->order_sn,
'buy_amount' => $order->buy_amount,
'ord_price' => $order->actual_price,
];
$tpl = $this->emailtplService->detailByToken('card_send_user_email');
$mailBody = replace_mail_tpl($tpl, $mailData);
// 邮件发送
MailSend::dispatch($order->email, $mailBody['tpl_name'], $mailBody['tpl_content']);
return $order;
}
}
+290
View File
@@ -0,0 +1,290 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Exceptions\RuleValidationException;
use App\Models\BaseModel;
use App\Models\Coupon;
use App\Models\Goods;
use App\Models\Carmis;
use App\Models\Order;
use App\Rules\SearchPwd;
use App\Rules\VerifyImg;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class OrderService
{
/**
* 商品服务层.
* @var \App\Service\PayService
*/
private $goodsService;
/**
* 优惠码服务层
* @var \App\Service\CouponService
*/
private $couponService;
public function __construct()
{
$this->goodsService = app('Service\GoodsService');
$this->couponService = app('Service\CouponService');
}
/**
* 验证集合
*
* @param Request $request
* @throws RuleValidationException
* @throws \Illuminate\Validation\ValidationException
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function validatorCreateOrder(Request $request): void
{
$validator = Validator::make($request->all(), [
'gid' => 'required' ,
'email' => ['required', 'email'],
'payway' => ['required', 'integer'],
'search_pwd' => [new SearchPwd()],
'by_amount' => ['required', 'integer', 'min:1'],
'img_verify_code' => [new VerifyImg()],
], [
'by_amount.required' => __('dujiaoka.prompt.buy_amount_format_error'),
'by_amount.integer' => __('dujiaoka.prompt.buy_amount_format_error'),
'by_amount.min' => __('dujiaoka.prompt.buy_amount_format_error'),
'payway.required' => __('dujiaoka.prompt.please_select_mode_of_payment'),
'payway.integer' => __('dujiaoka.prompt.please_select_mode_of_payment'),
'email.required' => __('dujiaoka.prompt.email_format_error'),
'email.email' => __('dujiaoka.prompt.email_format_error'),
'gid.required' => __('dujiaoka.prompt.goods_does_not_exist'),
]);
if ($validator->fails()) {
throw new RuleValidationException($validator->errors()->first());
}
// 极验验证
if (
dujiaoka_config_get('is_open_geetest') == BaseModel::STATUS_OPEN
&&
!Validator::make($request->all(),
['geetest_challenge' => 'geetest',],
[ 'geetest' => __('dujiaoka.prompt.geetest_validate_fail')])
) {
throw new RuleValidationException(__('dujiaoka.prompt.geetest_validate_fail'));
}
}
/**
* 得到商品详情并验证
*
* @param Request $request 请求
* @throws RuleValidationException
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function validatorGoods(Request $request): Goods
{
// 获得商品详情
$goods = $this->goodsService->detail($request->input('gid'));
// 商品状态验证
$this->goodsService->validatorGoodsStatus($goods);
// 如果有限购
if ($goods->buy_limit_num > 0 && $request->input('by_amount') > $goods->buy_limit_num) {
throw new RuleValidationException(__('dujiaoka.prompt.purchase_limit_exceeded'));
}
// 库存不足
if ($request->input('by_amount') > $goods->in_stock) {
throw new RuleValidationException(__('dujiaoka.prompt.inventory_shortage'));
}
return $goods;
}
/**
* 判断是否有循环卡密
*
* @param int $goodsID 商品id
* @return array|null
*
* @author ZhangYiQiu<me@zhangyiqiu.net>
* @copyright ZhangYiQiu<me@zhangyiqiu.net>
* @link http://zhangyiqiu.net/
*/
public function validatorLoopCarmis(Request $request)
{
$carmis = Carmis::query()
->where('goods_id', $request->input('gid'))
->where('status', Carmis::STATUS_UNSOLD)
->where('is_loop', true)
->count();
if($carmis > 0 && $request->input('by_amount') > 1){
throw new RuleValidationException(__('dujiaoka.prompt.loop_carmis_limit'));
}
return $carmis;
}
/**
* 优惠码验证
*
* @param Request $request
* @return Coupon|null
* @throws RuleValidationException
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function validatorCoupon(Request $request):? Coupon
{
// 如果提交了优惠码
if ($request->filled('coupon_code')) {
// 查询优惠码是否存在
$coupon = $this->couponService->withHasGoods($request->input('coupon_code'), $request->input('gid'));
// 此商品没有这个优惠码
if (empty($coupon)) {
throw new RuleValidationException(__('dujiaoka.prompt.coupon_does_not_exist'));
}
// 剩余次数不足
if ($coupon->ret <= 0) {
throw new RuleValidationException(__('dujiaoka.prompt.coupon_lack_of_available_opportunities'));
}
return $coupon;
}
return null;
}
/**
* 代充框验证.
*
* @param Goods $goods
* @param Request $request
* @return string
* @throws RuleValidationException
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function validatorChargeInput(Goods $goods, Request $request): string
{
$otherIpt = '';
// 代充框验证
if ($goods->type == Goods::MANUAL_PROCESSING && !empty($goods->other_ipu_cnf)) {
// 如果有其他输入框 判断其他输入框内容 然后载入信息
$formatIpt = format_charge_input($goods->other_ipu_cnf);
foreach ($formatIpt as $item) {
if ($item['rule'] && !$request->filled($item['field'])) {
$errMessage = $item['desc'] . __('dujiaoka.prompt.can_not_be_empty');
throw new RuleValidationException($errMessage);
}
$otherIpt .= $item['desc'].':'.$request->input($item['field']) . PHP_EOL;
}
}
return $otherIpt;
}
/**
* 通过订单号查询订单
* @param string $orderSN
* @return Order
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function detailOrderSN(string $orderSN):? Order
{
$order = Order::query()->with(['coupon', 'pay', 'goods'])->where('order_sn', $orderSN)->first();
return $order;
}
/**
* 根据订单号过期订单.
*
* @param string $orderSN
* @return bool
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function expiredOrderSN(string $orderSN): bool
{
return Order::query()->where('order_sn', $orderSN)->update(['status' => Order::STATUS_EXPIRED]);
}
/**
* 设置订单优惠码已回退
*
* @param string $orderSN
* @return bool
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function couponIsBack(string $orderSN): bool
{
return Order::query()->where('order_sn', $orderSN)->update(['coupon_ret_back' => Order::COUPON_BACK_OK]);
}
/**
* 通过邮箱和查询密码查询
*
* @param string $email 邮箱
* @param string $searchPwd 查询面面
* @return array|\Illuminate\Database\Concerns\BuildsQueries[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function withEmailAndPassword(string $email, string $searchPwd = '')
{
return Order::query()
->where('email', $email)
->when(!empty($searchPwd), function ($query) use ($searchPwd) {
$query->where('search_pwd', $searchPwd);
})
->orderBy('created_at', 'DESC')
->take(5)
->get();
}
/**
* 通过订单号集合查询
*
* @param array $orderSNS 订单号集合
* @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function byOrderSNS(array $orderSNS)
{
return Order::query()
->whereIn('order_sn', $orderSNS)
->orderBy('created_at', 'DESC')
->take(5)
->get();
}
}
+75
View File
@@ -0,0 +1,75 @@
<?php
/**
* The file was created by Assimon.
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
namespace App\Service;
use App\Models\Pay;
class PayService
{
/**
* 加载支付网关
*
* @param string|int $payClient 支付场景客户端
* @return array|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function pays(string $payClient = Pay::PAY_CLIENT_PC): ?array
{
$payGateway = Pay::query()
->whereIn('pay_client', [$payClient, Pay::PAY_CLIENT_ALL])
->where('is_open', Pay::STATUS_OPEN)
->get();
return $payGateway ? $payGateway->toArray() : null;
}
/**
* 通过支付标识获得支付配置
*
* @param string $check 支付标识
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function detailByCheck(string $check)
{
$gateway = Pay::query()
->where('pay_check', $check)
->where('is_open', Pay::STATUS_OPEN)
->first();
return $gateway;
}
/**
* 通过id查询支付网关
*
* @param int $id 支付网关id
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
*
* @author assimon<ashang@utf8.hk>
* @copyright assimon<ashang@utf8.hk>
* @link http://utf8.hk/
*/
public function detail(int $id)
{
$gateway = Pay::query()
->where('id', $id)
->where('is_open', Pay::STATUS_OPEN)
->first();
return $gateway;
}
}