From f19efd85b060f011e3f61f9dc9aca43a119f3b23 Mon Sep 17 00:00:00 2001 From: "HESU\\HESU" <1696136552@qq.com> Date: Wed, 9 Jul 2025 15:10:14 +0800 Subject: [PATCH 1/4] 1 --- app/crm/controller/BaseController.php | 51 ++++++++ app/crm/controller/CarTypeController.php | 34 ++++++ app/crm/controller/CustomerController.php | 49 ++++++++ app/crm/controller/FollowController.php | 127 ++++++++++++++++++++ app/crm/controller/TagGroupController.php | 67 +++++++++++ app/crm/logic/CustomerLogic.php | 8 ++ app/crm/logic/FollowLogic.php | 8 ++ app/crm/model/CarType.php | 36 ++++++ app/crm/model/Channel.php | 48 ++++++++ app/crm/model/Country.php | 41 +++++++ app/crm/model/Customer.php | 135 ++++++++++++++++++++++ app/crm/model/CustomerHis.php | 68 +++++++++++ app/crm/model/CustomerTag.php | 36 ++++++ app/crm/model/Follow.php | 61 ++++++++++ app/crm/model/Tag.php | 55 +++++++++ app/crm/model/TagGroup.php | 50 ++++++++ app/crm/service/CustomerService.php | 27 +++++ app/crm/service/FollowService.php | 53 +++++++++ app/crm/utils/Util.php | 121 +++++++++++++++++++ app/crm/validate/FollowValidate.php | 21 ++++ config/constants/Constants.php | 100 ++++++++++++++++ 21 files changed, 1196 insertions(+) create mode 100644 app/crm/controller/BaseController.php create mode 100644 app/crm/controller/CarTypeController.php create mode 100644 app/crm/controller/CustomerController.php create mode 100644 app/crm/controller/FollowController.php create mode 100644 app/crm/controller/TagGroupController.php create mode 100644 app/crm/logic/CustomerLogic.php create mode 100644 app/crm/logic/FollowLogic.php create mode 100644 app/crm/model/CarType.php create mode 100644 app/crm/model/Channel.php create mode 100644 app/crm/model/Country.php create mode 100644 app/crm/model/Customer.php create mode 100644 app/crm/model/CustomerHis.php create mode 100644 app/crm/model/CustomerTag.php create mode 100644 app/crm/model/Follow.php create mode 100644 app/crm/model/Tag.php create mode 100644 app/crm/model/TagGroup.php create mode 100644 app/crm/service/CustomerService.php create mode 100644 app/crm/service/FollowService.php create mode 100644 app/crm/utils/Util.php create mode 100644 app/crm/validate/FollowValidate.php diff --git a/app/crm/controller/BaseController.php b/app/crm/controller/BaseController.php new file mode 100644 index 0000000..1b824e0 --- /dev/null +++ b/app/crm/controller/BaseController.php @@ -0,0 +1,51 @@ +scene($scene); + } + // 执行数据验证 + if (!$validator->check($data)) { + // 验证失败,抛出业务异常,异常信息为验证器返回的错误信息 + throw new BusinessException($validator->getError()); + } + // 验证成功,返回原始数据 + return $data; + } + + public function page($result){ + $current = $result->currentPage(); + $total = $result->total(); + $size = $result->perPage(); + $result = $result->toArray(); + $result['current'] = $current; + $result['total'] = $total; + $result['size'] = $size; + return $result; + } +} \ No newline at end of file diff --git a/app/crm/controller/CarTypeController.php b/app/crm/controller/CarTypeController.php new file mode 100644 index 0000000..6156876 --- /dev/null +++ b/app/crm/controller/CarTypeController.php @@ -0,0 +1,34 @@ +user['language'] != 'zh_CN'){ + foreach ($list as &$value) { + $value['name'] = $value['name_en']; + } + }elseif ($request->user['language'] == 'ru'){ + foreach ($list as &$value) { + $value['name'] = $value['name_ru']; + } + } + + return $this->success($list); + } + +} \ No newline at end of file diff --git a/app/crm/controller/CustomerController.php b/app/crm/controller/CustomerController.php new file mode 100644 index 0000000..9844dc3 --- /dev/null +++ b/app/crm/controller/CustomerController.php @@ -0,0 +1,49 @@ +list($request->all()); + return $this->success($this->page($result)); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } + + public function follow(Request $request) + { +// try { +// $result = (new CustomerService())->follow($request->all()); +// return $this->success($this->page($result)); +// } catch (\Throwable $e) { +// return $this->error($e->getMessage()); +// } + $page = $request->input('page', 1); + $perPage = $request->input('per_page', 10); + $where = []; + if($request->input('user_id')){ + $where[] = ['user_id', '=', $request->input('user_id')]; + } + $user = Customer::with('user')->where($where)->paginate($perPage, ['*'], 'page', $page); + $user = $user->toArray(); + foreach ($user['data'] as &$item) { + unset($item['password']); + } + return $this->success($user); + } +} \ No newline at end of file diff --git a/app/crm/controller/FollowController.php b/app/crm/controller/FollowController.php new file mode 100644 index 0000000..7f08e7d --- /dev/null +++ b/app/crm/controller/FollowController.php @@ -0,0 +1,127 @@ + $value) { + $grade[] = [ + 'status' => $key, + 'text' => $value, + ]; + } + return $this->success($grade); + } + + + /** + * 跟进列表 + * @param Request $request + * @return \support\Response + */ + public function list(Request $request) + { + try { + $data = $this->validate(new FollowValidate(), $request->get(), 'upwd_list'); + $result = (new FollowService())->list($request->all()); + return $this->success($this->page($result)); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } + + /** + * 跟进详情 + * @param Request $request + * @return \support\Response + */ + public function detail(Request $request) + { + //跟进id + $id = Util::getParam($request,'id'); + if(Util::isEmpty($id)){ + return $this->error('id'.trans('not_null')); + } + + $res = Follow::select('id','user_id','customer_id','type','picture','remark','audio','audio_text','lat','lng','address') + ->where('id',$id) + ->first(); + if($res){ + $res->toArray(); + }else{ + return $this->error('记录不存在'); + } + + $res = Follow::getFollow($res); + + return $this->success($res); + } + + /** + * 客户录入 + * @param Request $request + * @return \support\Response + */ + public function save(Request $request) + { + $customer_id = Util::getParam($request,'customer_id'); + + if(Util::isEmpty($customer_id)){ + return $this->error('customer_id'.trans('not_null')); + } + $type = Util::getParam($request,'type'); + if(Util::isEmpty($type)){ + return $this->error('type'.trans('not_null')); + } + $picture = Util::getParam($request,'picture'); + if(Util::isEmpty($picture)){ + return $this->error(trans('picture_not_null')); + } + + $data = [ + 'user_id'=>$request->user['id'], + 'customer_id'=>$customer_id, + 'type'=>$type, + 'picture'=>$picture, + 'remark'=>Util::getParam($request,'remark',''), + 'audio'=>Util::getParam($request,'audio',''), + 'audio_text'=>Util::getParam($request,'audio_text',''), + 'lat'=>Util::getParam($request,'lat',0), + 'lng'=>Util::getParam($request,'lng',0), + 'address'=>Util::getParam($request,'address'), + 'follow_time'=>strtotime(Util::getParam($request,'firstFollowtime',0)), + ]; + + $res = Follow::create($data); + + $customer = Customer::find($customer_id); + $customer->follow_last = strtotime($res->created_at); + $customer->follow_next = null; + $customer->warn = 0; + $customer->save(); + + if ($res) { + return $this->success($res,trans('save_success')); + } else { + return $this->error(trans('save_fail')); + } + } + +} \ No newline at end of file diff --git a/app/crm/controller/TagGroupController.php b/app/crm/controller/TagGroupController.php new file mode 100644 index 0000000..7e5dff1 --- /dev/null +++ b/app/crm/controller/TagGroupController.php @@ -0,0 +1,67 @@ +get(); + $languageArr = Constants::LANGUAGE; + $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 $this->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 $this->error( trans('customer_id') . trans('not_null')); + } + if (Util::isEmpty($groupId)) { + return $this->error( 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 $this->success($res, trans('success')); + }else{ + return $this->error( trans('fail')); + } + } +} \ No newline at end of file diff --git a/app/crm/logic/CustomerLogic.php b/app/crm/logic/CustomerLogic.php new file mode 100644 index 0000000..0e6b1a0 --- /dev/null +++ b/app/crm/logic/CustomerLogic.php @@ -0,0 +1,8 @@ +select('id','name','name_en','status')->where('status',0)->toArray(); + return $list; + } +} \ No newline at end of file diff --git a/app/crm/model/Channel.php b/app/crm/model/Channel.php new file mode 100644 index 0000000..59f9237 --- /dev/null +++ b/app/crm/model/Channel.php @@ -0,0 +1,48 @@ + 'datetime:Y-m-d H:i:s', // 指定序列化格式 +// 'created_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式 + 'updated_at' => 'timestamp', // 指定序列化格式 + 'created_at' => 'timestamp', // 指定序列化格式 + ]; + + public static function getAll() + { + $list = self::get()->select('id','name','name_en','status')->where('status',0)->toArray(); + return $list; + } +} \ No newline at end of file diff --git a/app/crm/model/Country.php b/app/crm/model/Country.php new file mode 100644 index 0000000..29ba895 --- /dev/null +++ b/app/crm/model/Country.php @@ -0,0 +1,41 @@ +select('id','cn_addr','en_addr')->get()->toArray(); + return $list; + } +} \ No newline at end of file diff --git a/app/crm/model/Customer.php b/app/crm/model/Customer.php new file mode 100644 index 0000000..7db2f1e --- /dev/null +++ b/app/crm/model/Customer.php @@ -0,0 +1,135 @@ + 'datetime:Y-m-d H:i:s', // 指定序列化格式 + 'created_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式 + ]; + + /** + * 重新格式化时间 + * @param DateTimeInterface $date + * @return string + */ + protected function serializeDate(DateTimeInterface $date): string + { + return $date->format(Carbon::parse($date)->toDateTimeString()); + } + + /** + * @param $customer + * @param $request + * @param $tag 是否返回客户标签 + * @return mixed + */ + public static function getCustomer($customer, $request, $tag = false) + { + $language = $request->user['language'] ?: 'en'; + $customer['grade_txt'] = Util::language($language, Constants::GRADE_EN[$customer['grade']], Constants::GRADE_ZH[$customer['grade']], Constants::GRADE_RU[$customer['grade']]); + $customer['magnitude_txt'] = Util::language($language, Constants::MAGNITUDE_EN[$customer['magnitude']], Constants::MAGNITUDE[$customer['magnitude']], Constants::MAGNITUDE_RU[$customer['magnitude']]); + $customer['sex_txt'] = Util::language($language, Constants::SEX_EN[$customer['sex']], Constants::SEX[$customer['sex']], Constants::SEX_RU[$customer['sex']]); + + if ($customer['grade']<=2) { + $customer['follow'] = 0; + $customer['follow_txt'] = Util::language($language,'Following','跟进中','Продолжение'); + }elseif ($customer['grade']<5) { + $customer['follow'] = 1; + $customer['follow_txt'] = Util::language($language,'transacted','已成交','Транзакция завершена'); + }else{ + $customer['follow'] = 2; + $customer['follow_txt'] = Util::language($language,'lost','已流失','Потерянный'); + } + + $where = [ + 'customer_id' => $customer['id'] + ]; + $begin_follow = Follow::select('id','created_at','updated_at') + ->where($where) + ->min('created_at'); + + + $customer['begin_follow'] = Util::timeTotDate($begin_follow); +// $customer['created_at'] = Util::timeTotDate($customer['created_at']); +// $customer['updated_at'] = Util::timeTotDate($customer['updated_at']); + + $customer = Util::formatDate($customer,['follow_last']); + $nameLang = $language=='en'?'name_en':($language=='ru'?'name_ru':'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(); // 如果需要记录关联时间 + } + + + // 定义与 变更历史 的一对多关系 + public function his() + { + return $this->hasMany(CustomerHis::class, 'customer_id', 'id'); + } + + // 定义反向多对一关联 + public function user() + { + return $this->belongsTo(User::class, 'user_id', 'id'); + } +} \ No newline at end of file diff --git a/app/crm/model/CustomerHis.php b/app/crm/model/CustomerHis.php new file mode 100644 index 0000000..b7039dd --- /dev/null +++ b/app/crm/model/CustomerHis.php @@ -0,0 +1,68 @@ + 'datetime:Y-m-d H:i:s', // 指定序列化格式 +// 'created_at' => 'timestamp', // 指定序列化格式 + ]; + + /** + * 重新格式化时间 + * @param DateTimeInterface $date + * @return string + */ + protected function serializeDate(DateTimeInterface $date): string + { + return $date->format(Carbon::parse($date)->toDateTimeString()); + } + + // 定义反向多对一关联 + public function customer() + { + return $this->belongsTo(Customer::class, 'customer_id', 'id'); + } + + // 禁用 updated_at 的自动更新 + public function setUpdatedAt($value) + { + return $this; // 不做任何操作 + } +} \ No newline at end of file diff --git a/app/crm/model/CustomerTag.php b/app/crm/model/CustomerTag.php new file mode 100644 index 0000000..b6a26bf --- /dev/null +++ b/app/crm/model/CustomerTag.php @@ -0,0 +1,36 @@ + 'datetime:Y-m-d H:i:s', // 指定序列化格式 + 'created_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式 + 'follow_time' => 'datetime:Y-m-d H:i:s', // 指定序列化格式 +// 'updated_at' => 'timestamp', // 指定序列化格式 +// 'created_at' => 'timestamp', // 指定序列化格式 + ]; + + public static function getFollow($follow,$domain = 'https://vehicle-album.oss-cn-beijing.aliyuncs.com') + { + $follow['type_txt'] = Constants::FOLLOW[$follow['type']]; + $follow['firstFollowtime'] = $follow['follow_time']; + $ossservice = new OssService(); + $oss_picture = $ossservice->generatePrivateUrl($follow['picture'],86400); + $follow['oss_picture'] = $oss_picture; +// $follow = Util::formatDate($follow); + return $follow; + } +} \ No newline at end of file diff --git a/app/crm/model/Tag.php b/app/crm/model/Tag.php new file mode 100644 index 0000000..4b00471 --- /dev/null +++ b/app/crm/model/Tag.php @@ -0,0 +1,55 @@ +belongsTo(TagGroup::class, 'group_id', 'id'); + } + + public function customers() + { + return $this->belongsToMany(Customer::class, 'customer_tag', 'tag_id', 'customer_id'); + } +} \ No newline at end of file diff --git a/app/crm/model/TagGroup.php b/app/crm/model/TagGroup.php new file mode 100644 index 0000000..9c2e419 --- /dev/null +++ b/app/crm/model/TagGroup.php @@ -0,0 +1,50 @@ +hasMany(Tag::class, 'group_id', 'id'); + } +} \ No newline at end of file diff --git a/app/crm/service/CustomerService.php b/app/crm/service/CustomerService.php new file mode 100644 index 0000000..d21d460 --- /dev/null +++ b/app/crm/service/CustomerService.php @@ -0,0 +1,27 @@ +input('page', 1); +// $perPage = $request->input('per_page', 10); + $perPage = $params['size'] ?? 10; + $page = $params['current'] ?? 1; + $where = []; + $user_id =$params['user_id']; + if(empty($user_id) || $user_id == 0){ + $where[] = ['user_id', '=', $user_id]; + } + $user = Customer::with('user')->where($where)->paginate($perPage, ['*'], 'page', $page); + $user = $user->toArray(); + foreach ($user['data'] as &$item) { + unset($item['password']); + } + return $user; + } +} \ No newline at end of file diff --git a/app/crm/service/FollowService.php b/app/crm/service/FollowService.php new file mode 100644 index 0000000..b870416 --- /dev/null +++ b/app/crm/service/FollowService.php @@ -0,0 +1,53 @@ +input('page', 1); +// $perPage = $request->input('per_page', 10); + + //客户id + $customer_id =$param['customer_id']; + + $where = []; + $where['customer_id'] = $customer_id; + + //用户角色 + $userId = $request->user['id']; + if(Util::isEmpty($userId)){ + return $this->error(trans('user_none')); + } + if($request->user['role']!=1){ + $where['user_id'] = $userId; + } + + //跟进id + $id = Util::getParam($request,'id'); + if(!Util::isEmpty($id)){ + $where['id'] = $id; + } + + // 执行分页查询 + $data = Follow::where($where) + ->orderBy('id', 'desc')->get(); +// ->paginate($perPage, ['*'], 'page', $page); + + +// $host = $request->host(); + $url = 'http:'.$request->url(); + foreach ($data as &$value){ + $value = Follow::getFollow($value); + } + + return $this->success($data,trans('success')); + } +} \ No newline at end of file diff --git a/app/crm/utils/Util.php b/app/crm/utils/Util.php new file mode 100644 index 0000000..db6743b --- /dev/null +++ b/app/crm/utils/Util.php @@ -0,0 +1,121 @@ +input($param,$default); + if(empty($param) && $default!==''){ + $param = $default; + } + return $param; + } + + /** + * 失败 + */ + public static function fail($data = [],$message = '', $code = -1) + { + $result = [ + 'code' => $code, + 'message' => $message, + 'data' => $data + ]; + return json($result); + } + + /** + * 成功 + */ + public static function success($data = [],$message = '', $code = 0) + { + $result = [ + 'code' => $code, + 'message' => $message, + 'data' => $data + ]; + return json($result); + } + + /** + * 分页查询返回 + */ + public static function page($data,$message = '', $code = 0) + { + $result = [ + 'code' => $code, + 'message' => $message + ]; + + $result['data'] = [ + 'list' => $data->items(), // 当前页数据 + 'total' => $data->total(), // 总记录数 + 'current_page' => $data->currentPage(), + 'per_page' => $data->perPage(), + 'last_page' => $data->lastPage() + ]; + return json($result); + } + + /** + * 日期格式转化 + */ + public static function timeTotDate($time = 0, $format = 'Y-m-d H:i:s') + { + if (empty($time)) { + return ''; + } + return date($format, $time); + } + + /** + * 格式化创建时间 + */ + public static function formatDate($value,$key = ['created_at','updated_at']) + { + foreach ($key as $k){ + $value[$k]= self::timeTotDate($value[$k]); + } + return $value; + } + + /** + * 格式化创建时间 + */ + public static function language($language,$en,$zh_CN,$ru) + { + if ($language == 'zh_CN'){ + return $zh_CN; + }elseif ($language == 'ru'){ + return $ru; + } + return $en; + } + +} \ No newline at end of file diff --git a/app/crm/validate/FollowValidate.php b/app/crm/validate/FollowValidate.php new file mode 100644 index 0000000..2ed6e71 --- /dev/null +++ b/app/crm/validate/FollowValidate.php @@ -0,0 +1,21 @@ + 'require', + ]; + + protected $message = [ + 'customer_id.require' => '用户id不能为空', + ]; + + protected $scene = [ + 'upwd_list' => ['customer_id'], + ]; +} \ No newline at end of file diff --git a/config/constants/Constants.php b/config/constants/Constants.php index 1e77a2b..6797078 100644 --- a/config/constants/Constants.php +++ b/config/constants/Constants.php @@ -34,4 +34,104 @@ class Constants self::TICKET_STATUS['REJECTED'] => 'Закрыть', ]; + //客户分级 USTOMER_GRADE + + public const GRADE = [ + 'INITIAL' => 0, // 初步接触 + 'COMMUNICATE' => 1, // 需求沟通 + 'PLAN' => 2, // 方案推进 + 'DEAL' => 3, // 成交阶段 + 'SALES' => 4, // 售后阶段 + 'LOSS' => 5, // 停滞或流失 + ]; + + public const GRADE_ZH = [ + self::GRADE['INITIAL'] => '初步接触', + self::GRADE['COMMUNICATE'] => '需求沟通', + self::GRADE['PLAN'] => '方案推进', + self::GRADE['DEAL'] => '成交阶段', + self::GRADE['SALES'] => '售后阶段', + self::GRADE['LOSS'] => '停滞或流失', + ]; + public const GRADE_EN = [ + self::GRADE['INITIAL'] => 'Initial contact', + self::GRADE['COMMUNICATE'] => 'Demand Chat', + self::GRADE['PLAN'] => 'promotion of the plan', + self::GRADE['DEAL'] => 'Transaction Stage', + self::GRADE['SALES'] => 'After Sales', + self::GRADE['LOSS'] => 'Stagnation or loss', + ]; + public const GRADE_RU = [ + self::GRADE['INITIAL'] => 'Первоначальные контакты', + self::GRADE['COMMUNICATE'] => 'Потребности в общении', + self::GRADE['PLAN'] => 'Продвижение программы', + self::GRADE['DEAL'] => 'Этап сделки', + self::GRADE['SALES'] => 'Послепродажный этап', + self::GRADE['LOSS'] => 'Застой или потеря', + ]; + + //客户重要性 + public const CUSTOMER_MAGNITUDE_INITIAL = 0; // 金牌商机 + public const CUSTOMER_MAGNITUDE_COMMUNICATE = 1; // 银牌商机 + public const CUSTOMER_MAGNITUDE_PLAN = 2; // 铜牌商机 + + public const MAGNITUDE = [ + self::CUSTOMER_MAGNITUDE_INITIAL => '金牌商机', + 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', + ]; + + public const MAGNITUDE_RU = [ + self::CUSTOMER_MAGNITUDE_INITIAL => 'Золотой бизнес', + self::CUSTOMER_MAGNITUDE_COMMUNICATE => 'Серебряный бизнес', + self::CUSTOMER_MAGNITUDE_PLAN => 'Бронзовый бизнес.', + ]; + + + //跟进类型 + public const CUSTOMER_FOLLOW_VISIT = 0; // 线下拜访 + public const CUSTOMER_FOLLOW_UP = 1; // 线上跟进 + + public const FOLLOW = [ + 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; // 未知 + public const CUSTOMER_SEX_MAN = 1; // 男 + public const CUSTOMER_SEX_WOMAN = 2; // 女 + + public const SEX = [ + self::CUSTOMER_SEX_UNKNOWN => '未知', + 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', + ]; + + public const SEX_RU = [ + self::CUSTOMER_SEX_UNKNOWN => 'неизвестный', + self::CUSTOMER_SEX_MAN => 'мужской', + self::CUSTOMER_SEX_WOMAN => 'женский', + ]; + + public const SIGN = [ + ['id' => 'xinyouhe', 'name' => '新友合'], + ['id' => 'mbaf', 'name' => 'MAGIC BRIDGE AUTO FZE'] + ]; + + public const LANGUAGE = ['en', 'zh_CN','ru']; } \ No newline at end of file From a45d586f07d58ee9f04c2605523e540962838947 Mon Sep 17 00:00:00 2001 From: "HESU\\HESU" <1696136552@qq.com> Date: Thu, 10 Jul 2025 14:27:56 +0800 Subject: [PATCH 2/4] crm --- app/crm/controller/FollowController.php | 22 ++++++++++++---- app/crm/model/Customer.php | 2 +- app/crm/model/CustomerHis.php | 2 +- app/crm/model/Follow.php | 13 +-------- app/crm/model/Tag.php | 2 +- app/crm/model/TagGroup.php | 2 +- app/crm/service/FollowService.php | 35 ++++++++++++++++--------- app/crm/validate/FollowValidate.php | 2 +- config/route.php | 9 +++++++ resource/translations/ar/messages.php | 31 ++++++++++++++++++++++ resource/translations/en/messages.php | 31 ++++++++++++++++++++++ resource/translations/ru/messages.php | 31 ++++++++++++++++++++++ resource/translations/zh/messages.php | 31 ++++++++++++++++++++++ 13 files changed, 179 insertions(+), 34 deletions(-) diff --git a/app/crm/controller/FollowController.php b/app/crm/controller/FollowController.php index 7f08e7d..7ee34a4 100644 --- a/app/crm/controller/FollowController.php +++ b/app/crm/controller/FollowController.php @@ -39,9 +39,9 @@ class FollowController extends BaseController public function list(Request $request) { try { - $data = $this->validate(new FollowValidate(), $request->get(), 'upwd_list'); - $result = (new FollowService())->list($request->all()); - return $this->success($this->page($result)); + $data = $this->validate(new FollowValidate(), $request->get(), 'list'); + $result = (new FollowService())->list($request->all(),$request->user->uid); + return $this->success($result); } catch (\Throwable $e) { return $this->error($e->getMessage()); } @@ -69,7 +69,7 @@ class FollowController extends BaseController return $this->error('记录不存在'); } - $res = Follow::getFollow($res); + $res = FollowService::getFollow($res); return $this->success($res); } @@ -96,7 +96,7 @@ class FollowController extends BaseController } $data = [ - 'user_id'=>$request->user['id'], + 'user_id'=>$request->user->uid, 'customer_id'=>$customer_id, 'type'=>$type, 'picture'=>$picture, @@ -117,6 +117,18 @@ class FollowController extends BaseController $customer->warn = 0; $customer->save(); + $follow_next = Util::getParam($request, 'follow_next', 0); + $follow_remark = Util::getParam($request, 'follow_remark', 0); + if($res && (!empty($follow_next))){ + $data = [ + 'follow_next' => $follow_next, + 'follow_remark' => $follow_remark, + 'warn' => 0, + ]; + $res = Customer::where('id', $customer_id) + ->update($data); + } + if ($res) { return $this->success($res,trans('save_success')); } else { diff --git a/app/crm/model/Customer.php b/app/crm/model/Customer.php index 7db2f1e..c03d4ac 100644 --- a/app/crm/model/Customer.php +++ b/app/crm/model/Customer.php @@ -17,7 +17,7 @@ class Customer extends Model * * @var string */ - protected $table = 'customer'; + protected $table = 'crm_customer'; /** * The primary key associated with the table. diff --git a/app/crm/model/CustomerHis.php b/app/crm/model/CustomerHis.php index b7039dd..65d7de6 100644 --- a/app/crm/model/CustomerHis.php +++ b/app/crm/model/CustomerHis.php @@ -17,7 +17,7 @@ class CustomerHis extends Model * * @var string */ - protected $table = 'customer_his'; + protected $table = 'crm_customer_his'; /** * The primary key associated with the table. diff --git a/app/crm/model/Follow.php b/app/crm/model/Follow.php index e44c08b..778b669 100644 --- a/app/crm/model/Follow.php +++ b/app/crm/model/Follow.php @@ -16,7 +16,7 @@ class Follow extends Model * * @var string */ - protected $table = 'follow'; + protected $table = 'crm_follow'; /** * The primary key associated with the table. @@ -47,15 +47,4 @@ class Follow extends Model // 'updated_at' => 'timestamp', // 指定序列化格式 // 'created_at' => 'timestamp', // 指定序列化格式 ]; - - public static function getFollow($follow,$domain = 'https://vehicle-album.oss-cn-beijing.aliyuncs.com') - { - $follow['type_txt'] = Constants::FOLLOW[$follow['type']]; - $follow['firstFollowtime'] = $follow['follow_time']; - $ossservice = new OssService(); - $oss_picture = $ossservice->generatePrivateUrl($follow['picture'],86400); - $follow['oss_picture'] = $oss_picture; -// $follow = Util::formatDate($follow); - return $follow; - } } \ No newline at end of file diff --git a/app/crm/model/Tag.php b/app/crm/model/Tag.php index 4b00471..3e7ec25 100644 --- a/app/crm/model/Tag.php +++ b/app/crm/model/Tag.php @@ -17,7 +17,7 @@ class Tag extends Model * * @var string */ - protected $table = 'tag'; + protected $table = 'crm_tag'; /** * The primary key associated with the table. diff --git a/app/crm/model/TagGroup.php b/app/crm/model/TagGroup.php index 9c2e419..5b5e28e 100644 --- a/app/crm/model/TagGroup.php +++ b/app/crm/model/TagGroup.php @@ -17,7 +17,7 @@ class TagGroup extends Model * * @var string */ - protected $table = 'tag_group'; + protected $table = 'crm_tag_group'; /** * The primary key associated with the table. diff --git a/app/crm/service/FollowService.php b/app/crm/service/FollowService.php index b870416..89b7c2b 100644 --- a/app/crm/service/FollowService.php +++ b/app/crm/service/FollowService.php @@ -2,13 +2,15 @@ namespace app\crm\service; +use app\common\service\OssService; use app\crm\model\Follow; use app\crm\utils\Util; +use config\constants\Constants; class FollowService { - public function list($param) + public function list($param, $userId) { @@ -22,16 +24,9 @@ class FollowService $where['customer_id'] = $customer_id; //用户角色 - $userId = $request->user['id']; - if(Util::isEmpty($userId)){ - return $this->error(trans('user_none')); - } - if($request->user['role']!=1){ - $where['user_id'] = $userId; - } //跟进id - $id = Util::getParam($request,'id'); + $id = $param['id']??null; if(!Util::isEmpty($id)){ $where['id'] = $id; } @@ -43,11 +38,27 @@ class FollowService // $host = $request->host(); - $url = 'http:'.$request->url(); +// $url = 'http:'.$request->url(); foreach ($data as &$value){ - $value = Follow::getFollow($value); + $value = self::getFollow($value); } - return $this->success($data,trans('success')); + return $data; + } + + + + public static function getFollow($follow,$domain = 'https://vehicle-album.oss-cn-beijing.aliyuncs.com') + { + $follow['type_txt'] = Constants::FOLLOW[$follow['type']]; + $follow['firstFollowtime'] = $follow['follow_time']; + $oss_picture = ''; + if(!empty($follow['picture'])){ + $ossservice = new OssService(); + $oss_picture = $ossservice->generatePrivateUrl($follow['picture'],86400); + } + $follow['oss_picture'] = $oss_picture; +// $follow = Util::formatDate($follow); + return $follow; } } \ No newline at end of file diff --git a/app/crm/validate/FollowValidate.php b/app/crm/validate/FollowValidate.php index 2ed6e71..a92c4a0 100644 --- a/app/crm/validate/FollowValidate.php +++ b/app/crm/validate/FollowValidate.php @@ -16,6 +16,6 @@ class FollowValidate extends Validate ]; protected $scene = [ - 'upwd_list' => ['customer_id'], + 'list' => ['customer_id'], ]; } \ No newline at end of file diff --git a/config/route.php b/config/route.php index db2c831..0e25da4 100644 --- a/config/route.php +++ b/config/route.php @@ -65,3 +65,12 @@ Route::group('/ticket', function () { }); +//crm +Route::group('/crm', function () { + Route::any('/follow/list', [app\crm\controller\FollowController::class, 'list']); + Route::any('/follow/detail', [app\crm\controller\FollowController::class, 'detail']); + Route::any('/follow/add', [app\crm\controller\FollowController::class, 'save']); + Route::any('/follow/getFollowType', [app\crm\controller\FollowController::class, 'getFollowType']); + Route::any('/follow/getFollowType', [app\crm\controller\FollowController::class, 'getFollowType']); +}); + diff --git a/resource/translations/ar/messages.php b/resource/translations/ar/messages.php index a701f87..7430697 100644 --- a/resource/translations/ar/messages.php +++ b/resource/translations/ar/messages.php @@ -2,4 +2,35 @@ return [ 'status_not_modified' => 'الدولة لا يمكن تعديلها عكسيا', + 'success' => ' النجاح', + 'fail' => ' الفشل', + 'login_success' => ' تم تسجيل الدخول بنجاح', + 'password_error' => ' كلمة المرور غير صحيحة', + 'user_none' => ' المستخدم غير موجود', + 'user_id' => ' معرف المستخدم', + 'user_login' => ' الرجاء تسجيل الدخول أولاً', + 'not_null' => ' لا يمكن أن يكون فارغًا', + 'code_error' => ' رمز التحقق غير صحيح', + 'format_error' => ' تنسيق غير صحيح', + 'email_repeat' => ' البريد الإلكتروني مكرر', + 'email_error' => ' تنسيق البريد الإلكتروني غير صحيح', + 'save_success' => ' تم الحفظ بنجاح', + 'save_fail' => ' فشل الحفظ', + 'register_success' => ' تم التسجيل بنجاح', + 'register_fail' => ' فشل التسجيل', + 'language_success' => ' تم تغيير اللغة بنجاح', + 'language_fail' => ' فشل تغيير اللغة', + 'param_error' => ' خطأ في المعلمات', + 'required_not_null' => ' الحقول المطلوبة لا يمكن أن تكون فارغة', + 'picture_not_null' => ' لا يمكن أن تكون الصورة فارغة', + 'contacts_not_null' => ' لا يمكن أن يكون جهة الاتصال أو البريد الإلكتروني أو الهاتف فارغين جميعًا في نفس الوقت', + 'car_type_not_null' => ' لا يمكن أن تكون التفضيلات فارغة', + 'channel_not_null' => ' لا يمكن أن تكون القناة فارغة', + 'email_consistent' => ' البريد الإلكتروني غير متطابق', + 'sign_not_null' => ' لم يتم تعيين الشركة التابعة', + 'password_short' => ' لا يمكن أن تكون كلمة المرور أقل من 6 أحرف', + 'id_empty' => ' لا يمكن أن يكون المعرف فارغًا', + 'customer_id' => ' معرف العميل', + 'tag_group_id' => ' معرف مجموعة العلامات', + 'claim_fail' => ' لا يمكن استلام العملاء الذين لديهم مالك بالفعل', ]; \ No newline at end of file diff --git a/resource/translations/en/messages.php b/resource/translations/en/messages.php index c676eb2..342ffad 100644 --- a/resource/translations/en/messages.php +++ b/resource/translations/en/messages.php @@ -2,4 +2,35 @@ return [ 'status_not_modified' => 'The status cannot be reversed for modification', + 'success' => ' success', + 'fail' => ' fail', + 'login_success' => ' login success', + 'password_error' => ' password error', + 'user_none' => ' user none', + 'user_id' => ' user ID', + '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', + 'register_fail' => ' register fail', + 'language_success' => ' Successfully switched languages', + 'language_fail' => ' Language switching failed', + 'param_error' => ' param error', + 'required_not_null' => ' required not_ ull', + 'picture_not_null' => ' picture not null', + 'contacts_not_null' => ' Contact person, email, and phone cannot be empty at the same time', + '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', + 'claim_fail' => ' Cannot claim ownership of customers', ]; \ No newline at end of file diff --git a/resource/translations/ru/messages.php b/resource/translations/ru/messages.php index 96ab3a4..3a1839f 100644 --- a/resource/translations/ru/messages.php +++ b/resource/translations/ru/messages.php @@ -2,4 +2,35 @@ return [ 'status_not_modified' => 'Статус не может быть изменен в обратном направлении', + 'success' => ' Успех', + 'fail' => ' Неудача', + 'login_success' => ' Регистрация завершена', + 'password_error' => ' Ошибка пароля', + 'user_none' => ' Пользователь не существует', + 'user_id' => ' Идентификатор пользователя', + 'user_login' => ' Пожалуйста, войдите.', + 'not_null' => ' Нельзя быть пустым', + 'code_error' => ' Ошибка кода проверки', + 'format_error' => ' Ошибка формата', + 'email_repeat' => ' Почтовый ящик повторяется', + 'email_error' => ' Ошибка формата почтового ящика', + 'save_success' => ' Сохранить успешно', + 'save_fail' => ' Ошибка сохранения', + 'register_success' => ' Регистрация успешно', + 'register_fail' => ' Ошибка регистрации', + 'language_success' => ' Переключить язык успешно', + 'language_fail' => ' Ошибка переключения языка', + 'param_error' => ' Ошибка параметра', + 'required_not_null' => ' Обязательное заполнение не может быть пустым.', + 'picture_not_null' => ' Фотографии не могут быть пустыми', + 'contacts_not_null' => ' Контакты, почтовый ящик, телефон не может быть одновременно пустым', + 'car_type_not_null' => ' Предпочтения не могут быть пустыми', + 'channel_not_null' => ' Каналы не могут быть пустыми', + 'email_consistent' => ' Почтовый ящик не совпадает', + 'sign_not_null' => ' Компания не создана', + 'password_short' => ' Пароль не может быть меньше 6.', + 'id_empty' => ' ID не может быть пустым', + 'customer_id' => ' Идентификатор клиента', + 'tag_group_id' => ' Идентификатор группы меток', + 'claim_fail' => ' Невозможность получения принадлежащего клиенту', ]; \ No newline at end of file diff --git a/resource/translations/zh/messages.php b/resource/translations/zh/messages.php index 229d7ee..96c3cb7 100644 --- a/resource/translations/zh/messages.php +++ b/resource/translations/zh/messages.php @@ -2,4 +2,35 @@ return [ 'status_not_modified' => '状态不能逆向修改', + 'success' => ' 成功', + 'fail' => ' 失败', + 'login_success' => ' 登录成功', + 'password_error' => ' 密码错误', + 'user_none' => ' 用户不存在', + 'user_id' => ' 用户ID', + 'user_login' => ' 请先登录', + 'not_null' => ' 不能为空', + 'code_error' => ' 验证码错误', + 'format_error' => ' 格式错误', + 'email_repeat' => ' 邮箱重复', + 'email_error' => ' 邮箱格式错误', + 'save_success' => ' 保存成功', + 'save_fail' => ' 保存失败', + 'register_success' => ' 注册成功', + 'register_fail' => ' 注册失败', + 'language_success' => ' 切换语言成功', + 'language_fail' => ' 切换语言失败', + 'param_error' => ' 参数错误', + 'required_not_null' => ' 必填项不能为空', + 'picture_not_null' => ' 图片不能为空', + 'contacts_not_null' => ' 联系人,邮箱,电话不能同时为空', + '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', + 'claim_fail' => ' 不能领取有归属客户', ]; \ No newline at end of file From 9a13c23788c97271ef79a24566eb471565dd33af Mon Sep 17 00:00:00 2001 From: "HESU\\HESU" <1696136552@qq.com> Date: Tue, 15 Jul 2025 13:52:31 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=AE=A2=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/crm/controller/CustomerController.php | 1 + app/crm/model/Customer.php | 4 ++-- app/crm/model/CustomerTag.php | 2 +- app/crm/model/Tag.php | 2 +- app/crm/service/CustomerService.php | 11 ++++++----- config/route.php | 7 ++++++- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/crm/controller/CustomerController.php b/app/crm/controller/CustomerController.php index d8b4887..9c9cd05 100644 --- a/app/crm/controller/CustomerController.php +++ b/app/crm/controller/CustomerController.php @@ -130,6 +130,7 @@ class CustomerController extends BaseController $param = $request->all(); $param['user_id'] = $request->user->uid; $result = (new CustomerService())->list($param); + return $this->success($this->page($result)); } catch (\Throwable $e) { return $this->error($e->getMessage()); diff --git a/app/crm/model/Customer.php b/app/crm/model/Customer.php index 3935a79..6c17787 100644 --- a/app/crm/model/Customer.php +++ b/app/crm/model/Customer.php @@ -66,7 +66,7 @@ class Customer extends Model */ public static function getCustomer($customer, $request, $tag = false) { - $language = $request->user['language'] ?: 'en'; + $language = 'zh_CN' ?: 'en'; $customer['grade_txt'] = Util::language($language, Constants::GRADE_EN[$customer['grade']], Constants::GRADE_ZH[$customer['grade']], Constants::GRADE_RU[$customer['grade']]); $customer['magnitude_txt'] = Util::language($language, Constants::MAGNITUDE_EN[$customer['magnitude']], Constants::MAGNITUDE[$customer['magnitude']], Constants::MAGNITUDE_RU[$customer['magnitude']]); $customer['sex_txt'] = Util::language($language, Constants::SEX_EN[$customer['sex']], Constants::SEX[$customer['sex']], Constants::SEX_RU[$customer['sex']]); @@ -117,7 +117,7 @@ class Customer extends Model */ public function tags() { - return $this->belongsToMany(Tag::class, 'customer_tag', 'customer_id', 'tag_id') + return $this->belongsToMany(Tag::class, 'crm_customer_tag', 'customer_id', 'tag_id') ->withTimestamps(); // 如果需要记录关联时间 } diff --git a/app/crm/model/CustomerTag.php b/app/crm/model/CustomerTag.php index b6a26bf..3a0c567 100644 --- a/app/crm/model/CustomerTag.php +++ b/app/crm/model/CustomerTag.php @@ -14,7 +14,7 @@ class CustomerTag extends Model * * @var string */ - protected $table = 'customer_tag'; + protected $table = 'crm_customer_tag'; /** * The primary key associated with the table. diff --git a/app/crm/model/Tag.php b/app/crm/model/Tag.php index 3e7ec25..e58bb87 100644 --- a/app/crm/model/Tag.php +++ b/app/crm/model/Tag.php @@ -50,6 +50,6 @@ class Tag extends Model public function customers() { - return $this->belongsToMany(Customer::class, 'customer_tag', 'tag_id', 'customer_id'); + return $this->belongsToMany(Customer::class, 'crm_customer_tag', 'tag_id', 'customer_id'); } } \ No newline at end of file diff --git a/app/crm/service/CustomerService.php b/app/crm/service/CustomerService.php index d21d460..74baab2 100644 --- a/app/crm/service/CustomerService.php +++ b/app/crm/service/CustomerService.php @@ -17,11 +17,12 @@ class CustomerService if(empty($user_id) || $user_id == 0){ $where[] = ['user_id', '=', $user_id]; } - $user = Customer::with('user')->where($where)->paginate($perPage, ['*'], 'page', $page); - $user = $user->toArray(); - foreach ($user['data'] as &$item) { - unset($item['password']); - } + $user = Customer::where($where)->paginate($perPage, ['*'], 'page', $page); +// $user = Customer::with('user')->where($where)->paginate($perPage, ['*'], 'page', $page); +// $user = $user->toArray(); +// foreach ($user['data'] as &$item) { +// unset($item['password']); +// } return $user; } } \ No newline at end of file diff --git a/config/route.php b/config/route.php index e8af21a..4c29ced 100644 --- a/config/route.php +++ b/config/route.php @@ -81,10 +81,15 @@ Route::group('/ticket', function () { //crm Route::group('/crm', function () { + //跟进 Route::any('/follow/list', [app\crm\controller\FollowController::class, 'list']); Route::any('/follow/detail', [app\crm\controller\FollowController::class, 'detail']); Route::any('/follow/add', [app\crm\controller\FollowController::class, 'save']); Route::any('/follow/getFollowType', [app\crm\controller\FollowController::class, 'getFollowType']); - Route::any('/follow/getFollowType', [app\crm\controller\FollowController::class, 'getFollowType']); + + //客户 + Route::any('/customer/list', [app\crm\controller\CustomerController::class, 'list']); + Route::any('/customer/detail', [app\crm\controller\CustomerController::class, 'detail']); + Route::any('/customer/add', [app\crm\controller\CustomerController::class, 'save']); }); From 416050a387b4ffb76d0c55a06d93b3eab3ae6c4f Mon Sep 17 00:00:00 2001 From: "HESU\\HESU" <1696136552@qq.com> Date: Thu, 17 Jul 2025 09:36:46 +0800 Subject: [PATCH 4/4] crm --- app/crm/controller/CustomerController.php | 144 +++++++++++++--------- app/crm/controller/FollowController.php | 60 ++++----- app/crm/logic/CustomerLogic.php | 7 ++ app/crm/model/Channel.php | 4 +- app/crm/model/Country.php | 2 +- app/crm/model/Customer.php | 3 +- app/crm/service/CustomerService.php | 12 ++ app/crm/service/FollowService.php | 17 +-- config/route.php | 5 + 9 files changed, 156 insertions(+), 98 deletions(-) diff --git a/app/crm/controller/CustomerController.php b/app/crm/controller/CustomerController.php index 9c9cd05..5fc0750 100644 --- a/app/crm/controller/CustomerController.php +++ b/app/crm/controller/CustomerController.php @@ -2,11 +2,12 @@ namespace app\crm\controller; +use app\common\model\User; use app\crm\model\Channel; +use app\crm\model\Country; use app\crm\model\Customer; use app\crm\model\CustomerHis; use app\crm\model\Follow; -use app\crm\model\User; use app\crm\service\CustomerService; use app\crm\utils\Util; use config\constants\Constants; @@ -24,9 +25,9 @@ class CustomerController extends BaseController { $grade = []; $gradeConstants = Constants::GRADE_EN; - if($request->user['language'] == 'zh_CN'){ - $gradeConstants = Constants::GRADE; - }elseif ($request->user['language'] == 'ru'){ + if('zh_CN' == 'zh_CN'){ + $gradeConstants = Constants::GRADE_ZH; + }elseif ('zh_CN' == 'ru'){ $gradeConstants = Constants::GRADE_RU; } foreach ($gradeConstants as $key => $value) { @@ -35,7 +36,7 @@ class CustomerController extends BaseController 'name' => $value, ]; } - return Util::success($grade); + return $this->success($grade); } /** @@ -47,9 +48,9 @@ class CustomerController extends BaseController { $grade = []; $magnitudeConstants = Constants::MAGNITUDE_EN; - if($request->user['language'] == 'zh_CN'){ + if('zh_CN' == 'zh_CN'){ $magnitudeConstants = Constants::MAGNITUDE; - }elseif ($request->user['language'] == 'ru'){ + }elseif ('zh_CN' == 'ru'){ $magnitudeConstants = Constants::MAGNITUDE_RU; } foreach ($magnitudeConstants as $key => $value) { @@ -58,7 +59,7 @@ class CustomerController extends BaseController 'name' => $value, ]; } - return Util::success($grade); + return $this->success($grade); } /** @@ -70,17 +71,40 @@ class CustomerController extends BaseController { $list = Channel::getAll(); - if($request->user['language'] != 'zh_CN'){ + if('zh_CN' != 'zh_CN'){ foreach ($list as &$value) { $value['name'] = $value['name_en']; } - }elseif ($request->user['language'] == 'ru'){ + }elseif ('zh_CN' == 'ru'){ foreach ($list as &$value) { $value['name'] = $value['name_ru']; } } - return Util::success($list); + return $this->success($list); + + } + + /** + * 国家 + * @param Request $request + * @return \support\Response + */ + public function getCountry(Request $request) + { + $list = Country::getAll(); + + if('zh_CN' != 'zh_CN'){ + foreach ($list as &$value) { + $value['name'] = $value['name_en']; + } + }elseif ('zh_CN' == 'ru'){ + foreach ($list as &$value) { + $value['name'] = $value['name_ru']; + } + } + + return $this->success($list); } @@ -91,12 +115,13 @@ class CustomerController extends BaseController */ public function waitFollow(Request $request) { - $userId = $request->user['id']; + $userId = $request->user->uid; $filter = Util::getParam($request, 'filter'); $page = $request->input('page', 1); $perPage = $request->input('per_page', 10); $where = [ ['user_id', '=', $userId], + ['corp_abbr', '=', $request->basic_data['corp_abbr']], ['follow_next', '<>', 0], ]; @@ -116,7 +141,7 @@ class CustomerController extends BaseController $item['follow_remaining'] = $item->follow_next-time(); $item['follow_next'] = date('Y-m-d H:i:s',$item->follow_next); } - return Util::page($customer); + return $this->success($this->page($customer)); } /** @@ -129,6 +154,7 @@ class CustomerController extends BaseController try { $param = $request->all(); $param['user_id'] = $request->user->uid; + $param['corp_abbr'] = $request->basic_data['corp_abbr']; $result = (new CustomerService())->list($param); return $this->success($this->page($result)); @@ -146,18 +172,18 @@ class CustomerController extends BaseController { $id = Util::getParam($request,'id', ''); if (Util::isEmpty($id)) { - return Util::fail([], trans('id_empty')); + return $this->error(trans('id_empty')); } - $userId = $request->user['id']; + $userId = $request->user->uid; $where = [ 'id' => $id, 'user_id' => $userId, ]; $res = Customer::where($where)->restore(); if($res){ - return Util::success($res, trans('success')); + return $this->success($res, trans('success')); }else{ - return Util::fail([], trans('fail')); + return $this->error(trans('fail')); } } @@ -171,21 +197,22 @@ class CustomerController extends BaseController { $id = Util::getParam($request, 'id'); if (Util::isEmpty($id)) { - return Util::fail([], 'id' . trans('not_null')); + return $this->error('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(); +// $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(); + $res = (new CustomerService)->detail($request->all()); if ($res) { $res->toArray(); } else { - return Util::fail([], '记录不存在'); + return $this->error('记录不存在'); } $res = Customer::getCustomer($res, $request, true); - return Util::success($res); + return $this->success($res); } /** @@ -198,25 +225,26 @@ class CustomerController extends BaseController $id = Util::getParam($request, 'id'); $channel_id = Util::getParam($request, 'channel_id'); if (Util::isEmpty($channel_id)) { - return Util::fail([], trans('channel_not_null')); + return $this->error(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')); +// return $this->error('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')); + return $this->error(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')); + return $this->error(trans('contacts_not_null')); } $data = [ - 'user_id' => $request->user['id'], + 'user_id' => $request->user->uid, + 'corp_abbr' => $request->basic_data['corp_abbr'], 'grade' => Util::getParam($request, 'grade', 0), 'channel_id' => $channel_id, 'country_id' => $country_id, @@ -244,9 +272,9 @@ class CustomerController extends BaseController } if ($res) { - return Util::success($res, trans('save_success')); + return $this->success($res, trans('save_success')); } else { - return Util::fail($res, trans('save_fail')); + return $this->error(trans('save_fail')); } } @@ -261,7 +289,7 @@ class CustomerController extends BaseController { $id = Util::getParam($request, 'id'); if (Util::isEmpty($id)) { - return Util::fail([], 'id' . trans('not_null')); + return $this->error('id' . trans('not_null')); } $data = [ 'follow_next' => Util::getParam($request, 'follow_next', 0), @@ -273,9 +301,9 @@ class CustomerController extends BaseController ->update($data); if ($res) { - return Util::success($res, trans('save_success')); + return $this->success($res, trans('save_success')); } else { - return Util::fail($res, trans('save_fail')); + return $this->error(trans('save_fail')); } } @@ -289,14 +317,14 @@ class CustomerController extends BaseController $id = Util::getParam($request, 'id'); $force = Util::getParam($request, 'force',''); - $userId = $request->user['id']; + $userId = $request->user->uid; $where = [ 'id' => $id, 'user_id' => $userId, ]; $customer = Customer::where($where)->withTrashed()->first(); if(empty($customer)){ - return Util::fail('', trans('fail')); + return $this->error( trans('fail')); } if($force == 'force'){ $res = $customer->forceDelete(); @@ -304,9 +332,9 @@ class CustomerController extends BaseController $res = $customer->delete(); } if ($res) { - return Util::success($res, trans('success')); + return $this->success($res, trans('success')); } else { - return Util::fail($res, trans('fail')); + return $this->error(trans('fail')); } } @@ -319,12 +347,14 @@ class CustomerController extends BaseController { $created = Util::getParam($request, 'created'); if (Util::isEmpty($created)) { - return Util::fail([], 'created' . trans('not_null')); + return $this->error('created' . trans('not_null')); } - $userId = $request->user['id']; - $created_at = $request->user['created_at']; + $userId = $request->user->uid; + //$created_at = $request->user['created_at']; + $created_at = User::find($userId)->created_at; $day = ceil((time() - $created_at + 1) / 60 / 60 / 24); $where[] = ['user_id', '=', $userId]; + $where[] = ['corp_abbr', '=', $request->basic_data['corp_abbr']]; $start = strtotime($created . '-01'); $year = date('Y', $start); $month = date('n', $start); //获取月份 @@ -366,9 +396,9 @@ class CustomerController extends BaseController 'customer_deal' => $customerDeal, //已成交 ]; if ($res) { - return Util::success($res, trans('success')); + return $this->success($res, trans('success')); } else { - return Util::fail($res, trans('fail')); + return $this->error(trans('fail')); } } @@ -380,17 +410,17 @@ class CustomerController extends BaseController public function claim(Request $request) { $customerId = Util::getParam($request, 'customer_id'); - $userId = $request->user['id']; + $userId = $request->user->uid; if (Util::isEmpty($customerId)) { - return Util::fail([], trans('customer_id').trans('not_null')); + return $this->error(trans('customer_id').trans('not_null')); } $data = [ - 'user_id' => $request->user['id'] + 'user_id' => $request->user->uid ]; $customer= Customer::withTrashed()->find($customerId); if(empty($customer) || $customer->user_id != 0){ - return Util::fail('', trans('claim_fail')); + return $this->error( trans('claim_fail')); } $customer->restore(); @@ -404,9 +434,9 @@ class CustomerController extends BaseController ]); if ($res) { - return Util::success($res, trans('success')); + return $this->success($res, trans('success')); } else { - return Util::fail($res, trans('fail')); + return $this->error(trans('fail')); } } @@ -421,14 +451,14 @@ class CustomerController extends BaseController { $customerId = Util::getParam($request, 'customer_id'); $user_sn = Util::getParam($request, 'user_sn'); - $userId = $request->user['id']; + $userId = $request->user->uid; if (Util::isEmpty($user_sn)) { - return Util::fail([], 'ID'.trans('not_null')); + return $this->error('ID'.trans('not_null')); } $user = User::where(['sn' => $user_sn])->first(); if (Util::isEmpty($user)) { - return Util::fail(null, trans('user_none')); + return $this->error( trans('user_none')); } if(Util::isEmpty($customerId)){ @@ -453,9 +483,9 @@ class CustomerController extends BaseController if ($res) { - return Util::success($res, trans('success')); + return $this->success($res, trans('success')); } else { - return Util::fail($res, trans('fail')); + return $this->error(trans('fail')); } } @@ -469,10 +499,10 @@ class CustomerController extends BaseController $id = Util::getParam($request, 'id'); $grade = Util::getParam($request, 'grade'); if (Util::isEmpty($id)) { - return Util::fail('', 'id' . trans('not_null')); + return $this->error( 'id' . trans('not_null')); } if (Util::isEmpty($id)) { - return Util::fail('', 'grade' . trans('not_null')); + return $this->error( 'grade' . trans('not_null')); } $data = [ 'grade' => $grade, @@ -481,9 +511,9 @@ class CustomerController extends BaseController ->update($data); if ($res) { - return Util::success($res, trans('save_success')); + return $this->success($res, trans('save_success')); } else { - return Util::fail($res, trans('save_fail')); + return $this->error(trans('save_fail')); } } } \ No newline at end of file diff --git a/app/crm/controller/FollowController.php b/app/crm/controller/FollowController.php index 7ee34a4..a23749c 100644 --- a/app/crm/controller/FollowController.php +++ b/app/crm/controller/FollowController.php @@ -40,7 +40,8 @@ class FollowController extends BaseController { try { $data = $this->validate(new FollowValidate(), $request->get(), 'list'); - $result = (new FollowService())->list($request->all(),$request->user->uid); + $request->setGet('corp_abbr', $request->basic_data['corp_abbr']); + $result = (new FollowService())->list($request->all(), $request->user->uid); return $this->success($result); } catch (\Throwable $e) { return $this->error($e->getMessage()); @@ -55,17 +56,17 @@ class FollowController extends BaseController public function detail(Request $request) { //跟进id - $id = Util::getParam($request,'id'); - if(Util::isEmpty($id)){ - return $this->error('id'.trans('not_null')); + $id = Util::getParam($request, 'id'); + if (Util::isEmpty($id)) { + return $this->error('id' . trans('not_null')); } - $res = Follow::select('id','user_id','customer_id','type','picture','remark','audio','audio_text','lat','lng','address') - ->where('id',$id) + $res = Follow::select('id', 'user_id', 'customer_id', 'type', 'picture', 'remark', 'audio', 'audio_text', 'lat', 'lng', 'address') + ->where('id', $id) ->first(); - if($res){ + if ($res) { $res->toArray(); - }else{ + } else { return $this->error('记录不存在'); } @@ -81,32 +82,33 @@ class FollowController extends BaseController */ public function save(Request $request) { - $customer_id = Util::getParam($request,'customer_id'); + $customer_id = Util::getParam($request, 'customer_id'); - if(Util::isEmpty($customer_id)){ - return $this->error('customer_id'.trans('not_null')); + if (Util::isEmpty($customer_id)) { + return $this->error('customer_id' . trans('not_null')); } - $type = Util::getParam($request,'type'); - if(Util::isEmpty($type)){ - return $this->error('type'.trans('not_null')); + $type = Util::getParam($request, 'type'); + if (Util::isEmpty($type)) { + return $this->error('type' . trans('not_null')); } - $picture = Util::getParam($request,'picture'); - if(Util::isEmpty($picture)){ + $picture = Util::getParam($request, 'picture'); + if (Util::isEmpty($picture)) { return $this->error(trans('picture_not_null')); } $data = [ - 'user_id'=>$request->user->uid, - 'customer_id'=>$customer_id, - 'type'=>$type, - 'picture'=>$picture, - 'remark'=>Util::getParam($request,'remark',''), - 'audio'=>Util::getParam($request,'audio',''), - 'audio_text'=>Util::getParam($request,'audio_text',''), - 'lat'=>Util::getParam($request,'lat',0), - 'lng'=>Util::getParam($request,'lng',0), - 'address'=>Util::getParam($request,'address'), - 'follow_time'=>strtotime(Util::getParam($request,'firstFollowtime',0)), + 'user_id' => $request->user->uid, + 'corp_abbr' => $request->basic_data['corp_abbr'], + 'customer_id' => $customer_id, + 'type' => $type, + 'picture' => $picture, + 'remark' => Util::getParam($request, 'remark', ''), + 'audio' => Util::getParam($request, 'audio', ''), + 'audio_text' => Util::getParam($request, 'audio_text', ''), + 'lat' => Util::getParam($request, 'lat', 0), + 'lng' => Util::getParam($request, 'lng', 0), + 'address' => Util::getParam($request, 'address'), + 'follow_time' => strtotime(Util::getParam($request, 'firstFollowtime', 0)), ]; $res = Follow::create($data); @@ -119,7 +121,7 @@ class FollowController extends BaseController $follow_next = Util::getParam($request, 'follow_next', 0); $follow_remark = Util::getParam($request, 'follow_remark', 0); - if($res && (!empty($follow_next))){ + if ($res && (!empty($follow_next))) { $data = [ 'follow_next' => $follow_next, 'follow_remark' => $follow_remark, @@ -130,7 +132,7 @@ class FollowController extends BaseController } if ($res) { - return $this->success($res,trans('save_success')); + return $this->success($res, trans('save_success')); } else { return $this->error(trans('save_fail')); } diff --git a/app/crm/logic/CustomerLogic.php b/app/crm/logic/CustomerLogic.php index 0e6b1a0..4e0619d 100644 --- a/app/crm/logic/CustomerLogic.php +++ b/app/crm/logic/CustomerLogic.php @@ -2,7 +2,14 @@ namespace app\crm\logic; +use app\crm\model\Customer; + class CustomerLogic { + public function find(int $id) + { + $customer = Customer::find($id); + return $customer; + } } \ No newline at end of file diff --git a/app/crm/model/Channel.php b/app/crm/model/Channel.php index 59f9237..ac02c71 100644 --- a/app/crm/model/Channel.php +++ b/app/crm/model/Channel.php @@ -11,7 +11,7 @@ class Channel extends Model * * @var string */ - protected $table = 'channel'; + protected $table = 'inquiry_channel'; /** * The primary key associated with the table. @@ -42,7 +42,7 @@ class Channel extends Model public static function getAll() { - $list = self::get()->select('id','name','name_en','status')->where('status',0)->toArray(); + $list = self::get()->select('id','name','name_en','status')->where('status',1)->toArray(); return $list; } } \ No newline at end of file diff --git a/app/crm/model/Country.php b/app/crm/model/Country.php index 29ba895..f1fffd1 100644 --- a/app/crm/model/Country.php +++ b/app/crm/model/Country.php @@ -35,7 +35,7 @@ class Country extends Model public static function getAll() { - $list = self::get()->select('id','cn_addr','en_addr')->get()->toArray(); + $list = self::select('id','cn_addr','en_addr')->get(); return $list; } } \ No newline at end of file diff --git a/app/crm/model/Customer.php b/app/crm/model/Customer.php index 6c17787..f28fb11 100644 --- a/app/crm/model/Customer.php +++ b/app/crm/model/Customer.php @@ -95,7 +95,8 @@ class Customer extends Model // $customer['updated_at'] = Util::timeTotDate($customer['updated_at']); $customer = Util::formatDate($customer,['follow_last']); - $nameLang = $language=='en'?'name_en':($language=='ru'?'name_ru':'name'); +// $nameLang = $language=='en'?'name_en':($language=='ru'?'name_ru':'name'); + $nameLang = '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); diff --git a/app/crm/service/CustomerService.php b/app/crm/service/CustomerService.php index 74baab2..f085f44 100644 --- a/app/crm/service/CustomerService.php +++ b/app/crm/service/CustomerService.php @@ -2,6 +2,7 @@ namespace app\crm\service; +use app\crm\logic\CustomerLogic; use app\crm\model\Customer; class CustomerService @@ -25,4 +26,15 @@ class CustomerService // } return $user; } + + + public function detail($params) + { + $id =$params['id']; + $customer = 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(); + + return $customer; + } } \ No newline at end of file diff --git a/app/crm/service/FollowService.php b/app/crm/service/FollowService.php index 89b7c2b..b97d5f1 100644 --- a/app/crm/service/FollowService.php +++ b/app/crm/service/FollowService.php @@ -18,16 +18,18 @@ class FollowService // $perPage = $request->input('per_page', 10); //客户id - $customer_id =$param['customer_id']; + $customer_id = $param['customer_id']; + $corp_abbr = $param['corp_abbr']; $where = []; $where['customer_id'] = $customer_id; + $where['corp_abbr'] = $corp_abbr; //用户角色 //跟进id - $id = $param['id']??null; - if(!Util::isEmpty($id)){ + $id = $param['id'] ?? null; + if (!Util::isEmpty($id)) { $where['id'] = $id; } @@ -39,7 +41,7 @@ class FollowService // $host = $request->host(); // $url = 'http:'.$request->url(); - foreach ($data as &$value){ + foreach ($data as &$value) { $value = self::getFollow($value); } @@ -47,15 +49,14 @@ class FollowService } - - public static function getFollow($follow,$domain = 'https://vehicle-album.oss-cn-beijing.aliyuncs.com') + public static function getFollow($follow) { $follow['type_txt'] = Constants::FOLLOW[$follow['type']]; $follow['firstFollowtime'] = $follow['follow_time']; $oss_picture = ''; - if(!empty($follow['picture'])){ + if (!empty($follow['picture'])) { $ossservice = new OssService(); - $oss_picture = $ossservice->generatePrivateUrl($follow['picture'],86400); + $oss_picture = $ossservice->generatePrivateUrl($follow['picture'], 86400); } $follow['oss_picture'] = $oss_picture; // $follow = Util::formatDate($follow); diff --git a/config/route.php b/config/route.php index 4c29ced..dd98cca 100644 --- a/config/route.php +++ b/config/route.php @@ -91,5 +91,10 @@ Route::group('/crm', function () { Route::any('/customer/list', [app\crm\controller\CustomerController::class, 'list']); Route::any('/customer/detail', [app\crm\controller\CustomerController::class, 'detail']); Route::any('/customer/add', [app\crm\controller\CustomerController::class, 'save']); + Route::any('/customer/claim', [app\crm\controller\CustomerController::class, 'claim']); + Route::any('/customer/restore', [app\crm\controller\CustomerController::class, 'restore']); + Route::any('/customer/delete', [app\crm\controller\CustomerController::class, 'delete']); + Route::any('/customer/waitFollow', [app\crm\controller\CustomerController::class, 'waitFollow']); + Route::any('/customer/getChannel', [app\crm\controller\CustomerController::class, 'getChannel']); });