travel/service/app/admin/controller/OrderController.php

627 lines
23 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\admin\controller;
require_once(__DIR__.'/xlsxwriter.class.php');
use app\model\Admins;
use app\model\Backs;
use app\model\Follows;
use app\model\Orders;
use app\model\Logs;
use app\model\ThirdMobileLogs;
use app\server\AliCloudApiService;
use app\server\Orders as ServerOrders;
use stdClass;
use support\Log;
use support\Redis;
use support\Request;
use think\facade\Db;
class OrderController extends base
{
public function index(Request $request) {
$sn = $request->get('sn');
$timetype = $request->get('timetype');
$times = $request->get('times');
$os_status = $request->get('os_status');
$where = [];
if(!$request->admin->is_super) {
$where = [['admin_id','=', $request->admin->id]];
} else {
$where = [['admin_id', '!=', 0]];
}
if($sn) {
$where[] = ['sn','=', $sn];
}
// if (in_array($appointment_status, [0, 1])) {
// $where[] = ['appointment_status', '=', $appointment_status];
// }
$status = $request->get('status', null);
$query = Orders::attimes($timetype, $times)->with(['admin','anchor','backs', 'mobileInfo'])->where($where)
->order('create_at','desc')
->order('update_time','desc')
->order('id','desc');
if($os_status) {
if ($os_status[0] == array_search(Orders::OSS[4],Orders::OSS)){
if (isset($os_status[1]) && is_numeric($os_status[1])) {
$query->whereRaw(Orders::AllOssStatusSql[$os_status[1]]);
}
}else{
if (isset($os_status[0]) && is_numeric($os_status[0])) {
$query->where('os', $os_status[0]);
}
if (isset($os_status[1]) && is_numeric($os_status[1])) {
$query->where('order_status', $os_status[1]);
}
}
}
if($status!=null && $status >= 0) {
$query->where('status', $status);
}
$appointment_status = $request->get('appointment_status', null);
if($appointment_status!=null && $appointment_status >= 0) {
$query->where('appointment_status', $appointment_status);
}
$mobile = $request->get('mobile');
if($mobile){
$query->where('mobile','like', '%'.$mobile.'%');
}
$productName = $request->get('product_name');
if($productName){
$query->where('product_name','like', '%'.$productName.'%');
}
$zhubo = $request->get('zhubo');
if($zhubo){
$zhubo_id = Admins::where('username', $zhubo)->value('id');
$query->where('zhubo', $zhubo_id);
}
$admin = $request->get('admin');
if($admin){
$admin_id = Admins::where('username', $admin)->value('id');
$query->where('admin_id', $admin_id);
}
$excel = $request->get('excel');
if($excel == 1) {
$orders = $query->select();
$writer = new \XLSXWriter();
$writer->writeSheetHeader('Sheet1', ['电话'=>'string','平台'=>'string','直播'=>'string','订单号'=>'string','下单时间'=>'string','状态'=>'string','跟进状态'=>'string',
'标题'=>'string','跟进备注'=>'string','联系人'=>'string','出行时间'=>'string','回来时间'=>'string',
'跟进时间'=>'string',
'总金额'=>'price','支付金额'=>'price','核销金额'=>'price','人数'=>'integer','跟单人'=>'string','主播'=>'string']);
foreach($orders as $order) {
$writer->writeSheetRow('Sheet1', [$order->mobile, $order->os_name, $order->is_zhibo, "$order->sn", date('Y-m-d H:i:s', intval($order->create_at/1000)),$order->order_status_name, $order->status_name,
$order->product_name, $order->remark, $order->contact, $order->travel_date, $order->travel_end,
$order->last_follow ? date('Y-m-d H:i:s', intval($order->last_follow/1000)):'',
$order->total_price/100, $order->actual_price/100, $order->asset_price/100, $order->quantity, $order->admin->username ?? '', $order->anchor->username ?? '']);
}
$file_name = "订单导出-".date('Ymd-His').".xlsx";
$response = response();
$c = $writer->writeToString();
$response->withHeaders([
'Content-Type' => 'application/force-download',
'Content-Disposition' => 'attachment; filename="'.$file_name.'"',
'Content-Transfer-Encoding' => 'binary',
'Cache-Control' => 'max-age=0',
])->withBody($c);
return $response;
// return;
}else{
$orders = $query->paginate($request->get('limit',10));
}
foreach($orders as &$order) {
if(empty($order->personnel)) {
$order->personnel = new stdClass();
}
}
$list = $orders->visible(['admin' => ['username','name','avatar']])->hidden(['check_sn'])->append(['order_status_name','status_name','os_name']);
$localMobiles = [];
foreach ($list as &$value) {
$mobileInfo = $value['mobileInfo'] ?? '';
if (empty($value['mobileInfo'])) {
try {
if (isset($localMobiles[$value['mobile']])) {
// 防止重复查询第三方接口
$mobileInfo = $localMobiles[$value['mobile']];
} else {
$mobileInfo = (new AliCloudApiService())->getMobileArea($value['mobile']);
$localMobiles[$value['mobile']] = $mobileInfo;
}
} catch (\Exception $exception) {
$mobileInfo = [];
Log::info('查询手机归属地失败:' . $exception->getMessage());
}
}
$value['mobileInfo'] = $mobileInfo;
}
$_oss = [];
foreach (Orders::OSS as $key=>$os) {
$_oss[$key] = ['label' => $os,'value' => $key];
if($key == 1) {
$statss = Orders::OrderStatus;
}elseif($key ==2) {
$statss = Orders::KuaishouStatus;
}elseif($key ==3) {
$statss = Orders::DouyinStatus;
}elseif ($key == 4) {
$statss = Orders::AllOssStatus;
}elseif($key ==5) {
$statss = Orders::DouyinStatus;
}elseif($key ==6) {
$statss = Orders::TongchengStatus;
}
$_ch = [];
foreach($statss as $k=>$v) {
$_ch[] = ['label' => $v,'value' => $k];
}
$_oss[$key]['children'] = $_ch;
}
return $this->success($list,null,['timetype'=> Orders::timeType, 'oss' => array_values($_oss)]);
}
public function all(Request $request) {
$sn = $request->get('sn');
if($sn) {
$where[] = ['sn','=', $sn];
}
$orders = Orders::with(['admin'])->where($where)->order('update_time','desc')->order('create_at','desc')->order('id','desc')->paginate($request->get('limit',10));
return $this->success($orders->visible(['admin' => ['username','name','avatar']])->hidden(['mobile','check_sn'])->append(['order_status_name','status_name','os_name']));
}
public function pub(Request $request) {
$orders = Orders::where('admin_id', 0)->order('create_at','desc')->order('id','desc')->paginate($request->get('limit',10));
return $this->success($orders->hidden(['mobile','check_sn'])->append(['order_status_name','os_name']));
}
//公海领取订单
public function fish(Request $request) {
$id = $request->post('id');
if(empty($id) || intval($id) <=0) return $this->error(2001, '请提交id');
$order = Orders::find($id);
if($order->admin_id > 0 ) return $this->error(2002, '订单没有找到或者已经转移到其他人');
try{
Orders::fish($order->id, $request->admin->id);
return $this->success(null);
}catch(\Exception $e){
return $this->error(2003, '公海获取订单失败,订单没有找到或者已经转移到其他人');
}
}
public function info(Request $request) {
$id = $request->get('id');
if(empty($id) || intval($id) <=0) return $this->error(2001, '请提交id');
$where[] = ['id','=',$id];
if($request->admin->is_super == 0) {
$where[] = ['admin_id','=',$request->admin->id];
}
$item = Orders::where($where)->with(['follow.admin','finance'])->find();
if(empty($item)) {
return $this->error(2002, '订单没有找到或者已经转移到其他人');
}
Logs::see($item->id, $request->admin->id);
if(empty($item->personnel)) {
$item->personnel = new stdClass();
}
return $this->success($item->append(['order_status_name','os_name']));
}
//核销,跟单
public function save(Request $request) {
$id = $request->post('id');
$next_follow = $request->post('next_follow');
$check_sn = $request->post('check_sn');
$desc = $request->post('desc');
$status = $request->post('status');
$is_wechat = $request->post('is_wechat');
$personnel = $request->post('personnel');
$travel_date = $request->post('travel_date');
$travel_end = $request->post('travel_end');
if(empty($desc) || empty($status)) return $this->error(2004, '跟进说明需要填写!');
if(empty($personnel)) return $this->error(2004, '人员情况需要填写!');
if(empty($travel_date)) return $this->error(2004, '出游时间需要填写!');
if ($status == 1){
if(empty($next_follow)) return $this->error(2004, '下次跟进时间需要填写!');
}
if ($status == 2){
$next_follow = '';
if(empty($travel_end)) return $this->error(2004, '返回日期需要填写!');
if(empty($check_sn)) return $this->error(2004, '核销码需要填写!');
}
$lock = 'Travel:Order:'.$id.':lock';
$back = Redis::set($lock, $request->admin->id, 'EX', 6, 'NX');
if(!$back) return $this->error(2005, '锁定失败');
$item = Orders::where('id', $id)->where('admin_id', $request->admin->id)->find();
if(empty($item)) return $this->error(2006, '订单不存在');
if($item->admin_id != $request->admin->id) return $this->error(2007, '订单已经发生转移');
//if(!empty($travel_date) && empty($travel_end)) return $this->error(2008, '核销的订单请填写出行和返回时间');
Follows::create([
'admin_id' => $request->admin->id,
'order_id' => $item->id,
'status' => $status,
'desc' => $desc
]);
//放弃跟进
// if($status == 4) {
// $item->status = 0;
// $item->admin_id = 0;
// $item->remark = $desc;
// $item->save();
// return $this->success($item);
// }else{
//修改状态
$item->check_sn = $check_sn;
$item->status = $status;
!empty($travel_date) && empty($item->travel_date) ? $item->travel_date = date('Y-m-d', strtotime($travel_date)) : null;
!empty($travel_end) && empty($item->travel_end) ? $item->travel_end = date('Y-m-d', strtotime($travel_end)) : null;
$item->personnel = json_encode($personnel);
$item->is_wechat = $is_wechat? 1: 0;
$item->last_follow = microtime(true) * 1000;
$item->next_follow = strtotime($next_follow??'') * 1000;
$item->remark = $desc;
$back = $item->save();
// }
if($back) {
if ($item->check_sn) {
//通过命令行核销订单
Redis::LPUSH('Travel:Order:check:lits',json_encode([
'id' => $item->id,
'check_sn' => $item->check_sn
]));
// 限制只被录入一次
$has = Logs::where('admin_id', $request->admin->id)->whereIN('action',[2,3])->where('check_sn',$check_sn)->find();
if(empty($has)) {
Logs::pass($item->id, $request->admin->id, $check_sn);
}
}
if($item->is_wechat > 0 ) {
$has = Logs::where('admin_id', $request->admin->id)->where('order_id', $item->id)->where('action', 5)->find();
if(empty($has)) {
Logs::wechat($item->id, $request->admin->id);
}
}
return $this->success($item);
}else{
return $this->error(2008, '保存订单失败');
}
}
public function pass(Request $request) {
$check_sn = $request->post('check_sn');
if(!is_numeric($check_sn)) return $this->error(2008, '格式错误');
$has = Orders::where('check_sn', $check_sn)->find();
if($has) {
return $this->error(2008, '核销码已经被使用了');
}
//限制只被录入一次
$has = Logs::where('admin_id', $request->admin->id)->whereIN('action',[2,3])->where('check_sn', $check_sn)->find();
if(empty($has)) {
Logs::pass2($request->admin->id, $check_sn);
}
//通过命令行核销订单
Redis::LPUSH('Travel:Order:check:lits',json_encode([
'admin_id' => $request->admin->id,
'check_sn' => $check_sn
]));
return $this->success(null,'提交成功');
}
//把订单拉回
public function backlist(Request $request) {
$sn = $request->get('sn');
$status = $request->get('status',null);
$query = Backs::with(['into','outto','orders','apply'])->where(function($query) use($request) {
$query->where('admin_id', $request->admin->id)->WhereOr('admin', $request->admin->id);
})->order('update_time','desc')->order('id','desc');
if($sn) {
$order_id = Orders::where('sn', $sn)->value('id');
$query->where('order_id', $order_id);
}
if($status != null) {
$query->where('status', $status);
}
$backs = $query->paginate($request->get('limit',10));
foreach($backs as &$back){
if ($back->admin_id == $request->admin->id || $back->admin == $request->admin->id){
$back->self = 0;
if($back->apply_id == $request->admin->id) {
$back->self = 3;
}
}else{
$back->self = 1;
}
}
return $this->success($backs->append(['order_status_name','os_name']),null, Orders::OSS);
}
//把订单拉回
public function back(Request $request) {
$sn = $request->post('sn');
$os = $request->post('os');
$to_admin_id = $request->post('to_admin_id');
$admin_id = empty($to_admin_id) ? $request->admin->id : $to_admin_id;
if(empty($sn)) return $this->error(2001, '提交单号');
$item = Orders::where('sn', $sn)->where('os', $os)->find();
if(empty($item)) return $this->error(2002, '订单没有找到');
if($item->admin_id == $admin_id) return $this->error(2002, '订单已经在账号上,不需要再拉取!');
//管理员不用审批
$status = 0;
if ($request->admin->is_super == 1 || $request->admin->id == 1){
$status = 1;
}
$backs = [
'order_id' => $item->id,
'admin_id' => $admin_id,
'admin' => $item->admin_id,
'apply_id' => $request->admin->id,
'status' => $status
];
try {
Db::transaction(function() use ($backs,$item) {
Backs::create($backs);
Logs::todo($backs['order_id'], $backs['apply_id'], $backs['status'] == 1 ? 12 : 7,$item->sn);
if ($backs['status'] == 1){//管理员审批处理
Orders::where('id', $backs['order_id'])->where('admin_id', $backs['admin'])->update(['admin_id'=> $backs['admin_id']]);
$other = Backs::where('order_id', $backs['order_id'])->where('status', 0)->lock()->select();
foreach($other as $o) {
Backs::where('id', $o->id)->where('status', 0)->update(['status' => 3]);
Logs::todo($o->order_id, $o->admin, 10); //取消其他转单需求
}
}
});
}catch (\Exception $e){
return $this->error(2003, '创建拉回记录失败了');
}
return $this->success(true);
}
public function toBack(Request $request) {
$sn = $request->post('sn');
$os = $request->post('os');
$to_admin_id = $request->post('to_admin_id');
$admin_id = empty($to_admin_id) ? $request->admin->id : $to_admin_id;
if(empty($sn)) return $this->error(2001, '提交单号');
$item = Orders::where('sn', $sn)->where('os', $os)->find();
if(empty($item)) return $this->error(2002, '订单没有找到');
if($item->admin_id == $admin_id) return $this->error(2002, '订单已经在账号上,不需要再拉取!');
//管理员不用审批
$status = 0;
if ($request->admin->is_super == 1 || $request->admin->id == 1){
$status = 1;
}
$backs = [
'order_id' => $item->id,
'admin_id' => $admin_id,
'admin' => $item->admin_id,
'apply_id' => $request->admin->id,
'status' => $status
];
try {
Db::transaction(function() use ($backs,$item) {
Backs::create($backs);
Logs::todo($backs['order_id'], $backs['apply_id'], $backs['status'] == 1 ? 12 : 7,$item->sn);
if ($backs['status'] == 1){//管理员审批处理
Orders::where('id', $backs['order_id'])->where('admin_id', $backs['admin'])->update(['admin_id'=> $backs['admin_id']]);
$other = Backs::where('order_id', $backs['order_id'])->where('status', 0)->lock()->select();
foreach($other as $o) {
Backs::where('id', $o->id)->where('status', 0)->update(['status' => 3]);
Logs::todo($o->order_id, $o->admin, 10); //取消其他转单需求
}
}
});
}catch (\Exception $e){
return $this->error(2003, '创建拉回记录失败了');
}
return $this->success(true);
}
/**
* 同意操作
* @param Request $request
* @return \support\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function backpass(Request $request) {
$id = $request->post('id', 0);
$item = Backs::where('id', $id)->find();
if($item->status != 0) return $this->error(2004, '记录已经处理了.');
if($item->admin != $request->admin->id && $item->admin != $item->apply_id) return $this->error(2005, '管理员错误');
try {
Backs::change($item);
return $this->success('');
}catch(\Exception $e) {
return $this->error(2006, '确认失败了');
}
}
/**
* 拒绝操作
* @param Request $request
* @return \support\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function backrefuse(Request $request) {
$id = $request->post('id', 0);
$item = Backs::where('id', $id)->find();
if(empty($item)) return $this->error(2004, '记录没有找到.');
if($item->status != 0) return $this->error(2004, '记录已经处理了.');
if($item->admin != $request->admin->id && $item->admin != $item->apply_id) return $this->error(2005, '管理员错误');
try {
Backs::refuse($item);
return $this->success('');
}catch(\Exception $e) {
return $this->error(2006, '确认失败了');
}
}
/**
* 取消操作
* @param Request $request
* @return \support\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function backcancel(Request $request)
{
$id = $request->post('id', 0);
$item = Backs::where('id', $id)->find();
if(empty($item)) return $this->error(2004, '记录没有找到.');
if($item->status != 0) return $this->error(2004, '记录已经处理了.');
if($item->admin != $request->admin->id && $item->admin == $item->apply_id) return $this->error(2005, '管理员错误');
try {
Backs::cancel($item);
return $this->success('');
}catch(\Exception $e) {
return $this->error(2006, '确认失败了');
}
}
/**
* 一键修复订单问题
* @param Request $request
* @return \support\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function oneClickRepair(Request $request)
{
try {
$ids = $request->post('id', 0);
$idArr = explode(',', $ids);
$flow = [];
foreach ($idArr as $id) {
Log::info('同步订单ID' . $id);
$order = Orders::where('id', $id)->find();
if (empty($order)) {
return $this->error(2004, '记录没有找到.');
}
// 订单是待使用状态,先同步第三方状态
if (ServerOrders::isDaishiyong($order)) {
ServerOrders::syncFromThird($order);
$flow[] = "订单为待使用状态,已请求第三方进行同步。";
}
}
return $this->success(implode("\n", $flow));
}catch(\Exception $e) {
return $this->error(2006, '出错了:' . $e->getMessage());
}
}
/**
* 预约处理
* @param Request $request
* @return \support\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function changeAppointmentStatus(Request $request)
{
try {
$ids = $request->post('id', 0);
$idArr = explode(',', $ids);
$flow = [];
foreach ($idArr as $id) {
Log::info('同步订单ID' . $id);
$order = Orders::where('id', $id)->find();
if (empty($order)) {
return $this->error(2004, '记录没有找到.');
}
// 订单是待使用状态,先同步第三方状态
$order['appointment_status'] = 2;
$order->save();
}
return $this->success(implode("\n", $flow));
}catch(\Exception $e) {
return $this->error(2006, '出错了:' . $e->getMessage());
}
}
}