Files
crm-server/app/controller/CustomerController.php
T
2025-08-29 18:49:42 +08:00

731 lines
23 KiB
PHP

<?php
namespace app\controller;
use app\model\Channel;
use app\model\Corp;
use app\model\Customer;
use app\model\CustomerHis;
use app\model\Follow;
use app\model\InquiryLog;
use app\model\User;
use app\service\UserService;
use app\util\Util;
use config\constants\Constants;
use Illuminate\Database\Eloquent\Builder;
use support\Log;
use support\Request;
class CustomerController
{
/**
* 不需要登录的方法
*/
protected $noNeedLogin = ['collect'];
/**
* 客户分级
* @param Request $request
* @return \support\Response
*/
public function getGrade(Request $request)
{
$grade = [];
$gradeConstants = Constants::GRADE_EN;
//$language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
if($language == 'zh_CN'){
$gradeConstants = Constants::GRADE;
}elseif ($language == 'ru'){
$gradeConstants = Constants::GRADE_RU;
}
foreach ($gradeConstants as $key => $value) {
$grade[] = [
'id' => $key,
'name' => $value,
];
}
return Util::success($grade);
}
/**
* 商机
* @param Request $request
* @return \support\Response
*/
public function getMagnitude(Request $request)
{
$grade = [];
$magnitudeConstants = Constants::MAGNITUDE_EN;
//$language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
if($language == 'zh_CN'){
$magnitudeConstants = Constants::MAGNITUDE;
}elseif ($language == 'ru'){
$magnitudeConstants = Constants::MAGNITUDE_RU;
}
foreach ($magnitudeConstants as $key => $value) {
$grade[] = [
'id' => $key,
'name' => $value,
];
}
return Util::success($grade);
}
/**
* 客户渠道
* @param Request $request
* @return \support\Response
*/
public function getChannel(Request $request)
{
$list = Channel::getAll();
//$language = $request->user['language'];
//$language = 'zh_CN';
// $language = $request->language;
// if($language != 'zh_CN'){
// foreach ($list as &$value) {
// $value['name'] = $value['name_en'];
// }
// }elseif ($language == 'ru'){
// foreach ($list as &$value) {
// $value['name'] = $value['name_ru'];
// }
// }
return Util::success($list);
}
/**
* 待跟进客户列表
* @param Request $request
* @return \support\Response
*/
public function waitFollow(Request $request)
{
$userId = $request->user['id'];
$filter = Util::getParam($request, 'filter');
$page = $request->input('page', 1);
$perPage = $request->input('per_page', 10);
$where = [
['user_id', '=', $userId],
['follow_next', '<>', 0],
];
if($filter == 0){
$where[] = ['follow_next', '<=', time() + 3600 * 24];
}elseif($filter == 1){
$where[] = ['follow_next', '<=', time() + 3600 * 24*3];
}elseif($filter == 2){
$where[] = ['follow_next', '<=', time() + 3600 * 24*7];
}
$customer = Customer::where($where)
->whereNotNull('follow_next')
->orderBy('follow_next')
->paginate($perPage, ['*'], 'page', $page);
foreach ($customer as &$item) {
$item['follow_remaining'] = $item->follow_next-time();
$item['follow_next'] = date('Y-m-d H:i:s',$item->follow_next);
}
return Util::page($customer);
}
/**
* 客户列表
* @param Request $request
* @return \support\Response
*/
public function list(Request $request)
{
$page = $request->input('page', 1);
$perPage = $request->input('per_page', 10);
$follow = $request->input('follow', ''); //跟进状态
$keyword = $request->input('keyword', ''); //follow_last
$follow_last = $request->input('follow_last', ''); //最后跟进:1:当天跟进客户,2:近三天跟进客户,3:近七天跟进客户
$tagId = $request->input('tag_id', ''); //打有某个标签的客户
$countryId = $request->input('country_id', ''); //打有某个标签的客户
$seas = $request->input('seas', ''); //公海客户
$where = [];
$userId = $request->user['id'];
if (Util::isEmpty($userId)) {
return Util::fail(['user_id' => $userId], trans('user_none'));
}
// $where[] = ['type', 0];
if($seas == 'seas'){
$where[] = ['user_id', 0];
}else{
$where[] = ['user_id', $userId];
}
$where[] = ['status', 1];
if (!empty($countryId)){
$where[] = ['country_id', $countryId];
}
//验证权限
// if ($request->user['role'] != 1) {
// $where[] =['user_id',$userId] ;
// }
$grade = [];
if (!Util::isEmpty($follow) && $follow == 0) {
$where[] = ['grade', '<=', 2];
} elseif (!Util::isEmpty($follow) && $follow == 1) {
$grade = [3, 4];
} elseif (!Util::isEmpty($follow) && $follow == 2) {
$where[] = ['grade', '=', 5];
}
if (!Util::isEmpty($follow_last) && $follow_last == 0) {
$where[] = ['follow_last', '>', strtotime('-1 day')];
} elseif (!Util::isEmpty($follow_last) && $follow_last == 1) {
$where[] = ['follow_last', '>', strtotime('-3 day')];
} elseif (!Util::isEmpty($follow_last) && $follow_last == 2) {
$where[] = ['follow_last', '>', strtotime('-7 day')];
}
// 执行分页查询 //关联标签tags //关联标签及分组tags.group
$query = Customer::with('tags')->where($where)
->orderBy('crm_customer.id', 'desc');
if(!empty($tagId)){
//查询有$tagId 里任意一个标签的客户
// $query->whereHas('tags', function($query) use ($tagId){
// $query->where('tag.id', $tagId);
// });
//查询有$tagId 里所有标签的客户
$tagId = explode(',', $tagId);
foreach ($tagId as $id) {
$query->whereHas('tags', function($query) use ($id){
$query->where('tag_id', $id);
});
}
}
if (!Util::isEmpty($keyword)) {
$query->where(function ($query) use ($keyword) {
$query->where('contacts', 'like', "%{$keyword}%")
->orWhere('phone', 'like', "%{$keyword}%");
});
}
if (!Util::isEmpty($grade)) {
$query->whereIn('grade', $grade);
}
$recycle = Util::getParam($request,'recycle', '');
if ($recycle == 'recycle') {
$query->onlyTrashed();
}
if ($seas == 'seas') {
$user = User::where('id', $userId)->first();
$corpId = $user?$user->corp_id:0;
if($corpId == 1){
$query->whereIn('channel_id', [1,2,3,4,5,6,7,8]);
} elseif($corpId == 3) {
$query->whereIn('channel_id', [9,10,11]);
} else{
$query->whereIn('channel_id', [0]);
}
$query->withTrashed();
}
$data = $query->paginate($perPage, ['*'], 'page', $page);
foreach ($data->items() as &$value) {
$value = Customer::getCustomer($value, $request);
if($seas == 'seas'){
$value['phone'] = Util::mask($value['phone']);
$value['email'] = Util::mask($value['email']);
$value['WhatsApp'] = Util::mask($value['WhatsApp']);
$value['seas_time'] = time()-(empty($value['deleted_at'])?strtotime($value['updated_at']):strtotime($value['deleted_at']));
}
}
return Util::page($data);
}
/**
* 客户恢复
* @param Request $request
* @return \support\Response
*/
public function restore(Request $request)
{
$id = Util::getParam($request,'id', '');
if (Util::isEmpty($id)) {
return Util::fail([], trans('id_empty'));
}
$userId = $request->user['id'];
$where = [
'id' => $id,
'user_id' => $userId,
];
$res = Customer::where($where)->restore();
if($res){
return Util::success($res, trans('success'));
}else{
return Util::fail([], trans('fail'));
}
}
/**
* 客户详情
* @param Request $request
* @return \support\Response
*/
public function detail(Request $request)
{
$id = Util::getParam($request, 'id');
if (Util::isEmpty($id)) {
return Util::fail([], 'id' . trans('not_null'));
}
$res = Customer::with('tags')->select('id', 'user_id', 'grade', 'channel_id', 'car_type_id', 'country_id', 'magnitude', 'email', 'phone', 'WhatsApp', 'contacts', 'describe', 'address', 'lat', 'lng', 'follow_next', 'follow_remark', 'sex')
->where('id', $id)
->first();
if ($res) {
$res->toArray();
} else {
return Util::fail([], '记录不存在');
}
$res = Customer::getCustomer($res, $request, true);
return Util::success($res);
}
/**
* 客户录入
* @param Request $request
* @return \support\Response
*/
public function save(Request $request)
{
$id = Util::getParam($request, 'id');
$channel_id = Util::getParam($request, 'channel_id');
if (Util::isEmpty($channel_id)) {
return Util::fail([], trans('channel_not_null'));
}
$country_id = Util::getParam($request, 'country_id', 0);
if (Util::isEmpty($country_id)) {
// return Util::fail([],'country_id'.trans('not_null'));
}
// $car_type_id = Util::getParam($request, 'car_type_id');
// if (Util::isEmpty($car_type_id)) {
// return Util::fail([], trans('car_type_not_null'));
// }
$contacts = Util::getParam($request, 'contacts');
$email = Util::getParam($request, 'email');
$phone = Util::getParam($request, 'phone');
if (Util::isEmpty($contacts) && Util::isEmpty($email) && Util::isEmpty($phone)) {
return Util::fail([], trans('contacts_not_null'));
}
$user = User::where(['id' => $request->user['id']])->first();
$whatsApp = Util::getParam($request, 'WhatsApp', '');
$data = [
'user_id' => $request->user['id'],
'corp_id' => $user->corp_id,
'grade' => Util::getParam($request, 'grade', 0),
'channel_id' => $channel_id,
'country_id' => $country_id,
// 'car_type_id' => $car_type_id,
'magnitude' => Util::getParam($request, 'magnitude', 0),
'email' => $email,
'phone' => $phone,
'WhatsApp' => $whatsApp,
'contacts' => $contacts,
'describe' => Util::getParam($request, 'describe'),
'lat' => Util::getParam($request, 'lat', 0),
'lng' => Util::getParam($request, 'lng', 0),
'address' => Util::getParam($request, 'address', ''),
'sex' => Util::getParam($request, 'sex', 0),
];
if (Util::isEmpty($id)) {
$data['enter_user_id'] = $request->user->uid;
$distinct = [
'email' => $email,
'phone' => $phone,
'whatsapp' => $whatsApp,
];
$dis = $this->distinct($distinct, $user->corp_id);
if($dis){
return Util::fail([], '客户线索重复,已经有人在跟进');
}
$res = Customer::create($data);
} else {
unset($data['grade']);
$res = Customer::where('id', $id)
->update($data);
// Log::info('update', ['res' => $res]);
(!$res) ?: $res = Customer::find($id)->toArray();
}
if ($res) {
return Util::success($res, trans('save_success'));
} else {
return Util::fail($res, trans('save_fail'));
}
}
public function distinct($params, $corpId){
$customer = Customer::where('corp_id', $corpId)
->where((function (Builder $query) use ($params) {
if(!empty($params['email']))
$query->Orwhere('email', '=', $params['email']);
if(!empty($params['phone']))
$query->Orwhere('phone', '=', $params['phone']);
if(!empty($params['whatsApp']))
$query->Orwhere('whatsApp', '=', $params['whatsApp']);
return $query;
}))
->first();
if (!empty($customer)) {
return true;
}
return false;
}
/**
* 领取公海客户
* @param Request $request
* @return \support\Response
*/
public function claim(Request $request)
{
$customerId = Util::getParam($request, 'customer_id');
$userId = $request->user['id'];
if (Util::isEmpty($customerId)) {
return Util::fail([], trans('customer_id').trans('not_null'));
}
$user = User::where(['id' => $userId])->first();
$data = [
'user_id' => $request->user['id'],
'obtain' => time(),
'corp_id' => $user->corp_id,
];
$customer= Customer::withTrashed()->find($customerId);
if(empty($customer) || $customer->user_id != 0){
return Util::fail('', trans('claim_fail'));
}
$customer->restore();
$res = $customer->update($data);
//记录客户关系变化
$his = CustomerHis::create([
'customer_id' => $customerId,
'user_his' => 0,
'user_id' => $userId,
]);
self::inquiryUpdate($customer,$request->user['id']);
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
/**
* 询单修改
*/
public static function inquiryUpdate($customer,$userId = null)
{
if(empty($customer->sn) || $customer->type!=1){
return false;
}
$inquiryLog = InquiryLog::where('order_no', $customer->sn)->first();
if(empty($inquiryLog)){
return false;
}
$userId = $userId??$customer->user_id;
if ($userId == 0){
$inquiryLog->recipient = 0;
$inquiryLog->t_time = time();
$inquiryLog->status = 1;
$inquiryLog->r_time = time();
$inquiryLog->save();
}else {
$inquiryLog->recipient = $customer->user_id;
$inquiryLog->t_time = time();
$inquiryLog->save();
}
return true;
}
/**
* 批量转让
* @param Request $request
* @return \support\Response
*/
public function cede(Request $request)
{
$customerId = Util::getParam($request, 'customer_id');
$userId = Util::getParam($request, 'user_id');
$selfId = $request->user['id'];
if (Util::isEmpty($userId)) {
return Util::fail([], 'user_id'.trans('not_null'));
}
if (Util::isEmpty($customerId)) {
return Util::fail([], 'customer_id'.trans('not_null'));
}
$user = User::where(['id' => $userId])->first();
if (Util::isEmpty($user)) {
return Util::fail(null, trans('user_none'));
}
$query= Customer::where('user_id',$selfId)->where('id',$customerId);
$customer = $query->get();
foreach ($customer as $item) {
//记录客户关系变化
$his = CustomerHis::create([
'customer_id' => $item->id,
'user_his' => $item->user_id,
'user_id' => $user['id'],
]);
self::inquiryUpdate($customer,$user->id);
}
$data = [
'user_id' => $user->id,
'obtain' => time(),
];
$res = $query->update($data);
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
/**
* 跟进状态
* @param Request $request
* @return \support\Response
*/
public function grade(Request $request)
{
$id = Util::getParam($request, 'id');
$grade = Util::getParam($request, 'grade');
if (Util::isEmpty($id)) {
return Util::fail('', 'id' . trans('not_null'));
}
if (Util::isEmpty($id)) {
return Util::fail('', 'grade' . trans('not_null'));
}
$data = [
'grade' => $grade,
];
$res = Customer::where('id', $id)
->update($data);
if ($res) {
return Util::success($res, trans('save_success'));
} else {
return Util::fail($res, trans('save_fail'));
}
}
/**
* 更新下次跟进时间
* @param Request $request
* @return \support\Response
*/
public function followNext(Request $request)
{
$id = Util::getParam($request, 'id');
if (Util::isEmpty($id)) {
return Util::fail([], 'id' . trans('not_null'));
}
$data = [
'follow_next' => Util::getParam($request, 'follow_next', 0),
'follow_remark' => Util::getParam($request, 'follow_remark', 0),
'warn' => 0,
];
$res = Customer::where('id', $id)
->update($data);
if ($res) {
return Util::success($res, trans('save_success'));
} else {
return Util::fail($res, trans('save_fail'));
}
}
/**
* 删除客户
* @param Request $request
* @return \support\Response
*/
public function delete(Request $request)
{
$id = Util::getParam($request, 'id');
$force = Util::getParam($request, 'force','');
$userId = $request->user['id'];
$where = [
'id' => $id,
'user_id' => $userId,
];
$customer = Customer::where($where)->withTrashed()->first();
if(empty($customer)){
return Util::fail('', trans('fail'));
}
if($force == 'force'){
$res = $customer->forceDelete();
}else{
$res = $customer->delete();
}
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
/**
* 统计客户
* @param Request $request
* @return \support\Response
*/
public function statistics(Request $request)
{
$created = Util::getParam($request, 'created');
if (Util::isEmpty($created)) {
return Util::fail([], 'created' . trans('not_null'));
}
$userId = $request->user['id'];
$created_at = $request->user['created_at'];
$day = ceil((time() - $created_at + 1) / 60 / 60 / 24);
$where[] = ['user_id', '=', $userId];
$start = strtotime($created . '-01');
$year = date('Y', $start);
$month = date('n', $start); //获取月份
$end = mktime(00, 00, 00, $month + 1, 1, $year);
$where[] = ['created_at', '>=', $start];
$where[] = ['created_at', '<', $end];
$customer = Customer::where($where)->count();
//初步接触
$whereGrade = $where;
$whereGrade[] = ['grade', '<=', 2];
$customerInit = Customer::where($whereGrade)->count();
//跟进中
$customeroFllow = Customer::where($where)->whereIn('grade', [3, 4])->count();
//已成交
$whereGrade = $where;
$whereGrade[] = ['grade', '=', 5];
$customerDeal = Customer::where($whereGrade)->count();
//拜访数
$whereVisit = $where;
$whereVisit[] = ['type', '=', 0];
$visit = Follow::where($whereVisit)->distinct('customer_id')->count();
//跟进数
$whereVisit = $where;
$whereVisit[] = ['type', '=', 1];
$follow = Follow::where($whereVisit)->distinct('customer_id')->count();
$res = [
'customer' => $customer, //客户数
'visit' => $visit, //拜访
'follow' => $follow, //跟进
'day' => $day, //注册天数
'customer_init' => $customerInit, //初步接触
'customero_fllow' => $customeroFllow, //跟进中
'customer_deal' => $customerDeal, //已成交
];
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
/**
* 线索分配
* @param Request $request
* @return \support\Response
*/
public function collect(Request $request)
{
Log::info('receive collect start',$request->all());
$user_sn = Util::getParam($request, 'user_sn'); //用户sn
// $user_email = Util::getParam($request, 'user_email'); //邮箱
$user_id = Util::getParam($request, 'user_id'); //邮箱
$sn = Util::getParam($request, 'order_no'); //客户sn验证客户唯一性
$channel_id = Util::getParam($request, 'channel_id'); //渠道
$country_id = Util::getParam($request, 'country_id'); //国家
$magnitude = Util::getParam($request, 'magnitude'); //商机
$describe = Util::getParam($request, 'describe'); //客户详情
$phone = Util::getParam($request, 'phone'); //用户详情
$email = Util::getParam($request, 'email'); //用户详情
$WhatsApp = Util::getParam($request, 'WhatsApp');
$contacts = Util::getParam($request, 'contacts'); //联系人
if (Util::isEmpty($user_sn)) {
return Util::fail([], '用户sn不能为空');
}
if (Util::isEmpty($sn)) {
return Util::fail([], '客户sn不能为空');
}
// $user = UserService::updateSn($user_sn, $user_email);
// if(!$user){
// return Util::fail($user, $user_email.'用户不存在');
// }
$res = Customer::firstOrCreate(
['sn' => $sn],
[
'user_sn' => $user_sn,
'user_id' => $user_id,
'type' => 0,
'channel_id' => $channel_id,
'country_id' => $country_id,
'magnitude' => $magnitude,
'desc_collect' => $describe,
'phone' => $phone,
'email' => $email,
'WhatsApp' => $WhatsApp,
'contacts' => $contacts,
]
);
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
}