Files
2026-03-11 18:24:59 +08:00

548 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\teamapi\logic;
use app\common\logic\BaseLogic;
use app\common\model\teamaster\Teamaster;
use app\common\model\teamaster\TeamasterUser;
use app\common\model\teamaster\TeamasterAddress;
use app\common\model\teastore\TeaStore;
use app\common\model\teastore\TeaStoreCity;
use app\common\model\teamaster\TeamasterCert;
use app\common\model\teamaster\TeamasterUserBank;
use app\common\model\teamaster\TeamasterLeaf;
use app\common\model\order\OrderTeamaster;
use app\common\model\order\OrderTeamasterLeaf;
use app\common\model\user\User;
use app\common\model\teamaster\TeamasterAccountLog;
use app\common\service\FileService;
use app\common\service\pay\WxRefundService;
use think\facade\Db;
use think\facade\Config;
class OrderLogic extends BaseLogic
{
public static function orderTeamList($post,$user_id){
$os = [28, 29, 30, 31, 32, 40, 41, 42, 43];
$od = "start_time desc";
// 优化判断逻辑:使用 !empty() 更简洁
if (!empty($post['order_status'])) {
$os = explode(",", $post['order_status']);
$od = "start_time asc";
}
// 优化:$s 应该初始化为空数组而不是空字符串
$s = [];
// 优化判断逻辑:使用 !empty() 更简洁
if (!empty($post['search'])) {
$a = $post['search'];
$s = ['address', 'like', '%' . $a . '%'];
}
$team_user = TeamasterUser::where('id', $user_id)->find();
$title = $team_user->nickname . '的预约单';
// 构建基础查询条件
$baseQuery = [
['del', '=', 0],
['team_user_id', '=', $user_id]
];
// 处理时间筛选逻辑
$timeQuery = [];
if (!empty($post['is_time']) && $post['is_time'] == 1) {
$todayStart = strtotime(date('Y-m-d'));
$tomorrowStart = $todayStart + 86400;
$timeQuery = [
['start_time', '>=', $todayStart],
['start_time', '<', $tomorrowStart]
];
}
// 优化count查询合并所有条件
$countQuery = OrderTeamaster::where($baseQuery)
->where($timeQuery)
->whereIn('order_status', $os);
// 如果有搜索条件,添加到查询
if (!empty($s)) {
$countQuery->where($s[0], $s[1], $s[2]);
}
$count = $countQuery->count();
// 优化数据查询:使用相同的查询条件
$listsQuery = OrderTeamaster::where($baseQuery)
->where($timeQuery)
->whereIn('order_status', $os);
// 如果有搜索条件,添加到查询
if (!empty($s)) {
$listsQuery->where($s[0], $s[1], $s[2]);
}
$lists = $listsQuery->field('id,server_type,day_time,address,order_status,longitude,latitude,start_time,end_time,store_id,team_income_price,pay_time')
->page($post['page'], $post['size'])
->order($od)
->select();
$timekeeping = 0;
// 支付时间 + 10分钟 = 固定的过期时间点
// 当前时间到过期时间点的剩余秒数
if ($lists) {
foreach ($lists as &$item) {
$expire_time = $item['pay_time'] + 600;
// 优化使用switch或更简洁的if结构
if ($item['order_status'] == 28) {
$timekeeping = $expire_time - time();
} elseif ($item['order_status'] == 29) {
$timekeeping = $item['start_time'] - time();
} elseif ($item['order_status'] == 30 || $item['order_status'] == 31) {
$timekeeping = $item['end_time'] - time();
}
// 优化:减少重复查询
if ($item['server_type'] == 1 && !empty($item['store_id'])) {
$store = TeaStore::where('id', $item['store_id'])->find();
$item['title'] = $store->name ?? '';
} elseif ($item['server_type'] == 2) {
$item['title'] = $title;
}
$item['timekeeping'] = $timekeeping;
$item['day_time'] = date('m-d', $item['day_time']);
$item['start_time'] = date('H:i', $item['start_time']); // 修正:应该是 H:i 而不是 H:s
$item['end_time'] = date('H:i', $item['end_time']); // 修正:应该是 H:i 而不是 H:s
}
}
$data = [
'list' => $lists,
'page' => $post['page'],
'size' => $post['size'],
'count' => $count,
'more' => is_more($count, $post['page'], $post['size'])
];
return $data;
}
public static function orderDetails($post,$user_id){
Db::startTrans();
try {
$team_user = TeamasterUser::where('id',$user_id)->find();
$item = OrderTeamaster::where('del',0)
->where('id',$post['id'])
->find();
if($item['server_type'] == 1){
$store = TeaStore::where('id',$item['store_id'])->find();
$item['title'] = $store->name;
}
$timekeeping = 0;
if($item['order_status'] == 28){
$timekeeping = time()-$item['pay_time'];
}elseif ($item['order_status'] == 29||$item['order_status'] == 30){
$timekeeping = $item['start_time']-time();
}elseif ($item['order_status'] == 31){
$timekeeping = $item['end_time']-time();
}
$order_leaf = OrderTeamasterLeaf::where('order_id',$item['id'])->select();
$leaf_name = [];
foreach ($order_leaf as &$v){
$leaf_name[] = $v['leaf_name'].'('.$v['num'].')泡';
}
$user = User::where('id',$item['user_id'])->find();
$item['user_mobile'] = $user['mobile'];
$item['timekeeping'] =$timekeeping;
$item['leaf_name'] = implode(',',$leaf_name);
$item['title'] = $team_user->nickname.'的预约单';
$item['day_time'] = date('m-d', $item['day_time']);
$item['start_time'] = date('H:i', $item['start_time']);
$item['end_time'] = date('H:i', $item['end_time']);
$item['pay_time'] = date('Y-m-d H:i', $item['pay_time']);
$item['dtime'] = date('Y-m-d H:i', $item['dtime']);
$item['refund_time'] = date('Y-m-d H:i', $item['refund_time']);
$item['take_order_time'] = date('Y-m-d H:i', $item['take_order_time']);
$item['img_time'] = date('Y-m-d H:i', $item['img_time']);
$item['img'] = FileService::getImgUrl($item['img']);
$item['pay_way_title'] = '';
if($item['pay_way'] == 1){
$item['pay_way_title'] = "平台余额支付";
}
if($item['pay_way'] == 2){
$item['pay_way_title'] = "微信支付";
}
Db::commit();
return $item->toarray();
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderTake($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'order_status'=>28,
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误,请刷新页面');
}
$order->order_status = 29;
$order->take_order_time =time();
$order->save();
Db::commit();
return [];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderCancel($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'order_status'=>28,
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误');
}
$WxRefundService = new WxRefundService();
$result =$WxRefundService->Refund($order,10,40);
Db::commit();
return [];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderDepart($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'order_status'=>29,
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误,请刷新页面');
}
$order->order_status = 30;
$order->travel_time =time();
$order->save();
Db::commit();
return [
];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderArrive($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'order_status'=>30,
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误,请刷新页面');
}
$lat1 = $post['longitude'];
$lng1 = $post['latitude'];
$lat2 = $order['longitude'];
$lng2 = $order['latitude'];
$distance = self::getAccurateDistance($lat1, $lng1, $lat2, $lng2, 'km');
if($distance>2){
throw new \Exception('未到达打卡距离');
}
$order->order_status = 31;
$order->arrival_time =time();
$order->save();
Db::commit();
return [];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderImage($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'order_status'=>31,
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误,请刷新页面');
}
if($order['is_img'] == 1){
throw new \Exception('已打卡');
}
$end_time = time()+(3600*($order->hours+$order->renew_hour));
$order->img_time =time();
$order->img = $post['img'];
$order->start_time = time();
$order->end_time = $end_time;
$order->is_img = 1;
$order->save();
Db::commit();
return [];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderFinish($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'order_status'=>31,
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误');
}
if($order['end_time']>time()){
throw new \Exception('订单还未结束');
}
if($order['is_img'] == 0){
throw new \Exception('还未打卡,请先打卡');
}
$team_user = TeamasterUser::where('id',$user_id)->find();
$team_income_price = $order->team_income_price+(($order->renew_price+$order->renew_tea_price)*0.65);
$order->order_status = 32;
$order->save();
$reserve = [
'team_user_id'=>$user_id,
'user_id'=>$order->user_id,
'change_object'=>$order->pay_way,
'change_type'=>1,
'action'=>1,
'before_amount'=>$team_user->user_money,
'after_amount'=>$team_user->user_money+$order->team_income_price,
'amount'=>$order->team_income_price,
'source_sn'=>$order->order_sn,
'remark'=>'茶艺师预定订单',
'status'=>1,
'create_time'=>time()
];
TeamasterAccountLog::create($reserve);
$team_user->user_money = $team_user->user_money + round($team_income_price,2);
$team_user->save();
Db::commit();
return [];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function orderDel($post,$user_id){
Db::startTrans();
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'del'=>0
])->find();
if(!$order){
throw new \Exception('订单错误,请刷新页面');
}
$order->uptime =time();
$order->del = 1;
$order->save();
Db::commit();
return [
];
} catch (\Exception $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
public static function amountDetails($post,$user_id){
try {
$order = OrderTeamaster::where([
'id'=>$post['id'],
'del'=>0
])->find();
$all_amount = $order->order_amount+$order->renew_price+$order->renew_tea_price;
$team_income_price = $order->team_income_price+(($order->renew_price+$order->renew_tea_price)*0.65);
$data = [
'server_price'=>$order->server_price,
'mileage_price'=>$order->mileage_price,
'server_all_price'=>$order->server_all_price+$order->renew_price,
'mileage_server_price'=>$order->mileage_server_price,
'hours'=>$order->hours+$order->renew_hour,
'tea_price'=>$order->tea_price+$order->renew_tea_price,
'teacup_price'=>$order->teacup_price,
'renew_price'=>$order->renew_price,
'renew_tea_price'=>$order->renew_tea_price,
'handling_fee'=>round($all_amount-$team_income_price,2),
'team_income_price'=>round($team_income_price,2),
'distance'=>$order->distance,
'all_amount'=>$all_amount,
'coupon_price'=>$order->coupon_price,
'tea_all_price'=>$order->renew_tea_price+$order->tea_price+$order->teacup_price
];
return $data;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* 使用WGS84椭球模型计算距离Vincenty公式
* 精度:毫米级
*/
public static function getAccurateDistance($lat1, $lng1, $lat2, $lng2, $unit = 'm')
{
// WGS84椭球参数
$a = 6378137.0; // 长半轴(米)
$b = 6356752.314245; // 短半轴(米)
$f = 1 / 298.257223563; // 扁率
// 转换为弧度
$U1 = atan((1 - $f) * tan(deg2rad($lat1)));
$U2 = atan((1 - $f) * tan(deg2rad($lat2)));
$L = deg2rad($lng2 - $lng1);
$sinU1 = sin($U1);
$cosU1 = cos($U1);
$sinU2 = sin($U2);
$cosU2 = cos($U2);
$lambda = $L;
$lambdaP = 2 * M_PI;
$iterLimit = 100;
$sinLambda = 0;
$cosLambda = 0;
$sinSigma = 0;
$cosSigma = 0;
$sigma = 0;
$sinAlpha = 0;
$cosSqAlpha = 0;
$cos2SigmaM = 0;
while (abs($lambda - $lambdaP) > 1e-12 && --$iterLimit > 0) {
$sinLambda = sin($lambda);
$cosLambda = cos($lambda);
$sinSigma = sqrt(
($cosU2 * $sinLambda) * ($cosU2 * $sinLambda) +
($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda) *
($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda)
);
if ($sinSigma == 0) {
return 0; // 重合点
}
$cosSigma = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosLambda;
$sigma = atan2($sinSigma, $cosSigma);
$sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma;
$cosSqAlpha = 1 - $sinAlpha * $sinAlpha;
$cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha;
if (is_nan($cos2SigmaM)) {
$cos2SigmaM = 0;
}
$C = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha));
$lambdaP = $lambda;
$lambda = $L + (1 - $C) * $f * $sinAlpha *
($sigma + $C * $sinSigma *
($cos2SigmaM + $C * $cosSigma *
(-1 + 2 * $cos2SigmaM * $cos2SigmaM)));
}
if ($iterLimit == 0) {
return NAN; // 公式未收敛
}
$uSq = $cosSqAlpha * ($a * $a - $b * $b) / ($b * $b);
$A = 1 + $uSq / 16384 * (4096 + $uSq * (-768 + $uSq * (320 - 175 * $uSq)));
$B = $uSq / 1024 * (256 + $uSq * (-128 + $uSq * (74 - 47 * $uSq)));
$deltaSigma = $B * $sinSigma *
($cos2SigmaM + $B / 4 *
($cosSigma * (-1 + 2 * $cos2SigmaM * $cos2SigmaM) -
$B / 6 * $cos2SigmaM * (-3 + 4 * $sinSigma * $sinSigma) *
(-3 + 4 * $cos2SigmaM * $cos2SigmaM)));
$distance = $b * $A * ($sigma - $deltaSigma);
// 单位转换
switch (strtolower($unit)) {
case 'km':
return $distance / 1000;
case 'mile':
return $distance / 1609.344;
default:
return $distance;
}
}
}