初始版本
This commit is contained in:
892
server/app/api/logic/OrderLogic.php
Executable file
892
server/app/api/logic/OrderLogic.php
Executable file
@@ -0,0 +1,892 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\api\logic;
|
||||
|
||||
|
||||
use app\common\enum\GoodsEnum;
|
||||
use app\common\enum\notice\NoticeEnum;
|
||||
use app\common\enum\OrderEnum;
|
||||
use app\common\enum\OrderLogEnum;
|
||||
use app\common\enum\OrderRefundEnum;
|
||||
use app\common\enum\PayEnum;
|
||||
use app\common\enum\YesNoEnum;
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\logic\OrderLogLogic;
|
||||
use app\common\logic\RefundLogic;
|
||||
use app\common\model\city\City;
|
||||
use app\common\model\coach\Coach;
|
||||
use app\common\model\deposit\DepositPackage;
|
||||
use app\common\model\goods\Goods;
|
||||
use app\common\model\goods\GoodsComment;
|
||||
use app\common\model\goods\GoodsCommentImage;
|
||||
use app\common\model\order\Order;
|
||||
use app\common\model\order\OrderAppend;
|
||||
use app\common\model\order\OrderGap;
|
||||
use app\common\model\order\OrderGoods;
|
||||
use app\common\model\pay\PayWay;
|
||||
use app\common\model\RechargeOrder;
|
||||
use app\common\model\shop\Shop;
|
||||
use app\common\model\user\User;
|
||||
use app\common\model\user\UserAddress;
|
||||
use app\common\service\ConfigService;
|
||||
use app\common\service\FileService;
|
||||
use DateTime;
|
||||
use think\Exception;
|
||||
use think\facade\Db;
|
||||
|
||||
class OrderLogic extends BaseLogic
|
||||
{
|
||||
/**
|
||||
* @notes 订单结算详情
|
||||
* @param $params
|
||||
* @return array|false
|
||||
* @author ljj
|
||||
* @date 2022/2/24 6:19 下午
|
||||
*/
|
||||
public function settlement($params)
|
||||
{
|
||||
try {
|
||||
//获取用户信息
|
||||
$user = User::findOrEmpty($params['user_id'])->toArray();
|
||||
$addressId = $params['address_id'] ?? 0;
|
||||
$tripWay = $params['trip_way'] ?? 0;
|
||||
$appointTime = $params['appoint_time'] ?? '';
|
||||
$carAmount = 0;//车费
|
||||
$city = [];//当前城市
|
||||
$tripWayLists = [];//出行方式列表
|
||||
$userAddress = []; //地址
|
||||
$coach = [];//技师信息
|
||||
$distance = '';//订单距离
|
||||
$tips = '';
|
||||
$coach = Coach::where(['id'=>$params['coach_id']])
|
||||
->field( 'id,shop_id,sn,work_photo,name,longitude,latitude,longitude_location,latitude_location,deposit,work_status,server_status')
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
if(empty($coach)){
|
||||
throw new Exception('技师不存在');
|
||||
}
|
||||
if(0 == $coach['work_status']){
|
||||
throw new Exception('技师休息中');
|
||||
}
|
||||
if(0 == $coach['server_status']){
|
||||
throw new Exception('技师已暂停服务');
|
||||
}
|
||||
//获取服务信息
|
||||
$goodsInfo = self::getOrderGoods($params['goods'],$params['appoint_time'] ?? 0);
|
||||
if($appointTime){
|
||||
if($appointTime <= time()){
|
||||
throw new Exception('服务时间不能小于当前时间');
|
||||
}
|
||||
$serverTimeLists = $this->getCoachServerTime($params['coach_id'],$params['goods'][0]['id']);
|
||||
$serverTimeLists = array_column($serverTimeLists,null,'time_date');
|
||||
//预约天
|
||||
$appointTimeMd = date('m-d',$appointTime);
|
||||
//预约小时
|
||||
$appointTimeHi = date('H:i',$appointTime);
|
||||
$timeLists = $serverTimeLists[$appointTimeMd]['time_lists'] ?? [];
|
||||
|
||||
if(empty($timeLists)){
|
||||
throw new Exception('预约时间错误');
|
||||
}
|
||||
$timeLists = array_column($timeLists,null,'time');
|
||||
$time = $timeLists[$appointTimeHi] ?? [];
|
||||
if(empty($time)){
|
||||
throw new Exception('预约时间段错误');
|
||||
}
|
||||
if(2 == $time['status']){
|
||||
throw new Exception('当前时间技师休息中,无法预约');
|
||||
}
|
||||
if(3 == $time['status']){
|
||||
throw new Exception('当前时间区间有被预约,请更换其他时间区间');
|
||||
}
|
||||
$totalDuration = $goodsInfo['total_duration'];
|
||||
$dateTime = new DateTime(date('Y-m-d H:i:s',$appointTime));
|
||||
if($totalDuration > 30){
|
||||
$nums = intval($totalDuration / 30);
|
||||
for ($i = 0;$nums > $i;$i++){
|
||||
$dateTime->modify('+30 minutes');
|
||||
$appointTimeEnd = strtotime($dateTime->format('Y-m-d H:i'));
|
||||
}
|
||||
}else{
|
||||
$dateTime->modify('+'. $totalDuration.' minutes');
|
||||
$appointTimeEnd = strtotime($dateTime->format('Y-m-d H:i'));
|
||||
}
|
||||
$appointTimeEnd = round_date_time($appointTimeEnd);
|
||||
$appointTimeEndMd = date('m-d',$appointTimeEnd);
|
||||
$appointTimeEndHi = date('H:i',$appointTimeEnd);
|
||||
$timeLists = $serverTimeLists[$appointTimeEndMd]['time_lists'] ?? [];
|
||||
$timeLists = array_column($timeLists,null,'time');
|
||||
$time = $timeLists[$appointTimeEndHi] ?? [];
|
||||
if(empty($time)){
|
||||
throw new Exception('当前时间区间有被预约,请更换其他时间区间');
|
||||
}
|
||||
if(2 == $time['status']){
|
||||
throw new Exception('当前时间技师休息中,无法预约');
|
||||
}
|
||||
if(3 == $time['status']){
|
||||
throw new Exception('当前时间区间有被预约,请更换其他时间区间');
|
||||
}
|
||||
}
|
||||
//验证技师的接单数量
|
||||
// $this->ckechCoachTakeOrderNum($coach);
|
||||
|
||||
|
||||
//设置用户地址
|
||||
$userAddress = UserAddress::getUserAddress($params['user_id'], $addressId);
|
||||
$goodsCityLists = $goodsInfo['city_lists'];
|
||||
if($userAddress){
|
||||
$file = 'id,shop_id,sn,work_photo,name,round(st_distance_sphere(point('.$userAddress['longitude'].','.$userAddress['latitude'].'),
|
||||
point(longitude_location, latitude_location))/1000,2) as distance';
|
||||
if(empty($coach['longitude_location']) || empty($coach['latitude_location'])){
|
||||
$file ='id,shop_id,sn,work_photo,name,round(st_distance_sphere(point('.$userAddress['longitude'].','.$userAddress['latitude'].'),
|
||||
point(longitude, latitude))/1000,2) as distance';
|
||||
}
|
||||
$coach = Coach::where(['id'=>$params['coach_id']])
|
||||
->field( $file)
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
|
||||
// if(empty($userAddress)){
|
||||
// throw new Exception('用户地址不存在,请重新选择');
|
||||
// }
|
||||
$city = City::where(['city_id'=>$userAddress['city_id']])->findOrEmpty()->toArray();
|
||||
if($addressId && empty($city)){
|
||||
throw new Exception('当前城市未开通出行方式,请联系管理员');
|
||||
}
|
||||
if($addressId && true !== $goodsCityLists && !in_array($userAddress['city_id'],$goodsCityLists)){
|
||||
throw new Exception('抱歉,商品暂不支持该服务地址');
|
||||
}
|
||||
$coachServerScope = ConfigService::get('server_setting', 'coach_server_scope');
|
||||
if($addressId && $coach['distance'] > $coachServerScope){
|
||||
throw new Exception('当前最大服务范围'.$coachServerScope.'公里,请重新选择地址');
|
||||
}
|
||||
$distance = intval(ceil($coach['distance']));
|
||||
$tips = '全程'.$coach['distance'].'公里,出租出行收取来回费用,白天起步价'.$city['start_price'].'元,超过'.$city['start_km'].'公里部分,每公里'.$city['continue_price'].'元';
|
||||
if($city['taxi']){
|
||||
$amount = 0;
|
||||
if($distance <= $city['start_km']){
|
||||
$amount = $city['start_price'];
|
||||
}else{
|
||||
$amount += $city['start_price'];
|
||||
$surplus = round($distance-$city['start_km'],2);
|
||||
$amount += round($city['continue_price'] * $surplus,2);
|
||||
}
|
||||
$tripWayLists[] = [
|
||||
'type' => OrderEnum::TRIP_WAY_TAXI,
|
||||
'type_desc' => OrderEnum::getTripWayDesc(OrderEnum::TRIP_WAY_TAXI),
|
||||
'tips' => $tips,
|
||||
'amount' => round($amount,2),
|
||||
];
|
||||
}
|
||||
$nowH = date('H');
|
||||
if($city['bus'] && $nowH > $city['bus_start_time'] && $city['bus_end_time'] > $nowH){
|
||||
$tips = '当前城市'.$city['bus_start_time'].'-'.$city['bus_end_time'].'可选择交通地铁出行方式';
|
||||
$tripWayLists[] = [
|
||||
'type' => OrderEnum::TRIP_WAY_BUS,
|
||||
'type_desc' => OrderEnum::getTripWayDesc(OrderEnum::TRIP_WAY_BUS),
|
||||
'tips' => $tips,
|
||||
'amount' => $city['bus_fare'],
|
||||
];
|
||||
}
|
||||
$tripWayLists = array_column($tripWayLists,null,'type');
|
||||
$carAmount = $tripWayLists[$tripWay]['amount'] ?? 0;
|
||||
}
|
||||
// 订单金额
|
||||
$totalAmount = round($goodsInfo['total_amount']+$carAmount,2);
|
||||
//订单应付金额
|
||||
$orderAmount = $totalAmount;
|
||||
//订单服务总数量
|
||||
$totalNum = $goodsInfo['total_num'];
|
||||
//订单服务总价
|
||||
$totalGoodsPrice = $goodsInfo['total_amount'];
|
||||
$result = [
|
||||
'terminal' => $params['terminal'],
|
||||
'total_num' => $totalNum,
|
||||
'total_goods_price' => $totalGoodsPrice,
|
||||
'total_amount' => $orderAmount,
|
||||
'order_amount' => $orderAmount,
|
||||
'user_id' => $user['id'],
|
||||
'user_remark' => $params['user_remark'] ?? '',
|
||||
'appoint_time' => $params['appoint_time'] ?? '',
|
||||
'address' => $userAddress,
|
||||
'goods' => $goodsInfo['goods_lists'],
|
||||
'trip_way_lists' => array_values($tripWayLists),
|
||||
'trip_way' => $tripWay,
|
||||
'city' => $city,
|
||||
'coach_id' => $params['coach_id'] ?? '',
|
||||
'coach' => $coach,
|
||||
'total_duration' => $goodsInfo['total_duration'],
|
||||
'distance' => $distance,
|
||||
'distance_desc' => $distance ? $coach['distance'].'km' : $distance,
|
||||
'pay_way_list' => PayLogic::getPayWayList($params['terminal'],$params['user_id']),
|
||||
'car_amount' => $carAmount,
|
||||
'city_lists' => $goodsInfo['city_lists'],
|
||||
];
|
||||
return $result;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
self::$error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notes 验证技师的接单数量
|
||||
* @param $coach
|
||||
* @return int|mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author cjhao
|
||||
* @date 2024/11/26 23:44
|
||||
*/
|
||||
public function ckechCoachTakeOrderNum($coach){
|
||||
$deposit = $coach['deposit'];
|
||||
$depositPackageLists = [];
|
||||
$takeOrderNum = 0;
|
||||
if($coach['shop_id']){
|
||||
$deposit = Shop::where(['id'=>$coach['shop_id']])->value('deposit');
|
||||
$where[] = ['type','=',1];
|
||||
$orderNum = Order::where(['shop_id'=>$coach['shop_id']])
|
||||
->where('order_status','>=',OrderEnum::ORDER_STATUS_WAIT_RECEIVING)
|
||||
->where('order_status','<',OrderEnum::ORDER_STATUS_CLOSE)
|
||||
->whereDay('create_time')->count();
|
||||
}else{
|
||||
$where[] = ['type','=',2];
|
||||
$orderNum = Order::where(['coach_id'=>$coach['id']])
|
||||
->where('order_status','>=',OrderEnum::ORDER_STATUS_WAIT_RECEIVING)
|
||||
->where('order_status','<',OrderEnum::ORDER_STATUS_CLOSE)
|
||||
->whereDay('create_time')->count();
|
||||
}
|
||||
$depositPackageLists = DepositPackage::where($where)->order('money desc')->select()->toArray();
|
||||
//套餐列表
|
||||
foreach ($depositPackageLists as $depositPackage){
|
||||
if($deposit >= $depositPackage['money']){
|
||||
$takeOrderNum = $depositPackage['order_limit'];
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if($orderNum >= $takeOrderNum){
|
||||
throw new Exception('技师接单数量已达上限');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @notes 获取订单服务信息
|
||||
* @param $goods
|
||||
* @return array
|
||||
* @author ljj
|
||||
* @date 2022/2/24 6:09 下午
|
||||
*/
|
||||
public function getOrderGoods($postGoods,$appointTime)
|
||||
{
|
||||
$postGoods = array_column($postGoods,null,'id');
|
||||
$goodsLists = (new Goods())->field('id,status,name,shop_id,tags,duration,image,price,overtime_price,overtime_duration,shop_ratio,commission_ratio,appoint_start_time,appoint_end_time')
|
||||
->where(['id'=>array_keys($postGoods),'audit_status'=>GoodsEnum::AUDIT_STATUS_PASS])
|
||||
->with(['goods_city'])
|
||||
->select()
|
||||
->toArray();
|
||||
if(count($goodsLists) != count($postGoods)){
|
||||
throw new Exception('商品已失效,请返回上个页面重新选择服务');
|
||||
}
|
||||
$totalAmount = 0;
|
||||
$totalNum = 0;
|
||||
$totalDuration = 0;
|
||||
$cityLists = [];
|
||||
$appointStartI = date('H:i',$appointTime);
|
||||
foreach ($goodsLists as $key => $goods){
|
||||
$goodsNum = $postGoods[$goods['id']]['goods_num'] ?? 0;
|
||||
if(0 >= $goodsNum){
|
||||
throw new Exception('商品数量或商品数据错误');
|
||||
}
|
||||
$goodsLists[$key]['goods_num'] = $goodsNum;
|
||||
$totalAmount += round($goods['price'] * $goodsNum,2);
|
||||
$totalNum += $goodsNum;
|
||||
$totalDuration += ($goods['duration'] * $goodsNum);
|
||||
$appointEndI = date('H:i',$appointTime+$goods['duration'] * 60);
|
||||
if($goods['appoint_start_time'] >! $appointStartI && $goods['appoint_start_time'] <! $appointEndI){
|
||||
throw new Exception('商品服务时间为:'.$goods['appoint_start_time'].'~'.$goods['appoint_end_time']);
|
||||
}
|
||||
if($goods['appoint_end_time'] >! $appointStartI && $goods['appoint_end_time'] < !$appointEndI){
|
||||
throw new Exception('商品服务时间为:'.$goods['appoint_start_time'].'~'.$goods['appoint_end_time']);
|
||||
}
|
||||
if(empty($goods['status'])){
|
||||
throw new Exception('商品已下架,请返回上个页面重新选择服务');
|
||||
}
|
||||
if($goods['goods_city']){
|
||||
foreach ($goods['goods_city'] as $city){
|
||||
$cityLists[] = $city['city_id'];
|
||||
}
|
||||
}else{
|
||||
$cityLists = true;
|
||||
}
|
||||
}
|
||||
//服务数量
|
||||
return [
|
||||
'goods_lists' => $goodsLists,
|
||||
'total_amount' => $totalAmount,
|
||||
'total_num' => $totalNum,
|
||||
'total_duration'=> $totalDuration,
|
||||
'city_lists' => $cityLists,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 提交订单
|
||||
* @param $params
|
||||
* @return array|false
|
||||
* @author ljj
|
||||
* @date 2022/2/25 9:40 上午
|
||||
*/
|
||||
public function submitOrder($params)
|
||||
{
|
||||
Db::startTrans();
|
||||
try {
|
||||
|
||||
$this->submitOrderCheck($params);
|
||||
//创建订单信息
|
||||
$order = self::addOrder($params);
|
||||
//订单日志
|
||||
(new OrderLogLogic())->record(OrderLogEnum::TYPE_USER,OrderLogEnum::USER_ADD_ORDER,$order['id'],$params['user_id']);
|
||||
|
||||
//提交事务
|
||||
Db::commit();
|
||||
return ['order_id' => $order['id'], 'type' => 'order'];
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
self::$error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 创建订单信息
|
||||
* @param $params
|
||||
* @return Order|\think\Model
|
||||
* @author ljj
|
||||
* @date 2022/2/25 9:40 上午
|
||||
*/
|
||||
public static function addOrder($params)
|
||||
{
|
||||
|
||||
$serverFinishTime = $params['appoint_time'] + ($params['total_duration'] * 60);
|
||||
$shopId = 0;
|
||||
if($params['goods'][0]['shop_id']){
|
||||
$shopId = $params['goods'][0]['shop_id'];
|
||||
}
|
||||
if($params['coach']['shop_id']){
|
||||
$shopId = $params['coach']['shop_id'];
|
||||
}
|
||||
//创建订单信息
|
||||
$order = Order::create([
|
||||
'sn' => generate_sn((new Order()), 'sn'),
|
||||
'user_id' => $params['user_id'],
|
||||
'shop_id' => $shopId,
|
||||
'coach_id' => $params['coach_id'],
|
||||
'order_terminal' => $params['terminal'],
|
||||
'goods_price' => $params['total_goods_price'],
|
||||
'total_order_amount' => $params['order_amount'],
|
||||
'order_amount' => $params['order_amount'],
|
||||
'total_amount' => $params['total_amount'],
|
||||
'total_num' => $params['total_num'],
|
||||
'user_remark' => $params['user_remark'],
|
||||
'contact' => $params['address']['contact'],
|
||||
'mobile' => $params['address']['mobile'],
|
||||
'province_id' => $params['address']['province_id'],
|
||||
'city_id' => $params['address']['city_id'],
|
||||
'district_id' => $params['address']['district_id'],
|
||||
'address_id' => $params['address']['id'],
|
||||
'address_snap' => json_encode($params['address']),
|
||||
'trip_way' => $params['trip_way'],
|
||||
'appoint_time' => $params['appoint_time'],
|
||||
'server_finish_time' => $serverFinishTime,
|
||||
'car_amount' => $params['car_amount'],
|
||||
'car_config_snap' => $params['city'],
|
||||
'order_distance' => $params['distance'],
|
||||
'total_duration' => $params['total_duration'],
|
||||
]);
|
||||
$orderGoods = [];
|
||||
foreach ($params['goods'] as $goods){
|
||||
$orderGoods[] = [
|
||||
'order_id' => $order->id,
|
||||
'goods_id' => $goods['id'],
|
||||
'goods_name' => $goods['name'],
|
||||
'goods_num' => $goods['goods_num'],
|
||||
'goods_image' => FileService::setFileUrl($goods['image']),
|
||||
'goods_price' => $goods['price'],
|
||||
'total_price' => round($goods['price'] * $goods['goods_num'],2),
|
||||
'total_pay_price' => round($goods['price'] * $goods['goods_num'],2),
|
||||
'duration' => $goods['duration'],
|
||||
'goods_snap' => $goods
|
||||
];
|
||||
}
|
||||
//创建订单服务信息
|
||||
(new OrderGoods())->saveAll($orderGoods);
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 订单详情
|
||||
* @param $id
|
||||
* @return array
|
||||
* @author ljj
|
||||
* @date 2022/2/28 11:23 上午
|
||||
*/
|
||||
public function detail($id)
|
||||
{
|
||||
$result = Order::field('id,sn,pay_way,goods_price,order_status,pay_status,appoint_time,order_amount,server_finish_time,create_time,coach_id,cancel_time,total_gap_amount,total_append_amount,total_order_amount,order_distance,address_snap,car_amount,user_remark')
|
||||
->where(['id'=>$id])
|
||||
->order('id','desc')
|
||||
->append(['appoint_time','pay_way_desc','appoint_date','order_status_desc','pay_btn','gap_btn','append_btn','user_cancel_btn','del_btn','comment_btn','look_comment_btn','order_cancel_time'])
|
||||
->with(['order_goods' => function($query){
|
||||
$query->field('id,order_id,goods_id,goods_snap,is_comment,duration,goods_image,goods_num,goods_name,goods_price')->hidden(['goods_snap']);
|
||||
},'order_gap','order_append'])
|
||||
->findOrEmpty()
|
||||
->toArray();
|
||||
|
||||
if(!isset($result['address_snap']['house_number'])){
|
||||
$result['address_snap']['house_number'] = '';
|
||||
}
|
||||
// if(in_array($result['order_status'],[OrderEnum::ORDER_STATUS_DEPART,OrderEnum::ORDER_STATUS_ARRIVE,OrderEnum::ORDER_STATUS_START_SERVER,OrderEnum::ORDER_STATUS_SERVER_FINISH])){
|
||||
$coach = Coach::where(['id'=>$result['coach_id']])->field('id,mobile,name,work_photo,sn')->findOrEmpty()->toArray();
|
||||
$result['coach_info'] = [
|
||||
'name' => $coach['name'] ?? '',
|
||||
'work_photo' => $coach['work_photo'] ?? '',
|
||||
'sn' => $coach['sn'] ?? '',
|
||||
'mobile'=> $coach['mobile'],
|
||||
];
|
||||
// }
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 取消订单
|
||||
* @param $params
|
||||
* @return bool|string
|
||||
* @author ljj
|
||||
* @date 2022/2/28 11:36 上午
|
||||
*/
|
||||
public function cancel($params)
|
||||
{
|
||||
// 启动事务
|
||||
Db::startTrans();
|
||||
try {
|
||||
|
||||
//TODO 已支付订单原路退回金额
|
||||
$order = Order::where('id',$params['id'])->findOrEmpty()->toArray();
|
||||
$totalRefundAmount = 0;
|
||||
if($order['pay_status'] == PayEnum::ISPAID) {
|
||||
$totalRefundAmount = $order['total_order_amount'];
|
||||
(new RefundLogic())->refund($order,$order['total_order_amount'],0,OrderRefundEnum::TYPE_USER,1,$params['user_id']);
|
||||
}
|
||||
//更新订单状态
|
||||
Order::update([
|
||||
'total_refund_amount' => $totalRefundAmount,
|
||||
'order_status' => OrderEnum::ORDER_STATUS_CLOSE,
|
||||
'cancel_time' => time(),
|
||||
],['id'=>$params['id']]);
|
||||
|
||||
//添加订单日志
|
||||
(new OrderLogLogic())->record(OrderLogEnum::TYPE_USER,OrderLogEnum::USER_CANCEL_ORDER,$params['id'],$params['user_id']);
|
||||
//取消订单-通知用户
|
||||
event('Notice', [
|
||||
'scene_id' => NoticeEnum::ORDER_CANCEL_NOTICE,
|
||||
'params' => [
|
||||
'user_id' => $order['user_id'],
|
||||
'order_id' => $order['id']
|
||||
]
|
||||
]);
|
||||
//取消订单-通知师傅
|
||||
event('Notice', [
|
||||
'scene_id' => NoticeEnum::ORDER_CANCEL_NOTICE_STAFF,
|
||||
'params' => [
|
||||
'coach_id' => $order['coach_id'],
|
||||
'order_id' => $order['id']
|
||||
]
|
||||
]);
|
||||
// 提交事务
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
// 回滚事务
|
||||
Db::rollback();
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 删除订单
|
||||
* @param $id
|
||||
* @return bool
|
||||
* @author ljj
|
||||
* @date 2022/2/28 11:50 上午
|
||||
*/
|
||||
public function del($id)
|
||||
{
|
||||
Order::destroy($id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 支付方式
|
||||
* @param $params
|
||||
* @return mixed
|
||||
* @author ljj
|
||||
* @date 2024/7/24 下午7:08
|
||||
*/
|
||||
public static function payWay($params)
|
||||
{
|
||||
try {
|
||||
// 获取待支付金额
|
||||
if ($params['from'] == 'order') {
|
||||
// 订单
|
||||
$order = Order::findOrEmpty($params['order_id'])->toArray();
|
||||
}
|
||||
if ($params['from'] == 'recharge') {
|
||||
// 充值
|
||||
$order = RechargeOrder::findOrEmpty($params['order_id'])->toArray();
|
||||
}
|
||||
|
||||
if ($params['from'] == 'orderGap') {
|
||||
// 补差价
|
||||
$order = OrderGap::findOrEmpty($params['order_id'])->toArray();
|
||||
}
|
||||
if ($params['from'] == 'orderAppend') {
|
||||
// 加钟
|
||||
$order = OrderAppend::findOrEmpty($params['order_id'])->toArray();
|
||||
}
|
||||
if (empty($order)) {
|
||||
throw new \Exception('订单不存在');
|
||||
}
|
||||
|
||||
// 获取订单剩余支付时间
|
||||
$cancelUnpaidOrders = ConfigService::get('transaction', 'cancel_unpaid_orders',1);
|
||||
$cancelUnpaidOrdersTimes = ConfigService::get('transaction', 'cancel_unpaid_orders_times',30);
|
||||
$cancelTime = 0;
|
||||
if(!in_array($params['from'],['order_gap','order_append'])){
|
||||
if (empty($cancelUnpaidOrders)) {
|
||||
// 不自动取消待支付订单
|
||||
$cancelTime = 0;
|
||||
} else {
|
||||
// 指定时间内取消待支付订单
|
||||
$cancelTime = strtotime($order['create_time']) + intval($cancelUnpaidOrdersTimes) * 60;
|
||||
}
|
||||
}
|
||||
$pay_way = PayWay::alias('pw')
|
||||
->join('dev_pay dp', 'pw.pay_id = dp.id')
|
||||
->where(['pw.scene'=>$params['scene'],'pw.status'=>YesNoEnum::YES])
|
||||
->field('dp.id,dp.name,dp.pay_way,dp.image,pw.is_default')
|
||||
->order(['sort'=>'asc','id'=>'desc'])
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($pay_way as $k=>&$item) {
|
||||
if ($item['pay_way'] == PayEnum::BALANCE_PAY) {
|
||||
$user_money = User::where(['id' => $params['user_id']])->value('user_money');
|
||||
$item['extra'] = '可用余额:'.$user_money;
|
||||
}
|
||||
// 充值时去除余额支付
|
||||
if ($params['from'] == 'recharge' && $item['pay_way'] == PayEnum::BALANCE_PAY) {
|
||||
unset($pay_way[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'lists' => array_values($pay_way),
|
||||
'order_amount' => $order['order_amount'],
|
||||
'cancel_time' => $cancelTime,
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
self::setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取技师服务时间
|
||||
* @param $coachId
|
||||
* @param $goodsId
|
||||
* @return array|false
|
||||
* @author cjhao
|
||||
* @date 2024/11/26 22:44
|
||||
*/
|
||||
public function getCoachServerTime($coachId,$goodsId)
|
||||
{
|
||||
try {
|
||||
if(empty($coachId)){
|
||||
throw new Exception('请选择技师');
|
||||
}
|
||||
$coachServerTimeLists = \app\common\logic\CoachLogic::getCoachServerTime($coachId,$goodsId);
|
||||
$timeLists = [];
|
||||
// 获取当前日期的时间戳
|
||||
$currentDate = strtotime(date('Y-m-d'));
|
||||
// 获取明天和后天的时间戳
|
||||
$tomorrowDate = strtotime('tomorrow');
|
||||
$afterTomorrowDate = strtotime('+2 days',$currentDate);
|
||||
foreach ($coachServerTimeLists as $key => $serverTimeList){
|
||||
$timeTips = '';
|
||||
$timestamp = strtotime(date('Y-'.$key));
|
||||
if ($timestamp >=$currentDate && $timestamp <$tomorrowDate) {
|
||||
$timeTips = '今天';
|
||||
} elseif ($timestamp >=$tomorrowDate && $timestamp <$afterTomorrowDate) {
|
||||
$timeTips = '明天';
|
||||
} elseif ($timestamp >=$afterTomorrowDate && $timestamp < strtotime('+3 days',$currentDate)) {
|
||||
$timeTips = '后天';
|
||||
} else {
|
||||
$weekdays = array('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六');
|
||||
$weekdayIndex = date('w',$timestamp);
|
||||
$timeTips = $weekdays[$weekdayIndex];
|
||||
}
|
||||
$timeLists[] = [
|
||||
'time_date' => $key,
|
||||
'time_tips' => $timeTips,
|
||||
'time_lists' => $serverTimeList
|
||||
];
|
||||
|
||||
}
|
||||
return $timeLists;
|
||||
|
||||
}catch (Exception $e) {
|
||||
self::$error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 订单差价
|
||||
* @param array $params
|
||||
* @return array|false
|
||||
* @author cjhao
|
||||
* @date 2024/9/19 11:04
|
||||
*/
|
||||
public function orderGap(array $params)
|
||||
{
|
||||
// 启动事务
|
||||
// Db::startTrans();
|
||||
try {
|
||||
$order = Order::where(['id'=>$params['order_id'],'user_id'=>$params['user_id']])->findOrEmpty();
|
||||
if($order->isEmpty()){
|
||||
throw new Exception('订单不存在');
|
||||
}
|
||||
if(PayEnum::UNPAID == $order->pay_status){
|
||||
throw new Exception('当前订单未支付');
|
||||
}
|
||||
if(OrderEnum::ORDER_STATUS_SERVER_FINISH == $order->order_status){
|
||||
throw new Exception('订单已完成');
|
||||
}
|
||||
$orderGap = OrderGap::create([
|
||||
'sn' => generate_sn((new OrderGap()), 'sn'),
|
||||
'user_id' => $params['user_id'],
|
||||
'order_id' => $order->id,
|
||||
'order_amount' => $params['order_amount'],
|
||||
'remark' => $params['remark'],
|
||||
]);
|
||||
// 提交事务
|
||||
// Db::commit();
|
||||
return [
|
||||
'id' => $orderGap->id,
|
||||
'order_id' => $order->id,
|
||||
'sn' => $orderGap->sn,
|
||||
'type' => 'orderGap'
|
||||
];
|
||||
}catch (Exception $e){
|
||||
// Db::rollback();
|
||||
self::$error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 订单加钟
|
||||
* @param array $params
|
||||
* @return array|bool
|
||||
* @author cjhao
|
||||
* @date 2024/9/20 00:40
|
||||
*/
|
||||
public function orderAppend(array $params)
|
||||
{
|
||||
Db::startTrans();
|
||||
try {
|
||||
$order = Order::where(['id'=>$params['order_id'],'user_id'=>$params['user_id']])->findOrEmpty();
|
||||
if($order->isEmpty()){
|
||||
throw new Exception('订单不存在');
|
||||
}
|
||||
if(PayEnum::UNPAID == $order->pay_status){
|
||||
throw new Exception('当前订单未支付');
|
||||
}
|
||||
if(OrderEnum::ORDER_STATUS_SERVER_FINISH == $order->order_status){
|
||||
throw new Exception('订单已完成');
|
||||
}
|
||||
$goods = Goods::where(['id'=>$params['goods'][0]['id']])->findOrEmpty()->toArray();
|
||||
//加钟时长
|
||||
$overtimeDuration = $goods['overtime_duration'];
|
||||
//加钟价
|
||||
$overtimePrice = round($goods['overtime_price'] * $params['goods'][0]['goods_num'],2);
|
||||
$action = $params['action'] ?? 'settlement';
|
||||
if('settlement' === $action){
|
||||
return [
|
||||
'order_id' => $order->id,
|
||||
'goods_id' => $goods['id'],
|
||||
'goods_name' => $goods['name'],
|
||||
'goods_num' => (int)$params['goods'][0]['goods_num'],
|
||||
'duration' => $overtimeDuration,
|
||||
'goods_price' => $goods['overtime_price'],
|
||||
'order_amount' => $overtimePrice,
|
||||
];
|
||||
}
|
||||
$serverFinishTime = $order['server_finish_time'];
|
||||
$totalDurations = $overtimeDuration;
|
||||
//判断下订单也没有加时
|
||||
$totalDuration = OrderAppend::where(['order_id'=>$order->id,'pay_status'=>PayEnum::ISPAID])->sum('duration');
|
||||
if($totalDuration){
|
||||
$totalDurations += $totalDuration;
|
||||
}
|
||||
$serverTime = point_timestamps($serverFinishTime,$totalDurations*60*$params['goods'][0]['goods_num']);
|
||||
$dateTime = date('m-d',$serverFinishTime);
|
||||
$coachServerTime = \app\common\logic\CoachLogic::getCoachServerTime($order['coach_id'])[$dateTime] ?? [];
|
||||
$coachServerTime = array_column($coachServerTime,null,'time');
|
||||
foreach ($serverTime as $key => $time){
|
||||
|
||||
$coachTime = $coachServerTime[$time['time']] ?? [];
|
||||
if(empty($coachTime)){
|
||||
throw new Exception('技师当前占无时间段可预约');
|
||||
}
|
||||
//开始时间是重叠的,第一个key不判断
|
||||
if(0 != $key && 3 == $coachTime['status']){
|
||||
throw new Exception('当前时段已被预约');
|
||||
}
|
||||
if(2 == $coachTime['status']){
|
||||
throw new Exception( '当前时段技师在休息');
|
||||
}
|
||||
}
|
||||
$orderAppend = OrderAppend::create([
|
||||
'sn' => generate_sn((new OrderAppend()), 'sn'),
|
||||
'user_id' => $params['user_id'],
|
||||
'order_id' => $order->id,
|
||||
'goods_id' => $goods['id'],
|
||||
'goods_name' => $goods['name'],
|
||||
'goods_image' => $goods['image'],
|
||||
'goods_num' => $params['goods'][0]['goods_num'],
|
||||
'goods_price' => $goods['overtime_price'],
|
||||
'goods_snap' => $goods,
|
||||
'order_amount' => $overtimePrice,
|
||||
'duration' => $overtimeDuration,
|
||||
]);
|
||||
|
||||
Db::commit();
|
||||
return [
|
||||
'id' => $orderAppend->id,
|
||||
'order_id' => $order->id,
|
||||
'sn' => $orderAppend->sn,
|
||||
'type' => 'orderAppend'
|
||||
];
|
||||
}catch (Exception $e){
|
||||
Db::rollback();
|
||||
self::$error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 订单评论
|
||||
* @param $params
|
||||
* @return false|void
|
||||
* @author cjhao
|
||||
* @date 2024/9/24 20:45
|
||||
*/
|
||||
public function comment($params)
|
||||
{
|
||||
Db::startTrans();
|
||||
try {
|
||||
$order = Order::where(['id'=>$params['id'],'user_id'=>$params['user_id']])->with(['order_goods'])->findOrEmpty();
|
||||
if($order->isEmpty()){
|
||||
throw new Exception('订单不存在');
|
||||
}
|
||||
if(OrderEnum::ORDER_STATUS_SERVER_FINISH != $order->order_status){
|
||||
throw new Exception('订单未完成服务,不能评论');
|
||||
}
|
||||
$comment = GoodsComment::where(['order_goods_id'=>$order['order_goods'][0]['id']])->findOrEmpty();
|
||||
if(!$comment->isEmpty()){
|
||||
throw new Exception('订单已评论');
|
||||
}
|
||||
$goodsComment = GoodsComment::create([
|
||||
'goods_id' => $order['order_goods'][0]['goods_id'],
|
||||
'user_id' => $params['user_id'],
|
||||
'order_goods_id' => $order['order_goods'][0]['id'],
|
||||
'service_comment' => $params['service_comment'],
|
||||
'comment' => $params['content'],
|
||||
]);
|
||||
$imageLists = $params['image_lists'] ?? [];
|
||||
if($imageLists){
|
||||
$commentImage = [];
|
||||
foreach ($imageLists as $image){
|
||||
$commentImage[] = [
|
||||
'comment_id' => $goodsComment['id'],
|
||||
'uri' => $image,
|
||||
];
|
||||
}
|
||||
(new GoodsCommentImage())->saveAll($commentImage);
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
return true;
|
||||
}catch (Exception $e){
|
||||
Db::rollback();
|
||||
self::$error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 下单前验证
|
||||
* @param $params
|
||||
* @return true
|
||||
* @author cjhao
|
||||
* @date 2025/4/27 10:56
|
||||
*/
|
||||
public function submitOrderCheck($params)
|
||||
{
|
||||
//验证在默认使用地址的情况下,默认地址是否可用
|
||||
$city = $params['city'] ?? '';
|
||||
$userAddress = $params['address'] ?? [];
|
||||
$coach = $params['coach'] ?? [];
|
||||
$goodsCityLists = $params['city_lists'] ?? [];
|
||||
if(empty($params['address_id'])){
|
||||
if(empty($city)){
|
||||
throw new Exception('当前城市未开通出行方式,请联系管理员');
|
||||
}
|
||||
if(true !== $goodsCityLists && !in_array($userAddress['city_id'],$goodsCityLists)){
|
||||
throw new Exception('抱歉,商品暂不支持该服务地址');
|
||||
}
|
||||
$coachServerScope = ConfigService::get('server_setting', 'coach_server_scope');
|
||||
if($coach['distance'] > $coachServerScope){
|
||||
throw new Exception('当前最大服务范围'.$coachServerScope.'公里,请重新选择地址');
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user