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

429 lines
17 KiB
PHP
Raw Permalink 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;
use app\model\Admins;
use app\model\Backs;
use app\model\Finances;
use app\model\Onlines;
use app\model\Orders;
use DateTime;
use Qiniu\Auth;
use support\Log;
use support\Redis;
use support\Request;
class IndexController extends base
{
public function isWork(Request $request)
{
Redis::set('CRM:USER:ONLINE:WATCH:' . $request->admin->id, time());
$lastTime = Redis::get('CRM:USER:ONLINE:' . $request->admin->id);
$end = Redis::hGet('CRM:USER:ONLINE:END', $request->admin->id);
if (!empty($lastTime) && time() - $lastTime <= 5 * 60) {
} elseif (empty($lastTime) && $end) {
$has = Onlines::where("admin_id", $request->admin->id)->order('id desc')->find();
if ($has && empty($has->end)) {
Onlines::where("id", $has->id)->update(['end' => $end]);
} else {
$start = Redis::hGet('CRM:USER:ONLINE', $request->admin->id);
//创建一个新的
Onlines::create([
'admin_id' => $request->admin->id,
'start' => $start,
'end' => $end
]);
}
//创建一个新的
Onlines::create([
'admin_id' => $request->admin->id,
'start' => time(),
'end' => 0
]);
} else {
//第一次,给建个新的
Onlines::create([
'admin_id' => $request->admin->id,
'start' => time(),
'end' => 0
]);
}
Redis::Set('CRM:USER:ONLINE:' . $request->admin->id, time(), 'ex', 10 * 60);
Redis::hSet('CRM:USER:ONLINE:END', $request->admin->id, time() + 60);
$new = Redis::get('CRM:USER:ONLINE:NEW:' . $request->admin->id);
Redis::del('CRM:USER:ONLINE:NEW:' . $request->admin->id);
$back = Redis::set('CRM:USER:ONLINE:FOLLOW:LOCK:' . $request->admin->id, time(), 'EX', 60, 'nx');
$follow = $backs = 0;
if ($back) {
$follow = Orders::where('admin_id', $request->admin->id)->whereBetween('next_follow', [1, (time() - 60) * 1000])->count();
$backs = Backs::where('admin', $request->admin->id)->where('status', 0)->count();
}
// 核销提醒
$orderWriteOff = Redis::get('CRM:USER:WRITE:OFF:' . $request->admin->id);
Redis::del('CRM:USER:WRITE:OFF:' . $request->admin->id);
// 跟进提醒
$followMessage = 0;
$followOrderId = '';
$appointmentNum = 0;
if ($request->admin->id > 1) {
$start = strtotime(date('Y-m-d')) * 1000;
$end = strtotime(date('Y-m-d', strtotime('+1 days'))) * 1000 - 1;
$followMessageList = Orders::where(['admin_id' => $request->admin->id])
->whereBetween('next_follow', [$start, $end])
->where('status', 1)
->field(['id'])
->select();
$followMessage = count($followMessageList);
if ($followMessage) {
$followOrderId = $followMessageList[0]['id'];
}
// 预约未处理数量
$appointmentNum = Orders::where(['admin_id' => $request->admin->id])
->where('appointment_status', 1)
->count();
}
return $this->success(['new' => $new ?? 0, 'follow' => $follow, 'back' => $backs, 'order_write_off' => $orderWriteOff, 'follow_message' => $followMessage, 'follow_order_id' => $followOrderId, 'appointment_num' => $appointmentNum]);
}
public function line()
{
$time = strtotime(date('Y-m-d'));
$data = [];
for ($i = 10; $i > 0; $i--) {
$_time = $time - 3600 * 24 * $i;
$d = Finances::whereBetween('create_time', [$_time, $_time + 24 * 3600 - 1])
->where('status', 1)
->fieldRaw('SUM(IF(type=1,`total`,0))/100 as total, SUM(IF(type=2,`total`,0))/100 as refund')
->find();
$d->date = date("m-d", $_time);
$data[] = $d;
}
$_data = [];
foreach ($data as $d) {
$_data['title'][] = trim($d->date);
$_data['total'][] = $d->total ?? 0;
$_data['refund'][] = abs($d->refund ?? 0);
}
return $this->success($_data);
}
public function orders(Request $request)
{
// 获取当天结束时间23:59:59
$currentTime = new DateTime();
$currentTime->setTime(23, 59, 59);
$endOfDayTimestamp = $currentTime->getTimestamp() * 1000;
// 获取前30天的开始时间00:00:00
$thirtyDaysAgo = new DateTime('-30 days');
$thirtyDaysAgo->setTime(0, 0, 0);
$startOfThirtyDaysAgoTimestamp = $thirtyDaysAgo->getTimestamp() * 1000;
// 获取前60天的开始时间00:00:00
$sixtyDaysAgo = new DateTime('-60 days');
$sixtyDaysAgo->setTime(0, 0, 0);
$startOfSixtyDaysAgoTimestamp = $sixtyDaysAgo->getTimestamp() * 1000;
// 获取前80天的开始时间00:00:00
$eightyDaysAgo = new DateTime('-80 days');
$eightyDaysAgo->setTime(0, 0, 0);
$startOfEightyDaysAgoTimestamp = $eightyDaysAgo->getTimestamp() * 1000;
/*SUM(IF(asset_price>0 AND status=2,1,0)) as asset,
SUM(IF(asset_price>0 AND status=2,asset_price,0)) as asset_price,*/
$order = Orders::where('sn', '>', 0)
->fieldRaw('
SUM(IF(status=0,1,0)) as wait,
SUM(IF(status=1,1,0)) as doing,
SUM(total_price) as total,
COUNT(id) as `all`,
SUM(CASE
WHEN (os in(1,7) AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os in (3,5) AND order_status = 1) THEN 1
ELSE 0
END) as tobeused,
SUM(CASE
WHEN (os in(1,7) AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os in (3,5) AND order_status = 1) THEN total_price
ELSE 0
END) as tobeused_price,
SUM(CASE
WHEN (os in(1,7) AND order_status = 4) OR (os in (3,5) AND order_status = 2) OR (os = 2 AND order_status = 5) THEN 1
ELSE 0
END) as asset,
SUM(CASE
WHEN (os in(1,7) AND order_status = 4) OR (os in (3,5) AND order_status = 2) OR (os = 2 AND order_status = 5) THEN asset_price
ELSE 0
END) as asset_price,
SUM(CASE
WHEN ((os in(1,7) AND status = 5) OR (os in (3,5) AND status = 4) OR (os = 2 AND status = 1)) THEN 1
ELSE 0
END) AS refund,
SUM(CASE
WHEN ((os in(1,7) AND status = 5) OR (os in (3,5) AND status = 4) OR (os = 2 AND status = 1)) THEN actual_price
ELSE 0
END) AS refund_price,
SUM(CASE
WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfThirtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN 1
ELSE 0
END) AS tobeused_30,
SUM(CASE
WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfThirtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN total_price
ELSE 0
END) AS tobeused_price_30,
SUM(CASE
WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfSixtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN 1
ELSE 0
END) AS tobeused_60,
SUM(CASE
WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfSixtyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN total_price
ELSE 0
END) AS tobeused_price_60,
SUM(CASE
WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfEightyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN 1
ELSE 0
END) AS tobeused_80,
SUM(CASE
WHEN ((os in(1,7) AND order_status=3) OR (os=2 AND order_status=4) OR (os in (3,5) AND order_status=1)) AND create_at >= ' . $startOfEightyDaysAgoTimestamp . ' AND create_at <= ' . $endOfDayTimestamp . ' THEN total_price
ELSE 0
END) AS tobeused_price_80
');
if ($request->admin->id != 1) {
$order = $order->where('admin_id', $request->admin->id);
}
$order = $order->find();
return $this->success([
'wait' => $order->wait ?? 0,
'doing' => $order->doing ?? 0,
'total' => $order->total ?? 0,
'all' => $order->all ?? 0,
'tobeused' => $order->tobeused ?? 0,
'tobeused_price' => $order->tobeused_price ?? 0,
'asset' => $order->asset ?? 0,
'asset_price' => $order->asset_price ?? 0,
'refund' => $order->refund ?? 0,
'refund_price' => $order->refund_price ?? 0,
'tobeused_30' => $order->tobeused_30 ?? 0,
'tobeused_price_30' => $order->tobeused_price_30 ?? 0.00,
'tobeused_60' => $order->tobeused_60 ?? 0,
'tobeused_price_60' => $order->tobeused_price_60 ?? 0.00,
'tobeused_80' => $order->tobeused_80 ?? 0,
'tobeused_price_80' => $order->tobeused_price_80 ?? 0.00
]);
}
public function pie()
{
$time = strtotime(date('Y-m-d'));
$_time = $time - 3600 * 24 * 10;
$data = Orders::whereBetween('create_time', [$_time, time()])->fieldRaw('sum(total_price) as value, status')->group('status')->select();
$ddd = [];
foreach (Orders::StatusName as $k => $d) {
$item['name'] = $d;
$item['value'] = 0;
foreach ($data as $dd) {
if ($dd->status == $k) {
$item['value'] = $dd->value / 100;
break;
}
}
$ddd[] = $item;
}
return $this->success($ddd);
}
public function Info(Request $request)
{
$info = Admins::where('id', $request->admin->id)->find();
$roles = ['editor'];
if ($info->is_super) {
$roles = ['admin'];
}
if ($info->is_franchisee) {
$roles = ['franchisee'];
}
return $this->success([
'roles' => $roles,
'avatar' => $info->avatar ?? '/avatar.webp',
'name' => $info->name,
'is_anchor' => $info->is_anchor ? 1 : 0,
'oss' => Orders::OSS
]);
}
public function qiniu()
{
// 用于签名的公钥和私钥
$accessKey = config('qiniu.accessKey');
$secretKey = config('qiniu.secretKey');
// 初始化签权对象
$auth = new Auth($accessKey, $secretKey);
$bucket = 'tt-api';
$key = 'imgs/' . Date('Ym/d-His') . '.jpg';
// 生成上传Token
$token = $auth->uploadToken($bucket);
return $this->success(['qiniu_key' => $key, 'qiniu_token' => $token, 'qiniu_url' => 'http://up-z2.qiniup.com']);
}
public function avatar(Request $request)
{
$file = $request->file("file");
$filename = '/uploads/avatar/' . $request->admin->id . '.' . $file->getUploadExtension();
$file->move(public_path() . $filename);
$item = Admins::where('id', $request->admin->id)->find();
$item->avatar = $filename;
$item->save();
return $this->success($filename);
}
public function productNameList(Request $request)
{
$limit = $request->get('limit', 10);
$product_name = $request->get('product_name');
$os = $request->get('os_status');
$times = $request->get('times');
$list = Orders::where('id','>',0)
->fieldRaw('
os,product_name,
SUM(IF(status=0,1,0)) as wait,
SUM(IF(status=1,1,0)) as doing,
SUM(total_price) as total,
count(id) as `all`,
SUM(CASE
WHEN (os = 1 AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os = 3 AND order_status = 1) THEN 1
ELSE 0
END) as tobeused,
SUM(CASE
WHEN (os = 1 AND order_status = 3) OR (os = 2 AND order_status = 4) OR (os = 3 AND order_status = 1) THEN total_price
ELSE 0
END) as tobeused_price,
SUM(CASE
WHEN (os = 1 AND order_status = 4) OR (os = 3 AND order_status = 2) OR (os = 2 AND order_status = 5) THEN 1
ELSE 0
END) as asset,
SUM(CASE
WHEN (os = 1 AND order_status = 4) OR (os = 3 AND order_status = 2) OR (os = 2 AND order_status = 5) THEN asset_price
ELSE 0
END) as asset_price,
SUM(CASE
WHEN (os = 1 AND order_status = 5) OR (os = 3 AND order_status = 4) OR (os = 2 AND order_status = 1) THEN 1
ELSE 0
END) AS refund,
SUM(CASE
WHEN (os = 1 AND order_status = 5) OR (os = 3 AND order_status = 4) OR (os = 2 AND order_status = 1) THEN actual_price
ELSE 0
END) AS refund_price
')
->group('os,product_name')
->order('all desc');
if ($request->admin->id !=1){
$list = $list->where('admin_id', $request->admin->id);
}
if($times) {
if (is_string($times)) {
$times = explode(',', $times);
}
$list = $list->whereBetween('create_at',[strtotime($times[0])*1000,strtotime($times[1])*1000+999]);
}
if (!empty($os)){
$list = $list->where('os',$os);
}
if (!empty($product_name)){
$list = $list->where('product_name','like','%'.$product_name.'%');
}
$excel = $request->get('excel');
if($excel == 1) {
$orderProducts = $list->select();
$writer = new \XLSXWriter();
$writer->writeSheetHeader('产品列表', [
'产品名称' => 'string',
'平台' => 'string',
'订单数' => 'integer',
'订单金额' => 'price',
'待更进' => 'integer',
'跟进中' => 'integer',
'待使用' => 'integer',
'待使用金额' => 'price',
'核销数' => 'integer',
'核销金额' => 'price',
'退款数' => 'integer',
'退款金额' => 'price',
'核销率' => 'string',
'退款率' => 'string',
]);
$osList = [
1 => '美团',
2 => '快手',
3 => '抖音',
];
bcscale(2);
foreach($orderProducts as $product) {
$writer->writeSheetRow('产品列表', [
$product->product_name,
$osList[$product->os] ?? '',
$product->all,
bcdiv($product->total, 100),
$product->wait,
$product->doing,
$product->tobeused,
bcdiv($product->tobeused_price, 100),
$product->asset,
bcdiv($product->asset_price, 100),
$product->refund,
bcdiv($product->refund_price, 100),
number_format(($product['asset']/$product['all'])*100,2) . '%',
number_format(($product['refund']/$product['all'])*100,2) . '%',
]);
}
$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;
}
$list = $list->paginate($limit)->toArray();
foreach ($list['data'] as &$item) {
// $item['refund_rate'] = bcmul(bcdiv((string)$item['refund'], (string)$item['all'], 4), '100', 2);
// $item['asset_rate'] = bcmul(bcdiv((string)$item['asset'], (string)$item['all'], 4), '100', 2);
$item['refund_rate'] = number_format(($item['refund']/$item['all'])*100,2);
$item['asset_rate'] = number_format(($item['asset']/$item['all'])*100,2);;
}
return $this->success($list);
}
}