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.
yanzong/app/common/service/server/Order.php

365 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']) && $order['order_status'] != ServerEnum::COMPLETED || $order['order_status'] != ServerEnum::CANCELLED) {
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']) && $order['order_status'] != ServerEnum::COMPLETED || $order['order_status'] != 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 checkPay($order): bool
{
$userId = UserService::getCurrentLoginUserId();
if (!empty($order) && $order['pay_status'] == PayStatus::PENDING && $order['user_id'] == $userId) {
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 int $serverId
* @param int $couponId
* @param string $buyer_remark
* @return array
* @throws BaseException
* @throws DbException
* @author: wanghousheng
*/
public function createOrder(int $serverId, int $couponId, string $buyer_remark = ''): array
{
$userId = UserService::getCurrentLoginUserId();
$data = $this->onCheck($serverId, $couponId);
// 设置优惠券使用状态
$couponId > 0 && UserCoupon::setIsUse($couponId);
//封装数据
$order_data = [
'server_id' => $this->serverInfo['server_id'],
'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'],
'buyer_remark' => $buyer_remark,
'create_time' => time(),
'update_time' => time(),
];
$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 [];
}
}