Compare commits
53 Commits
feature/fs
...
test
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b19071d1c | |||
| a9e83695ae | |||
| 7f6bf16440 | |||
| 1e890f8f06 | |||
| fa27b28ca8 | |||
| 2ce58106f7 | |||
| 80a7541d0c | |||
| 4d28cd88ca | |||
| 16a7ea2976 | |||
| a908619084 | |||
| aff152e40d | |||
| eeca83c3df | |||
| 9a68f72826 | |||
| 6e79dd47c4 | |||
| 9f3bfacc2f | |||
| 90ec9a7ad8 | |||
| af3398fa70 | |||
| 1a263900e8 | |||
| aaf8981369 | |||
| 1a947df500 | |||
| 4742b37391 | |||
| a643694bfa | |||
| 1833eb012d | |||
| d511b2fdb5 | |||
| 8cbf82fb2d | |||
| 23ffdab0f6 | |||
| d5c9d1a7a5 | |||
| 68eb23e316 | |||
| cef8472965 | |||
| fc1825a1c7 | |||
| 6184f69ddd | |||
| 06f2531ec0 | |||
| fc6e7c2063 | |||
| 1773ab9863 | |||
| d14945e546 | |||
| 8cee9fa81b | |||
| d8d790f96e | |||
| b7775cafcf | |||
| b9f5e671bc | |||
| a1f20d4877 | |||
| 656733c00a | |||
| b6409a69ed | |||
| 97250ca23e | |||
| 3fd7183b70 | |||
| 625b5123bb | |||
| 504bf7885c | |||
| e58ed1ee14 | |||
| b6d2e285d2 | |||
| 3c313b4f34 | |||
| c0c5138ac8 | |||
| e2e506a91f | |||
| 6e1eb75bb1 | |||
| eae3e9c09f |
@@ -41,10 +41,14 @@ class AreaController
|
||||
|
||||
public function getCountry (Request $request)
|
||||
{
|
||||
$level = Util::getParam($request,'level')?:1;
|
||||
$list = Country::get()->toArray();
|
||||
$language = 'en_addr';
|
||||
if($request->user['language'] == 'zh_CN'){
|
||||
$language = 'cn_addr';
|
||||
}
|
||||
|
||||
foreach ($list as &$row) {
|
||||
$row['name'] = $row['cn_addr'];
|
||||
$row['name'] = $row[$language];
|
||||
}
|
||||
return Util::success($list);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@ class CarTypeController
|
||||
public function getAll(Request $request)
|
||||
{
|
||||
$list = CarType::getAll();
|
||||
|
||||
if($request->user['language'] != 'zh_CN'){
|
||||
foreach ($list as $key => &$value) {
|
||||
$value['name'] = $value['name_en'];
|
||||
}
|
||||
}
|
||||
|
||||
return Util::success($list);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace app\controller;
|
||||
use app\model\Channel;
|
||||
use app\model\Customer;
|
||||
use app\model\Follow;
|
||||
use app\service\UserService;
|
||||
use app\util\Util;
|
||||
use config\constants\Constants;
|
||||
use support\Log;
|
||||
@@ -12,6 +13,13 @@ use support\Request;
|
||||
|
||||
class CustomerController
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* 不需要登录的方法
|
||||
*/
|
||||
protected $noNeedLogin = ['collect'];
|
||||
|
||||
/**
|
||||
* 客户分级
|
||||
* @param Request $request
|
||||
@@ -20,7 +28,11 @@ class CustomerController
|
||||
public function getGrade(Request $request)
|
||||
{
|
||||
$grade = [];
|
||||
foreach (Constants::GRADE as $key => $value) {
|
||||
$gradeConstants = Constants::GRADE_EN;
|
||||
if($request->user['language'] == 'zh_CN'){
|
||||
$gradeConstants = Constants::GRADE;
|
||||
}
|
||||
foreach ($gradeConstants as $key => $value) {
|
||||
$grade[] = [
|
||||
'id' => $key,
|
||||
'name' => $value,
|
||||
@@ -37,7 +49,11 @@ class CustomerController
|
||||
public function getMagnitude(Request $request)
|
||||
{
|
||||
$grade = [];
|
||||
foreach (Constants::MAGNITUDE as $key => $value) {
|
||||
$magnitudeConstants = Constants::MAGNITUDE_EN;
|
||||
if($request->user['language'] == 'zh_CN'){
|
||||
$magnitudeConstants = Constants::MAGNITUDE;
|
||||
}
|
||||
foreach ($magnitudeConstants as $key => $value) {
|
||||
$grade[] = [
|
||||
'id' => $key,
|
||||
'name' => $value,
|
||||
@@ -54,10 +70,52 @@ class CustomerController
|
||||
public function getChannel(Request $request)
|
||||
{
|
||||
$list = Channel::getAll();
|
||||
|
||||
if($request->user['language'] != 'zh_CN'){
|
||||
foreach ($list as $key => &$value) {
|
||||
$value['name'] = $value['name_en'];
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -68,9 +126,9 @@ class CustomerController
|
||||
|
||||
$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:近七天跟进客户
|
||||
$follow = $request->input('follow', ''); //跟进状态
|
||||
$keyword = $request->input('keyword', ''); //follow_last
|
||||
$follow_last = $request->input('follow_last', ''); //最后跟进:1:当天跟进客户,2:近三天跟进客户,3:近七天跟进客户
|
||||
|
||||
$where = [];
|
||||
|
||||
@@ -78,31 +136,30 @@ class CustomerController
|
||||
if (Util::isEmpty($userId)) {
|
||||
return Util::fail(['user_id' => $userId], trans('user_none'));
|
||||
}
|
||||
$where[] =['user_id',$userId] ;
|
||||
$where[] = ['user_id', $userId];
|
||||
//验证权限
|
||||
// if ($request->user['role'] != 1) {
|
||||
// $where[] =['user_id',$userId] ;
|
||||
// }
|
||||
$grade = [];
|
||||
if (!Util::isEmpty($follow) && $follow == 0) {
|
||||
$where[] = ['grade','<=', 2];
|
||||
$where[] = ['grade', '<=', 2];
|
||||
} elseif (!Util::isEmpty($follow) && $follow == 1) {
|
||||
$grade = [3, 4];
|
||||
$grade = [3, 4];
|
||||
} elseif (!Util::isEmpty($follow) && $follow == 2) {
|
||||
$where[] = ['grade','=', 5];
|
||||
$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')];
|
||||
$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::where($where)
|
||||
->orderBy('id', 'desc');
|
||||
if (!Util::isEmpty($keyword)) {
|
||||
@@ -116,16 +173,46 @@ class CustomerController
|
||||
$query->whereIn('grade', $grade);
|
||||
|
||||
}
|
||||
// return Util::success($query->toSql().serialize($where),$follow);
|
||||
|
||||
$recycle = Util::getParam($request,'recycle', '');
|
||||
if ($recycle == 'recycle') {
|
||||
$query->onlyTrashed();
|
||||
}
|
||||
|
||||
$data = $query->paginate($perPage, ['*'], 'page', $page);
|
||||
|
||||
foreach ($data->items() as &$value) {
|
||||
$value = Customer::getCustomer($value);
|
||||
$value = Customer::getCustomer($value, $request);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -138,7 +225,7 @@ class CustomerController
|
||||
return Util::fail([], 'id' . trans('not_null'));
|
||||
}
|
||||
|
||||
$res = Customer::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')
|
||||
$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) {
|
||||
@@ -147,7 +234,7 @@ class CustomerController
|
||||
return Util::fail([], '记录不存在');
|
||||
}
|
||||
|
||||
$res = Customer::getCustomer($res);
|
||||
$res = Customer::getCustomer($res, $request, true);
|
||||
|
||||
return Util::success($res);
|
||||
}
|
||||
@@ -176,7 +263,7 @@ class CustomerController
|
||||
$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'));
|
||||
return Util::fail([], trans('contacts_not_null'));
|
||||
}
|
||||
|
||||
$data = [
|
||||
@@ -256,10 +343,11 @@ class CustomerController
|
||||
$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);
|
||||
->update($data);
|
||||
|
||||
if ($res) {
|
||||
return Util::success($res, trans('save_success'));
|
||||
@@ -276,8 +364,22 @@ class CustomerController
|
||||
public function delete(Request $request)
|
||||
{
|
||||
$id = Util::getParam($request, 'id');
|
||||
$customer = Customer::where('id', $id)->first();
|
||||
$res = $customer->delete();
|
||||
$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 {
|
||||
@@ -298,19 +400,19 @@ class CustomerController
|
||||
}
|
||||
$userId = $request->user['id'];
|
||||
$created_at = $request->user['created_at'];
|
||||
$day = ceil((time()-$created_at+1)/60/60/24);
|
||||
$day = ceil((time() - $created_at + 1) / 60 / 60 / 24);
|
||||
$where[] = ['user_id', '=', $userId];
|
||||
$start = strtotime($created.'-01');
|
||||
$start = strtotime($created . '-01');
|
||||
$year = date('Y', $start);
|
||||
$month = date('n',$start); //获取月份
|
||||
$end = mktime(00, 00, 00, $month+1, 1, $year);
|
||||
$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];
|
||||
$whereGrade[] = ['grade', '<=', 2];
|
||||
$customerInit = Customer::where($whereGrade)->count();
|
||||
|
||||
//跟进中
|
||||
@@ -318,7 +420,7 @@ class CustomerController
|
||||
|
||||
//已成交
|
||||
$whereGrade = $where;
|
||||
$whereGrade[] = ['grade','=', 5];
|
||||
$whereGrade[] = ['grade', '=', 5];
|
||||
$customerDeal = Customer::where($whereGrade)->count();
|
||||
|
||||
//拜访数
|
||||
@@ -332,13 +434,13 @@ class CustomerController
|
||||
$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, //已成交
|
||||
'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'));
|
||||
@@ -347,4 +449,63 @@ class CustomerController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 线索分配
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function collect(Request $request)
|
||||
{
|
||||
Log::info('send follow start',$request->all());
|
||||
$user_sn = Util::getParam($request, 'user_sn'); //用户sn
|
||||
$user_email = Util::getParam($request, 'user_email'); //邮箱
|
||||
$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($user_email)) {
|
||||
return Util::fail([], '用户邮箱不能为空');
|
||||
}
|
||||
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_id' => $user->id,
|
||||
'channel_id' => $channel_id,
|
||||
'country_id' => $country_id,
|
||||
'magnitude' => $magnitude,
|
||||
'describe' => $describe,
|
||||
'phone' => $phone,
|
||||
'email' => $email,
|
||||
'WhatsApp' => $WhatsApp,
|
||||
'contacts' => $contacts,
|
||||
]
|
||||
);
|
||||
|
||||
if ($res) {
|
||||
return Util::success($res, trans('success'));
|
||||
} else {
|
||||
return Util::fail($res, trans('fail'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,13 +25,18 @@ class FeishuController
|
||||
*/
|
||||
public function getinfo(Request $request)
|
||||
{
|
||||
$config = Util::getParam($request, 'config');
|
||||
if (Util::isEmpty($config)) {
|
||||
$config = $this->config;
|
||||
// $config = Util::getParam($request, 'config');
|
||||
// if (Util::isEmpty($config)) {
|
||||
// $config = $this->config;
|
||||
// }
|
||||
$userId = $request->user['id'];
|
||||
$config = User::where('id',$userId)->value('sign');
|
||||
if(Util::isEmpty($config)){
|
||||
return Util::fail(null,trans('sign_not_null'));
|
||||
}
|
||||
|
||||
|
||||
// 获取凭证
|
||||
$certificate = config($config);
|
||||
$certificate = config('feishu.'.$config);
|
||||
$arr = [
|
||||
'app_id' => $certificate['appId'],
|
||||
'redirect_uri' => $certificate['rUrl'],
|
||||
@@ -48,13 +53,10 @@ class FeishuController
|
||||
public function getSign(Request $request)
|
||||
{
|
||||
|
||||
// 获取凭证
|
||||
$certificate = config('feishu');
|
||||
|
||||
$res = [];
|
||||
foreach ($certificate as $k => $v) {
|
||||
$res []=$k;
|
||||
}
|
||||
$res = [['id'=>'xinyouhe','name'=>'新友合'],['id'=>'mbaf','name'=>'MAGIC BRIDGE AUTO FZE']];
|
||||
// foreach ($certificate as $k => $v) {
|
||||
// $res []=['id'=>$k,'name'=>$k];
|
||||
// }
|
||||
return Util::success($res,trans('success'));
|
||||
}
|
||||
|
||||
@@ -70,8 +72,14 @@ class FeishuController
|
||||
public function auth(Request $request)
|
||||
{
|
||||
$param = $request->all();
|
||||
$userId = $request->user['id'];
|
||||
$config = User::where('id',$userId)->value('sign');
|
||||
if(Util::isEmpty($config)){
|
||||
return Util::fail(null,trans('sign_not_null'));
|
||||
}
|
||||
|
||||
// 获取凭证
|
||||
$certificate = config($this->config);
|
||||
$certificate = config('feishu.'.$config);
|
||||
|
||||
// 飞书服务
|
||||
$class = new \app\service\FeishuService($certificate['appId'], $certificate['appSecret'], $certificate['state']);
|
||||
@@ -89,54 +97,33 @@ class FeishuController
|
||||
}
|
||||
|
||||
Log::info('feishu user_info', ['res' => $rst]);
|
||||
$state = explode(",", $param['state']);
|
||||
$state = explode("_", $param['state']);
|
||||
//$userId = $request->user['id'];
|
||||
$userId = $state[2];
|
||||
$user = FeishuUser::where('id', $userId)->first();
|
||||
$userId = $state[1];
|
||||
// $user = FeishuUser::where('id', $userId)->first();
|
||||
// $user = FeishuUser::create();
|
||||
|
||||
//保存用户open_id
|
||||
$user->user_id = $userId;
|
||||
$user->sign = $state[0];
|
||||
$user->tenant_key = $rst['data']['tenant_key'];
|
||||
$user->open_id = $rst['data']['open_id'];
|
||||
$user->feishu_user_id = $rst['data']['user_id'];
|
||||
$user->union_id = $rst['data']['union_id'];
|
||||
$user->save();
|
||||
// //保存用户open_id
|
||||
// $user->user_id = $userId;
|
||||
// $user->sign = $state[0];
|
||||
// $user->tenant_key = $rst['data']['tenant_key'];
|
||||
// $user->open_id = $rst['data']['open_id'];
|
||||
// $user->feishu_user_id = $rst['data']['user_id'];
|
||||
// $user->union_id = $rst['data']['union_id'];
|
||||
// $user->save();
|
||||
|
||||
// var_dump($rst);
|
||||
// array(3) {
|
||||
// ["code"]=>
|
||||
// int(0)
|
||||
// ["data"]=>
|
||||
// array(11) {
|
||||
// ["avatar_big"]=>
|
||||
// string(168) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=640x640&cut_type=&quality=&format=image&sticker_format=.webp"
|
||||
// ["avatar_middle"]=>
|
||||
// string(168) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=240x240&cut_type=&quality=&format=image&sticker_format=.webp"
|
||||
// ["avatar_thumb"]=>
|
||||
// string(166) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=72x72&cut_type=&quality=&format=image&sticker_format=.webp"
|
||||
// ["avatar_url"]=>
|
||||
// string(166) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=72x72&cut_type=&quality=&format=image&sticker_format=.webp"
|
||||
// ["en_name"]=>
|
||||
// string(9) "李佳博"
|
||||
// ["mobile"]=>
|
||||
// string(14) "+8615738985690"
|
||||
// ["name"]=>
|
||||
// string(9) "李佳博"
|
||||
// ["open_id"]=>
|
||||
// string(35) "ou_37bb7cfc4311c858ea32461700fa1a43"
|
||||
// ["tenant_key"]=>
|
||||
// string(16) "14e7bc0fe5985740"
|
||||
// ["union_id"]=>
|
||||
// string(35) "on_a3fdbca48cd9477a140c7f2167a63691"
|
||||
// ["user_id"]=>
|
||||
// string(8) "481g947d"
|
||||
// }
|
||||
// ["msg"]=>
|
||||
// string(7) "success"
|
||||
// }
|
||||
$user = new FeishuUser();
|
||||
$user->firstOrCreate([
|
||||
'user_id' => $userId,
|
||||
'sign' => $state[0],
|
||||
'tenant_key' => $rst['data']['tenant_key'],
|
||||
'open_id' => $rst['data']['open_id'],
|
||||
'feishu_user_id' => $rst['data']['user_id'],
|
||||
'union_id' => $rst['data']['union_id']
|
||||
]);
|
||||
|
||||
return json($rst);
|
||||
// return json($rst);
|
||||
return Util::success($rst['data'], trans('success'));
|
||||
} else {
|
||||
//需要登录并且未提供token
|
||||
if (!Util::isEmpty($request->user['id'])) {
|
||||
@@ -159,11 +146,11 @@ class FeishuController
|
||||
* @param $href 详情链接
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function send($receiveId,$title,$content,$href)
|
||||
public static function send($config='xinyouhe',$receiveId='ou_e33bb3017ada6c4781398a68e55a4696',$title='ceshi',$content='测试',$href='http://219.157.255.213:8085/pages/index/mine')
|
||||
{
|
||||
Log::info('feishu send', ['receiveId' => $receiveId, 'title' => $title, 'content' => $content, 'href' => $href]);
|
||||
// 获取凭证
|
||||
$certificate = config($this->config);
|
||||
$certificate = config('feishu.'.$config);
|
||||
Log::info('feishu send', [$certificate,'config'=>$config,'receiveId' => $receiveId, 'title' => $title, 'content' => $content, 'href' => $href]);
|
||||
|
||||
// 飞书服务
|
||||
$class = new \app\service\FeishuService($certificate['appId'], $certificate['appSecret'], $certificate['state']);
|
||||
@@ -194,7 +181,7 @@ class FeishuController
|
||||
}";
|
||||
|
||||
// 卡片 类型
|
||||
/* $content = "{
|
||||
/*$content = "{
|
||||
\"config\":{
|
||||
\"wide_screen_mode\":true
|
||||
},
|
||||
@@ -223,7 +210,8 @@ class FeishuController
|
||||
}
|
||||
}
|
||||
}";*/
|
||||
$msgType = 'interactive';
|
||||
// $msgType = 'interactive';
|
||||
$msgType = 'post'; //卡片消息:interactive,富文本消息:post
|
||||
$receiveIdtype = 'open_id';
|
||||
|
||||
$result = $class->sendMessages($receiveId, $content, $msgType, $receiveIdtype);
|
||||
|
||||
@@ -146,6 +146,8 @@ class FollowController
|
||||
|
||||
$customer = Customer::find($customer_id);
|
||||
$customer->follow_last = strtotime($res->created_at);
|
||||
$customer->follow_next = null;
|
||||
$customer->warn = 0;
|
||||
$customer->save();
|
||||
|
||||
if ($res) {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\CustomerTag;
|
||||
use app\model\TagGroup;
|
||||
use app\util\Util;
|
||||
use support\Request;
|
||||
|
||||
class TagGroupController
|
||||
{
|
||||
|
||||
// 列表
|
||||
public function list(Request $request)
|
||||
{
|
||||
$list = TagGroup::with('tags')->get();
|
||||
$languageArr = config('translation.fallback_locale');
|
||||
$language = $request->user['language'];
|
||||
foreach ($list as &$item) {
|
||||
$item['names'] = unserialize($item['names']);
|
||||
if (in_array($language, $languageArr)) {
|
||||
$item['name'] = $item['names'][$language];
|
||||
}
|
||||
foreach ($item['tags'] as &$tag) {
|
||||
$tag['names'] = unserialize($tag['names']);
|
||||
if (in_array($language, $languageArr)) {
|
||||
$tag['name'] = $tag['names'][$language];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Util::success($list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新客户标签关系
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function updatePivot(Request $request)
|
||||
{
|
||||
$customerId = Util::getParam($request, 'customer_id');
|
||||
$groupId = Util::getParam($request, 'group_id');
|
||||
$tagId = Util::getParam($request, 'tag_id');
|
||||
if (Util::isEmpty($customerId)) {
|
||||
return Util::fail([], trans('customer_id') . trans('not_null'));
|
||||
}
|
||||
if (Util::isEmpty($groupId)) {
|
||||
return Util::fail([], trans('tag_group_id') . trans('not_null'));
|
||||
}
|
||||
|
||||
if(empty($tagId)){
|
||||
$res = CustomerTag::where(['customer_id' => $customerId, 'group_id' => $groupId])->delete();
|
||||
}else{
|
||||
$res = CustomerTag::updateOrCreate(['customer_id' => $customerId, 'group_id' => $groupId], ['tag_id' => $tagId]);
|
||||
}
|
||||
|
||||
if($res){
|
||||
return Util::success($res, trans('success'));
|
||||
}else{
|
||||
return Util::fail($res, trans('fail'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,11 @@ use support\Request;
|
||||
|
||||
class UploadController
|
||||
{
|
||||
|
||||
/**
|
||||
* 不需要登录的方法
|
||||
*/
|
||||
protected $noNeedLogin = ['uploadImage'];
|
||||
// 允许的文件类型
|
||||
protected $allowedMimeTypes = [
|
||||
'image/jpeg',
|
||||
@@ -110,7 +115,7 @@ class UploadController
|
||||
}
|
||||
|
||||
$result = Storage::adapter('oss')
|
||||
->path('vehicle_album/'.date('Ymd'))
|
||||
->path('lingke_crm/'.date('Ymd'))
|
||||
->size(1024*1024*5)
|
||||
->extYes(['image/jpeg','image/png'])
|
||||
->extNo(['image/gif'])
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Country;
|
||||
use app\model\FeishuUser;
|
||||
use app\model\User;
|
||||
use app\model\UserSn;
|
||||
use app\service\MailService;
|
||||
use app\util\JwtUtil;
|
||||
use app\util\Util;
|
||||
@@ -61,7 +63,7 @@ class UserController
|
||||
$result['token'] = $token;
|
||||
$result['feishu_openid'] = FeishuUser::where('user_id', $userId)->value('open_id');
|
||||
|
||||
if (Util::isEmpty($language)) {
|
||||
if (!Util::isEmpty($language)) {
|
||||
User::where('id', $userId)
|
||||
->update(['language' => $language]);
|
||||
locale($language);
|
||||
@@ -80,7 +82,7 @@ class UserController
|
||||
{
|
||||
$email = Util::getParam($request, 'email');
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
return Util::fail([], trans('required_not_null'));
|
||||
return Util::fail([], trans('email_error'));
|
||||
}
|
||||
|
||||
// 生成验证码
|
||||
@@ -137,6 +139,9 @@ class UserController
|
||||
if ($code != $verification_code) {
|
||||
return Util::fail([], trans('code_error'));
|
||||
}
|
||||
if(strlen($password) < 6) {
|
||||
return Util::fail([], trans('password_short'));
|
||||
}
|
||||
|
||||
//加密
|
||||
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
||||
@@ -144,15 +149,25 @@ class UserController
|
||||
$data = [
|
||||
'mobile' => $mobile,
|
||||
'email' => $email,
|
||||
'name' => $name,
|
||||
'name' => '用户_'.rand(111111, 999999),
|
||||
'sex' => $sex,
|
||||
'role' => 1,
|
||||
'password' => $hashedPassword,
|
||||
'status' => 0,
|
||||
'avatar' => 'lingke_crm/logo.png'
|
||||
];
|
||||
|
||||
|
||||
if (Util::isEmpty($id)) {
|
||||
// 获取编号
|
||||
$userSnModel = new UserSn();
|
||||
$sn = $userSnModel->where('user_id', '=', 0)->inRandomOrder()->first();
|
||||
if (!$sn) {
|
||||
throw new BusinessException('未找到适用编号');
|
||||
}
|
||||
$data['sn'] = $sn['user_sn'];
|
||||
$res = User::create($data);
|
||||
UserSn::where(['user_sn'=>$data['sn']])->update(['user_id'=>$res['id']]);
|
||||
} else {
|
||||
$res = User::where('id', $id)
|
||||
->update($data);
|
||||
@@ -178,7 +193,10 @@ class UserController
|
||||
$user->toArray();
|
||||
unset($user->password);
|
||||
$user['feishu_openid'] = FeishuUser::where('user_id', $userId)->value('open_id');
|
||||
|
||||
$user['country_name'] = Country::where('id', $user['country_id'])->value('cn_addr');
|
||||
$user['avatar_url'] = $user['avatar'];
|
||||
$ossservice = new \app\service\OssService();
|
||||
$user['avatar'] = $user['avatar'] ? $ossservice->generatePrivateUrl($user['avatar']) : '';
|
||||
return Util::success($user, trans('save_success'));
|
||||
}
|
||||
|
||||
@@ -196,6 +214,8 @@ class UserController
|
||||
$country_id = Util::getParam($request, 'country_id');
|
||||
$sign = Util::getParam($request, 'sign');
|
||||
$id = $request->user['id'];
|
||||
$avatar = Util::getParam($request, 'avatar_url');
|
||||
$mobile = Util::getParam($request, 'mobile');
|
||||
|
||||
$data = [
|
||||
'name' => $name,
|
||||
@@ -203,6 +223,8 @@ class UserController
|
||||
'position' => $position,
|
||||
'country_id' => $country_id,
|
||||
'sign' => $sign,
|
||||
'avatar' => $avatar,
|
||||
'mobile' => $mobile
|
||||
];
|
||||
|
||||
$res = User::where('id', $id)
|
||||
|
||||
@@ -54,11 +54,15 @@ class AuthMiddleware implements MiddlewareInterface
|
||||
// 从 Header 获取 Token
|
||||
$token = $request->header('Authorization');
|
||||
|
||||
$language = Util::getParam($request, 'language');
|
||||
$language = $language=='zh_CN'?:'en';
|
||||
//需要登录并且未提供token
|
||||
if ($isLogin && (!$token || !str_starts_with($token, 'Bearer '))) {
|
||||
return Util::fail('','请先登录',401);
|
||||
locale($language);
|
||||
return Util::fail('',trans('user_login'),401);
|
||||
// throw new BusinessException('未提供 Token'.$isLogin, 401);
|
||||
}elseif(!$isLogin){
|
||||
locale($language);
|
||||
return $handler($request);
|
||||
}
|
||||
|
||||
@@ -68,8 +72,11 @@ class AuthMiddleware implements MiddlewareInterface
|
||||
// 验证 Token 并获取用户ID
|
||||
$decoded = JwtUtil::verifyToken($token);
|
||||
|
||||
$userId = $decoded->sub;
|
||||
if (!isset($decoded->sub)) {
|
||||
return Util::fail('', trans('user_login'),401);
|
||||
}
|
||||
|
||||
$userId = $decoded->sub;
|
||||
$user = User::select(['id','name','sex','role','avatar','email','password','language','created_at'])
|
||||
->find($userId);
|
||||
if(!$user){
|
||||
|
||||
@@ -7,19 +7,36 @@ use Webman\MiddlewareInterface;
|
||||
|
||||
class CrossDomain implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// 动态允许请求来源(支持携带Cookie)
|
||||
$origin = $request->header('origin', '*');
|
||||
$response = $next($request);
|
||||
// public function process(Request $request, callable $next): Response
|
||||
// {
|
||||
// // 动态允许请求来源(支持携带Cookie)
|
||||
// $origin = $request->header('origin', '*');
|
||||
// $response = $next($request);
|
||||
//
|
||||
// // 设置跨域响应头
|
||||
// $response->withHeaders([
|
||||
// 'Access-Control-Allow-Origin' => $origin,
|
||||
// 'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
|
||||
// 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With',
|
||||
// 'Access-Control-Allow-Credentials' => 'true', // 允许携带Cookie
|
||||
// 'Access-Control-Max-Age' => 86400, // 预检请求缓存时间(秒)
|
||||
// 'Vary' => 'Origin' // 避免缓存干扰
|
||||
// ]);
|
||||
//
|
||||
// return $response;
|
||||
// }
|
||||
|
||||
// 设置跨域响应头
|
||||
public function process(Request $request, callable $handler) : Response
|
||||
{
|
||||
// 如果是options请求则返回一个空响应,否则继续向洋葱芯穿越,并得到一个响应
|
||||
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
|
||||
|
||||
// 给响应添加跨域相关的http头
|
||||
$response->withHeaders([
|
||||
'Access-Control-Allow-Origin' => $origin,
|
||||
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
|
||||
'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With',
|
||||
'Access-Control-Allow-Credentials' => 'true', // 允许携带Cookie
|
||||
'Access-Control-Max-Age' => 86400, // 预检请求缓存时间(秒)
|
||||
'Access-Control-Allow-Credentials' => 'true',
|
||||
'Access-Control-Allow-Origin' => $request->header('origin', '*'),
|
||||
'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
|
||||
'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
|
||||
'Vary' => 'Origin' // 避免缓存干扰
|
||||
]);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class CarType extends Model
|
||||
|
||||
public static function getAll()
|
||||
{
|
||||
$list = self::get()->select('id','name','status')->where('status',0)->toArray();
|
||||
$list = self::get()->select('id','name','name_en','status')->where('status',0)->toArray();
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class Channel extends Model
|
||||
|
||||
public static function getAll()
|
||||
{
|
||||
$list = self::get()->select('id','name','status')->where('status',0)->toArray();
|
||||
$list = self::get()->select('id','name','name_en','status')->where('status',0)->toArray();
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
+35
-10
@@ -59,21 +59,28 @@ class Customer extends Model
|
||||
return $date->format(Carbon::parse($date)->toDateTimeString());
|
||||
}
|
||||
|
||||
public static function getCustomer($customer)
|
||||
/**
|
||||
* @param $customer
|
||||
* @param $request
|
||||
* @param $tag 是否返回客户标签
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getCustomer($customer, $request, $tag = false)
|
||||
{
|
||||
$customer['grade_txt'] = Constants::GRADE[$customer['grade']];
|
||||
$customer['magnitude_txt'] = Constants::MAGNITUDE[$customer['magnitude']];
|
||||
$customer['sex_txt'] = Constants::SEX[$customer['sex']];
|
||||
$language = $request->user['language'] ?: 'en';
|
||||
$customer['grade_txt'] = $language=='en'?Constants::GRADE_EN[$customer['grade']]:Constants::GRADE[$customer['grade']];
|
||||
$customer['magnitude_txt'] = $language=='en'?Constants::MAGNITUDE_EN[$customer['magnitude']]:Constants::MAGNITUDE[$customer['magnitude']];
|
||||
$customer['sex_txt'] = $language=='en'?Constants::SEX_EN[$customer['sex']]:Constants::SEX[$customer['sex']];
|
||||
|
||||
if ($customer['grade']<=2) {
|
||||
$customer['follow'] = 0;
|
||||
$customer['follow_txt'] = '跟进中';
|
||||
$customer['follow_txt'] = ($language == 'en' ? 'Following' : '跟进中');
|
||||
}elseif ($customer['grade']<5) {
|
||||
$customer['follow'] = 1;
|
||||
$customer['follow_txt'] = '已成交';
|
||||
$customer['follow_txt'] = ($language == 'en' ? 'transacted' : '已成交');
|
||||
}else{
|
||||
$customer['follow'] = 2;
|
||||
$customer['follow_txt'] = '已流失';
|
||||
$customer['follow_txt'] = ($language == 'en' ? 'lost' : '已流失');
|
||||
}
|
||||
|
||||
$where = [
|
||||
@@ -89,11 +96,29 @@ class Customer extends Model
|
||||
// $customer['updated_at'] = Util::timeTotDate($customer['updated_at']);
|
||||
|
||||
$customer = Util::formatDate($customer,['follow_last']);
|
||||
$customer['car_type_name'] = empty($customer['car_type_id'])?'':CarType::where(['id'=>$customer['car_type_id']])->value('name');
|
||||
$customer['country_name'] = empty($customer['country_id'])?'':Country::where(['id'=>$customer['country_id']])->value('cn_addr');
|
||||
$customer['channel_name'] = empty($customer['channel_id'])?'':Channel::where(['id'=>$customer['channel_id']])->value('name');
|
||||
$nameLang = $language=='en'?'name_en':'name';
|
||||
$countryLang = $language=='en'?'en_addr':'cn_addr';
|
||||
$customer['car_type_name'] = empty($customer['car_type_id'])?'':CarType::where(['id'=>$customer['car_type_id']])->value($nameLang);
|
||||
$customer['country_name'] = empty($customer['country_id'])?'':Country::where(['id'=>$customer['country_id']])->value($countryLang);
|
||||
$customer['channel_name'] = empty($customer['channel_id'])?'':Channel::where(['id'=>$customer['channel_id']])->value($nameLang);
|
||||
// $customer['last_follow'] = $last_follow;
|
||||
|
||||
if ($tag) {
|
||||
foreach ($customer['tags'] as &$tag) {
|
||||
$tag['names'] = unserialize($tag['names']);
|
||||
$tag['name'] = $tag['names'][$language];
|
||||
}
|
||||
}
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户的标签
|
||||
*/
|
||||
public function tags()
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'customer_tag', 'customer_id', 'tag_id')
|
||||
->withTimestamps(); // 如果需要记录关联时间
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
use app\util\Util;
|
||||
use support\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class CustomerTag extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'customer_tag';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
//设置黑名单
|
||||
protected $guarded = ['id', 'created_at'];
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace app\model;
|
||||
|
||||
|
||||
use app\service\OssService;
|
||||
use app\util\Util;
|
||||
use config\constants\Constants;
|
||||
use support\Model;
|
||||
@@ -51,7 +52,9 @@ class Follow extends Model
|
||||
{
|
||||
$follow['type_txt'] = Constants::FOLLOW[$follow['type']];
|
||||
$follow['firstFollowtime'] = $follow['follow_time'];
|
||||
$follow['oss_picture'] = $domain.'/'.$follow['picture'];
|
||||
$ossservice = new OssService();
|
||||
$oss_picture = $ossservice->generatePrivateUrl($follow['picture'],86400);
|
||||
$follow['oss_picture'] = $oss_picture;
|
||||
// $follow = Util::formatDate($follow);
|
||||
return $follow;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
use app\util\Util;
|
||||
use config\constants\Constants;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Support\Carbon;
|
||||
use support\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tag';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
//设置黑名单
|
||||
protected $guarded = ['id','created_at','updated_at'];
|
||||
|
||||
// 指定日期字段存储格式为时间戳
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
// 定义反向多对一关联
|
||||
public function group()
|
||||
{
|
||||
return $this->belongsTo(TagGroup::class, 'group_id', 'id');
|
||||
}
|
||||
|
||||
public function customers()
|
||||
{
|
||||
return $this->belongsToMany(Customer::class, 'customer_tag', 'tag_id', 'customer_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
use app\util\Util;
|
||||
use config\constants\Constants;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Support\Carbon;
|
||||
use support\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class TagGroup extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tag_group';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
//设置黑名单
|
||||
protected $guarded = ['id','created_at','updated_at'];
|
||||
|
||||
// 指定日期字段存储格式为时间戳
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
// 定义与 Tag 的一对多关系
|
||||
public function tags()
|
||||
{
|
||||
return $this->hasMany(Tag::class, 'group_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
|
||||
use support\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class UserSn extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'user_sn';
|
||||
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
}
|
||||
+44
-9
@@ -1,39 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace process;
|
||||
namespace app\process;
|
||||
|
||||
use app\controller\FeishuController;
|
||||
use app\model\Customer;
|
||||
use app\model\FeishuUser;
|
||||
use app\model\User;
|
||||
use support\Log;
|
||||
use Webman\App;
|
||||
use Workerman\Crontab\Crontab;
|
||||
|
||||
class Task
|
||||
{
|
||||
|
||||
public function onWorkerStart()
|
||||
{
|
||||
// 每半小时执行一次
|
||||
new Crontab('30/* * * * *', function () {
|
||||
new Crontab('0 */30 * * * *', function(){
|
||||
echo date('Y-m-d H:i:s') . "\n";
|
||||
$customer = Customer::where(['follow_next', '<=', time() + 3600])
|
||||
->where(['follow_next', '>', time()])
|
||||
->where(['warn', '<', 1])
|
||||
->get();
|
||||
Log::info('send follow start',[time()]);
|
||||
// FeishuController::send('xinyouhe','ou_e33bb3017ada6c4781398a68e55a4696', '跟进提醒', '您有新的跟进提醒', '');
|
||||
// $customer = Customer::where(['follow_next', '<=', time() + 3600])
|
||||
// ->where(['follow_next', '>', time()])
|
||||
// ->where(['warn', '<', 1])
|
||||
// ->get();
|
||||
// foreach ($customer as $item) {
|
||||
// $feishuUser = FeishuUser::where(['user_id' => $item->user_id])->first();
|
||||
// if ($feishuUser) {
|
||||
// // 获取凭证
|
||||
// $certificate = config($this->config);
|
||||
// // 使用parse_url解析URL
|
||||
// $parsedUrl = parse_url($certificate['rUrl']);
|
||||
// // 获取域名和端口
|
||||
// $host = $parsedUrl['host'];
|
||||
// $port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
|
||||
// $url = $host .$port. '/pages/customer/detile?id='.$customer->id;
|
||||
// $item->warn = 1;
|
||||
// $item->update();
|
||||
// $user = User::first()->where('id', $item->user_id);
|
||||
// Log::info('send',['open_id'=>$item['open_id'],'url'=>$url]);
|
||||
// // FeishuController::send('xinyouhe','ou_e33bb3017ada6c4781398a68e55a4696', '跟进提醒', '您有新的跟进提醒', $url);
|
||||
// FeishuController::send($user->sign,$feishuUser->open_id, '跟进提醒', '您有新的跟进提醒', $url);
|
||||
// }
|
||||
// }
|
||||
|
||||
$where = [
|
||||
['follow_next', '<=', time() + 3600],
|
||||
['follow_next', '>', time()],
|
||||
['warn', '<', 1]
|
||||
];
|
||||
$customer = Customer::where($where)->get();
|
||||
foreach ($customer as $item) {
|
||||
$feishuUser = FeishuUser::where(['user_id' => $item->user_id])->first();
|
||||
if ($feishuUser) {
|
||||
// 获取凭证
|
||||
$certificate = config($this->config);
|
||||
$certificate = config('feishu.'.$feishuUser->sign);
|
||||
// 使用parse_url解析URL
|
||||
$parsedUrl = parse_url($certificate['rUrl']);
|
||||
// 获取域名和端口
|
||||
$host = $parsedUrl['host'];
|
||||
$port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
|
||||
$url = $host .$port. '/pages/customer/detile?id='.$customer->id;
|
||||
FeishuController::class->send($feishuUser->open_id, '跟进提醒', '您有新的跟进提醒', $url);
|
||||
$url = 'http://'. $host .$port. '/pages/customer/detile?id='.$item->id;
|
||||
$item->warn = 1;
|
||||
$item->update();
|
||||
Log::info('send',['open_id'=>$item['open_id'],'url'=>$url]);
|
||||
FeishuController::send($feishuUser->sign, $feishuUser->open_id, '跟进提醒', '您有新的跟进提醒', $url);
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('send follow start',[time()]);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ class FeishuService
|
||||
"client_id" => $this->appId,
|
||||
"client_secret" => $this->appSecret,
|
||||
"code" => $code,
|
||||
"redirect_uri" => 'http://219.157.255.213:8085/pages/index/webview'
|
||||
"redirect_uri" => $redirect_uri
|
||||
];
|
||||
return $this->requestResult('authen/v2/oauth/token');
|
||||
}
|
||||
|
||||
@@ -19,10 +19,18 @@ class MailService
|
||||
{
|
||||
// SMTP 配置
|
||||
$this->mailer->isSMTP();
|
||||
$this->mailer->Host = 'smtp.gmail.com';
|
||||
// $this->mailer->Host = 'smtp.gmail.com';
|
||||
$this->mailer->Host = 'smtp.feishu.cn';
|
||||
$this->mailer->SMTPAuth = true;
|
||||
$this->mailer->Username = 'xinyouhe25@gmail.com'; // 替换为你的 Gmail
|
||||
$this->mailer->Password = 'zhjkkaplncykzymo'; // 替换为应用专用密码
|
||||
|
||||
// $this->mailer->Username = 'xinyouhe25@gmail.com'; // 替换为你的 Gmail
|
||||
// $this->mailer->Password = 'zhjkkaplncykzymo'; // 替换为应用专用密码
|
||||
|
||||
// $this->mailer->Username = 'linyang0618@gmail.com'; // 替换为你的 Gmail
|
||||
// $this->mailer->Password = 'mrjefuahbwbpqakb'; // 替换为应用专用密码
|
||||
|
||||
$this->mailer->Username = 'app@hnxinyouhe.com'; // 替换为你的 Gmail
|
||||
$this->mailer->Password = 'akyIUFJ6ihGGjI5h'; // 替换为应用专用密码
|
||||
// $this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 使用 TLS
|
||||
$this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // SSL 加密
|
||||
// $this->mailer->Port = 587;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace app\service;
|
||||
|
||||
use app\model\User;
|
||||
use app\model\UserSn;
|
||||
|
||||
class UserService
|
||||
{
|
||||
/**
|
||||
* 更新用户sn
|
||||
* @param $sn
|
||||
* @param $email
|
||||
*/
|
||||
public static function updateSn($sn, $email)
|
||||
{
|
||||
$user = User::first()
|
||||
->where('email',$email)
|
||||
->first();
|
||||
return $user;
|
||||
if(!$user){
|
||||
return false;
|
||||
}
|
||||
if($user->sn != $sn){
|
||||
UserSn::where(['sn' => $user->sn])->update(['user_id' => 0]);
|
||||
UserSn::where(['sn' => $sn])->update(['user_id' => $user->id]);
|
||||
$user->sn = $sn;
|
||||
$user->save();
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,14 @@ class Constants
|
||||
self::CUSTOMER_GRADE_SALES => '售后阶段',
|
||||
self::CUSTOMER_GRADE_LOSS => '停滞或流失',
|
||||
];
|
||||
public const GRADE_EN = [
|
||||
self::CUSTOMER_GRADE_INITIAL => 'Initial contact',
|
||||
self::CUSTOMER_GRADE_COMMUNICATE => 'Demand Chat',
|
||||
self::CUSTOMER_GRADE_PLAN => 'promotion of the plan',
|
||||
self::CUSTOMER_GRADE_DEAL => 'Transaction Stage',
|
||||
self::CUSTOMER_GRADE_SALES => 'After Sales',
|
||||
self::CUSTOMER_GRADE_LOSS => 'Stagnation or loss',
|
||||
];
|
||||
|
||||
//客户重要性
|
||||
public const CUSTOMER_MAGNITUDE_INITIAL = 0; // 金牌商机
|
||||
@@ -30,6 +38,11 @@ class Constants
|
||||
self::CUSTOMER_MAGNITUDE_COMMUNICATE => '银牌商机',
|
||||
self::CUSTOMER_MAGNITUDE_PLAN => '铜牌商机',
|
||||
];
|
||||
public const MAGNITUDE_EN = [
|
||||
self::CUSTOMER_MAGNITUDE_INITIAL => 'Gold Medal',
|
||||
self::CUSTOMER_MAGNITUDE_COMMUNICATE => 'Silver Medal',
|
||||
self::CUSTOMER_MAGNITUDE_PLAN => 'Bronze Medal',
|
||||
];
|
||||
|
||||
|
||||
//跟进类型
|
||||
@@ -40,6 +53,10 @@ class Constants
|
||||
self::CUSTOMER_FOLLOW_VISIT => '线下拜访',
|
||||
self::CUSTOMER_FOLLOW_UP => '线上跟进',
|
||||
];
|
||||
public const FOLLOW_EN = [
|
||||
self::CUSTOMER_FOLLOW_VISIT => 'Visit',
|
||||
self::CUSTOMER_FOLLOW_UP => 'On line',
|
||||
];
|
||||
|
||||
//跟进类型
|
||||
public const CUSTOMER_SEX_UNKNOWN = 0; // 未知
|
||||
@@ -51,4 +68,10 @@ class Constants
|
||||
self::CUSTOMER_SEX_MAN => '男',
|
||||
self::CUSTOMER_SEX_WOMAN => '女',
|
||||
];
|
||||
|
||||
public const SEX_EN = [
|
||||
self::CUSTOMER_SEX_UNKNOWN => 'unknown',
|
||||
self::CUSTOMER_SEX_MAN => 'man',
|
||||
self::CUSTOMER_SEX_WOMAN => 'woman',
|
||||
];
|
||||
}
|
||||
+2
-2
@@ -4,7 +4,7 @@ return [
|
||||
'xinyouhe' => [
|
||||
'appId' => "cli_a73e1e6406fa501c",
|
||||
'appSecret' => "9cMfxujjGG9JPmNfNcOwUdCoIXqaM1wY",
|
||||
'rUrl' => "http://219.157.255.213:25321/feishu/auth",
|
||||
'rUrl' => "http://219.157.255.213:8085/pages/index/webview",
|
||||
'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot",
|
||||
'state' => "xinyouhe",
|
||||
'baseUri' => "https://open.feishu.cn/open-apis/"
|
||||
@@ -12,7 +12,7 @@ return [
|
||||
'mbaf' => [
|
||||
'appId' => "cli_a75839fb4ff85028",
|
||||
'appSecret' => "VsqLvwsRzpmisBVbrTIuKdNCvRCO447d",
|
||||
'rUrl' => "http://219.157.255.213:25321/feishu/auth",
|
||||
'rUrl' => "http://219.157.255.213:8085/pages/index/webview",
|
||||
'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot",
|
||||
'state' => "mbaf",
|
||||
'baseUri' => "https://open.larksuite.com/open-apis/"
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ return [
|
||||
'webman' => [
|
||||
'handler' => Http::class,
|
||||
'listen' => getenv('WEBMAN_LISTEN'),
|
||||
'count' => cpu_count() * 4,
|
||||
'count' => 8,
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
'reusePort' => false,
|
||||
@@ -60,6 +60,6 @@ return [
|
||||
]
|
||||
],
|
||||
'task' => [
|
||||
'handler' => process\Task::class
|
||||
'handler' => app\process\Task::class
|
||||
],
|
||||
];
|
||||
|
||||
@@ -6,10 +6,12 @@ return [
|
||||
'login_success' => ' login success',
|
||||
'password_error' => ' password error',
|
||||
'user_none' => ' user none',
|
||||
'user_login' => ' Please log in first',
|
||||
'not_null' => ' not null',
|
||||
'code_error' => ' code error',
|
||||
'format_error' => ' format error',
|
||||
'email_repeat' => ' email repeat',
|
||||
'email_error' => ' Email format error',
|
||||
'save_success' => ' save success',
|
||||
'save_fail' => ' save fail',
|
||||
'register_success' => ' register success',
|
||||
@@ -23,4 +25,9 @@ return [
|
||||
'car_type_not_null' => ' preference_not_null',
|
||||
'channel_not_null' => ' channel not null',
|
||||
'email_consistent' => ' Inconsistent email addresses',
|
||||
'sign_not_null' => ' No affiliated company has been set',
|
||||
'password_short' => ' Password cannot be less than 6 characters',
|
||||
'id_empty' => ' ID cannot be empty',
|
||||
'customer_id' => ' customer ID',
|
||||
'tag_group_id' => ' tag group ID',
|
||||
];
|
||||
@@ -6,10 +6,12 @@ return [
|
||||
'login_success' => ' 登录成功',
|
||||
'password_error' => ' 密码错误',
|
||||
'user_none' => ' 用户不存在',
|
||||
'user_login' => ' 请先登录',
|
||||
'not_null' => ' 不能为空',
|
||||
'code_error' => ' 验证码错误',
|
||||
'format_error' => ' 格式错误',
|
||||
'email_repeat' => ' 邮箱重复',
|
||||
'email_error' => ' 邮箱格式错误',
|
||||
'save_success' => ' 保存成功',
|
||||
'save_fail' => ' 保存失败',
|
||||
'register_success' => ' 注册成功',
|
||||
@@ -23,4 +25,9 @@ return [
|
||||
'car_type_not_null' => ' 偏好不能为空',
|
||||
'channel_not_null' => ' 渠道不能为空',
|
||||
'email_consistent' => ' 邮箱不一致',
|
||||
'sign_not_null' => ' 未设置所属公司',
|
||||
'password_short' => ' 密码不能少于6位',
|
||||
'id_empty' => ' id不能为空',
|
||||
'customer_id' => ' 客户ID',
|
||||
'tag_group_id' => ' 标签组ID',
|
||||
];
|
||||
Reference in New Issue
Block a user