You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
382 lines
12 KiB
382 lines
12 KiB
<?php
|
|
declare (strict_types=1);
|
|
|
|
namespace app\common\service\server;
|
|
|
|
use app\api\model\dealer\User as DealerUserModel;
|
|
use app\api\model\Server\ServerOrder;
|
|
use app\api\model\UserCoupon;
|
|
use app\api\service\User as UserService;
|
|
use app\common\enum\coupon\CouponType as CouponTypeEnum;
|
|
use app\common\enum\coupon\TypeCase;
|
|
use app\common\enum\dealer\DealerUserEnum;
|
|
use app\common\enum\order\PayStatus;
|
|
use app\common\enum\ServerEnum;
|
|
use app\common\library\helper;
|
|
use app\common\model\server\Server;
|
|
use app\common\model\UserCoupon as UserCouponModel;
|
|
use app\common\service\BaseService;
|
|
use app\common\service\Order as OrderService;
|
|
use app\common\service\order\Refund as RefundService;
|
|
use app\store\model\dealer\User as UserModel;
|
|
use cores\exception\BaseException;
|
|
use think\db\exception\DataNotFoundException;
|
|
use think\db\exception\DbException;
|
|
use think\db\exception\ModelNotFoundException;
|
|
|
|
class Order extends BaseService
|
|
{
|
|
/**
|
|
* 订单结算的规则
|
|
* @var array
|
|
*/
|
|
private array $checkoutRule = [
|
|
'isUserGrade' => true, // 会员等级折扣
|
|
'isCoupon' => true, // 优惠券抵扣
|
|
'isUsePoints' => true, // 是否使用积分抵扣
|
|
'isDealer' => true, // 是否开启分销
|
|
];
|
|
|
|
private array $serverInfo;
|
|
|
|
private int $serverId;
|
|
private int $couponId;
|
|
|
|
/**
|
|
* 生成订单号
|
|
* @return string
|
|
*/
|
|
private function orderNo(): string
|
|
{
|
|
return OrderService::createOrderNo();
|
|
}
|
|
|
|
/**
|
|
* @notes:用户取消订单
|
|
* @param array $order
|
|
* @return bool
|
|
* @throws BaseException
|
|
* @throws DataNotFoundException
|
|
* @throws DbException
|
|
* @throws ModelNotFoundException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function cancelOrder(array $order): bool
|
|
{
|
|
//未完成 未取消
|
|
if (!empty($order['order_status']) && self::checkCancel($order)) {
|
|
if (!empty($order['coupon_id'])) {
|
|
// 回退用户优惠券
|
|
$order['coupon_id'] > 0 && UserCouponModel::setIsUse($order['coupon_id'], false);
|
|
}
|
|
//判断是否已支付
|
|
if ($order['pay_status'] == PayStatus::SUCCESS) {
|
|
if (!(new RefundService)->handle($order)) {
|
|
try {
|
|
throwError('执行订单退款失败');
|
|
} catch (BaseException $e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
//更新订单状态
|
|
$model = new \app\common\model\server\Order;
|
|
$model->where(['order_id' => $order['order_id']])->save(['order_status' => ServerEnum::CANCELLED]);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @notes:是否可以取消
|
|
* @param $order
|
|
* @return bool
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function checkCancel($order): bool
|
|
{
|
|
|
|
if (!empty($order['order_status']) && !in_array($order['order_status'], [ServerEnum::COMPLETED, ServerEnum::CANCELLED])) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @notes:是否可以派单
|
|
* @param $order
|
|
* @return bool
|
|
* @throws BaseException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function checkDispatch($order): bool
|
|
{
|
|
if (!empty($order) && $order['order_status'] == ServerEnum::APPLYDISPATCH && UserService::isStore()) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @notes:是否可以完成
|
|
* @param $order
|
|
* @return bool
|
|
* @throws BaseException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function checkSuccess($order): bool
|
|
{
|
|
if (!UserService::isDealerEngineer() || !UserService::isStore()) {
|
|
return false;
|
|
}
|
|
if (!empty($order) && $order['order_status'] == ServerEnum::APPLYSERVER) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @notes:是否可以支付
|
|
* @param $order
|
|
* @return bool
|
|
* @throws BaseException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function checkPay($order): bool
|
|
{
|
|
$userId = UserService::getCurrentLoginUserId();
|
|
if (!empty($order) && $order['pay_status'] == PayStatus::PENDING && $order['user_id'] == $userId && $order['order_status'] == ServerEnum::APPLYPAY) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @notes:派单
|
|
* @param array $order
|
|
* @param int $dealerId
|
|
* @return bool
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function dispatchOrders(array $order, int $dealerId): bool
|
|
{
|
|
//判断该订单是否可以指派
|
|
if (!empty($order) && $order['order_status'] == ServerEnum::APPLYDISPATCH) {
|
|
//判断指派人员是否是分销工程师
|
|
$dealerInfo = DealerUserModel::detail($dealerId, []);
|
|
if (!empty($dealerInfo)) {
|
|
$dealerInfo = $dealerInfo->toArray();
|
|
if ($dealerInfo['type'] == DealerUserEnum::ENGINEER) {
|
|
$model = new \app\common\model\server\Order;
|
|
$up['dealer_id'] = $dealerId;
|
|
$up['order_status'] = ServerEnum::APPLYSERVER;
|
|
$model->where(['order_id' => $order['order_id']])->save($up);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @notes:生成订单
|
|
* @param array $params
|
|
* @param int $couponId
|
|
* @return array
|
|
* @throws BaseException
|
|
* @throws DbException
|
|
* @author: wanghousheng
|
|
*/
|
|
public function createOrder(array $params, int $couponId): array
|
|
{
|
|
$userId = UserService::getCurrentLoginUserId();
|
|
$data = $this->onCheck($params['server_id'], $couponId);
|
|
// 设置优惠券使用状态
|
|
$couponId > 0 && UserCoupon::setIsUse($couponId);
|
|
//封装数据
|
|
$order_data = [
|
|
'order_no' => $this->orderNo(),
|
|
'server_name' => $this->serverInfo['server_name'],
|
|
'server_image_id' => $this->serverInfo['image_id'],
|
|
'total_price' => $this->serverInfo['server_price'],
|
|
'store_id' => $this->storeId,
|
|
'user_id' => $userId,
|
|
'coupon_id' => $data['coupon_id'],
|
|
'coupon_money' => $data['coupon_money'],
|
|
'pay_price' => $data['pay_price'],
|
|
'create_time' => time(),
|
|
'update_time' => time(),
|
|
];
|
|
$order_data = array_merge($order_data, $params);
|
|
$model = new ServerOrder();
|
|
$order_id = $model->insertGetId($order_data);
|
|
if ($order_id) {
|
|
return ['order_no' => $order_data['order_no'], 'order_id' => $order_id];
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* @notes:订单确认-结算台
|
|
* @param int $serverId
|
|
* @param int $couponId
|
|
* @return array
|
|
* @throws BaseException
|
|
* @throws DbException
|
|
* @author: wanghousheng
|
|
*/
|
|
public function onCheck(int $serverId, int $couponId): array
|
|
{
|
|
$this->serverId = $serverId;
|
|
$this->couponId = $couponId;
|
|
return $this->checkOut();
|
|
}
|
|
|
|
/**
|
|
* @notes:订单结算台
|
|
* @return array
|
|
* @throws BaseException
|
|
* @throws DbException
|
|
* @author: wanghousheng
|
|
*/
|
|
private function checkOut(): array
|
|
{
|
|
$info = Server::detail(['server_id' => $this->serverId, 'status' => 1], ['image', 'category']);
|
|
if (empty($info)) {
|
|
throwError('未找到服务信息');
|
|
}
|
|
$this->serverInfo = $info->toArray();
|
|
$couponList = $this->getUserCouponList();
|
|
$couponMoney = 0;
|
|
if ($couponList && $this->couponId) {
|
|
$couponMoney = $this->getCouponMoney($this->couponId, $couponList);
|
|
}
|
|
return [
|
|
'info' => $this->serverInfo,
|
|
'server_id' => $this->serverId,
|
|
'coupon_list' => $couponList,
|
|
'coupon_money' => $couponMoney,
|
|
'coupon_id' => $this->couponId,
|
|
'pay_price' => helper::number2($this->serverInfo['server_price'] - $couponMoney),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 当前用户可用的优惠券列表
|
|
* @return array
|
|
* @throws DbException|BaseException
|
|
*/
|
|
private function getUserCouponList(): array
|
|
{
|
|
// 是否开启优惠券折扣
|
|
if (!$this->checkoutRule['isCoupon']) {
|
|
return [];
|
|
}
|
|
$userId = UserService::getCurrentLoginUserId();
|
|
// 当前用户可用的优惠券列表
|
|
$couponList = UserCoupon::getUserCouponList($userId, (float)$this->serverInfo['server_price'], TypeCase::SERVER);
|
|
// 判断当前优惠券是否满足订单使用条件 (优惠券适用范围)
|
|
return UserCoupon::couponListApplyRangeServer($couponList, [$this->serverId]);
|
|
}
|
|
|
|
/**
|
|
* 查找指定的优惠券信息
|
|
* @param array $couponList 优惠券列表
|
|
* @return false|mixed
|
|
*/
|
|
private function getCouponInfo(int $userCouponId, array $couponList)
|
|
{
|
|
return helper::getArrayItemByColumn($couponList, 'user_coupon_id', $userCouponId);
|
|
}
|
|
|
|
/**
|
|
* @notes:获取优惠金额
|
|
* @param int $userCouponId
|
|
* @param array $couponList
|
|
* @return float|int|mixed
|
|
* @author: wanghousheng
|
|
*/
|
|
private function getCouponMoney(int $userCouponId, array $couponList)
|
|
{
|
|
// 获取优惠券信息
|
|
$couponInfo = $this->getCouponInfo($userCouponId, $couponList);
|
|
$reducedMoney = $this->serverInfo['server_price'];
|
|
// 计算打折金额
|
|
if ($couponInfo['coupon_type'] == CouponTypeEnum::DISCOUNT) {
|
|
$reducePrice = $reducedMoney - ($reducedMoney * ($couponInfo['discount'] / 10));
|
|
} else {
|
|
$reducePrice = $couponInfo['reduce_price'];
|
|
}
|
|
$reducePrice = helper::number2($reducePrice);
|
|
// 优惠券最大允许抵扣到一分钱,所以此处判断抵扣金额大于等于订单金额时,减去一分钱
|
|
return ($reducePrice >= $reducedMoney) ? $reducedMoney - 1 : $reducePrice;
|
|
}
|
|
|
|
/**
|
|
* @notes:用户取消订单
|
|
* @param int $orderId
|
|
* @return bool
|
|
* @throws BaseException
|
|
* @throws DataNotFoundException
|
|
* @throws DbException
|
|
* @throws ModelNotFoundException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function userCancelOrder(int $orderId): bool
|
|
{
|
|
$userId = UserService::getCurrentLoginUserId();
|
|
$where['order_id'] = $orderId;
|
|
if (UserService::isDealerMember()) {
|
|
return false;
|
|
}
|
|
if (UserService::isPlusMember() || UserService::isNormalMember()) {
|
|
$where['user_id'] = $userId;
|
|
}
|
|
$orderInfo = ServerOrder::detail($where);
|
|
if ($orderInfo->isEmpty()) {
|
|
throwError('订单信息不存在');
|
|
}
|
|
return self::cancelOrder($orderInfo->toArray());
|
|
}
|
|
|
|
/**
|
|
* @notes:派单
|
|
* @param int $orderId
|
|
* @param int $dealerId
|
|
* @return bool
|
|
* @throws BaseException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function userDispatchOrders(int $orderId, int $dealerId): bool
|
|
{
|
|
if (!UserService::isStore()) {
|
|
return false;
|
|
}
|
|
$orderInfo = ServerOrder::detail(['order_id' => $orderId]);
|
|
if ($orderInfo->isEmpty()) {
|
|
throwError('订单信息不存在');
|
|
}
|
|
return self::dispatchOrders($orderInfo->toArray(), $dealerId);
|
|
}
|
|
|
|
/**
|
|
* @notes:分销商工程师-派单人员列表
|
|
* @return array
|
|
* @throws BaseException
|
|
* @throws DataNotFoundException
|
|
* @throws DbException
|
|
* @throws ModelNotFoundException
|
|
* @author: wanghousheng
|
|
*/
|
|
public static function getEngineer(): array
|
|
{
|
|
if (UserService::isStore()) {
|
|
$list = UserModel::getEngineer();
|
|
if (!$list->isEmpty()) {
|
|
return $list->toArray();
|
|
}
|
|
}
|
|
return [];
|
|
}
|
|
|
|
} |