diff --git a/1.sql b/1.sql new file mode 100644 index 0000000..ea1e67c --- /dev/null +++ b/1.sql @@ -0,0 +1,3 @@ +User ← user_roles → Role ← role_resources → Resource (type=menu/button) + ↘︎ + role_permissions → Permission \ No newline at end of file diff --git a/app/common/controller/PresetController.php b/app/common/controller/PresetController.php deleted file mode 100644 index 964b2a6..0000000 --- a/app/common/controller/PresetController.php +++ /dev/null @@ -1,36 +0,0 @@ -getList(); - return $this->success($result, '获取公司列表'); - } catch (\Throwable $e) { - return $this->error($e->getMessage()); - } - } - - - - public function feishuApp(Request $request) - { - try { - $corpId = $request->get('corp_id'); - $result = (new CorpFeishuAppService())->getFeishuApp($corpId); - return $this->success($result, '获取飞书应用信息'); - } catch (\Throwable $e) { - return $this->error($e->getMessage()); - } - } -} \ No newline at end of file diff --git a/app/common/logic/BaseLogic.php b/app/common/logic/BaseLogic.php deleted file mode 100644 index 94beff3..0000000 --- a/app/common/logic/BaseLogic.php +++ /dev/null @@ -1,86 +0,0 @@ -paginate($params['per_page'], ['*'], 'page', $params['page']); - } - - return $query->get(); - } - - /** - * 获取单个记录 - */ - public function getDetail(int $id, string $modelClass) - { - $record = $modelClass::find($id); - if (!$record) { - throw new BusinessException("记录不存在", 404); - } - - return $record; - } - - /** - * 创建记录 - */ - public function create(array $data, string $modelClass) - { - $model = new $modelClass; - $model->fill($data); // 根据字段填充数据 - try { - $model->save(); - } catch (\Throwable $e) { - throw new BusinessException("创建记录失败: " . $e->getMessage(), 500); - } - - return $model; - } - - /** - * 更新记录 - */ - public function update(array $data, string $modelClass) - { - $record = $modelClass::find($data['id']); - if (!$record) { - throw new BusinessException("记录不存在", 404); - } - - $record->update($data); - return $record; - } - - /** - * 删除记录 - */ - public function delete(int $id, string $modelClass) - { - $record = $modelClass::find($id); - if (!$record) { - throw new BusinessException("记录不存在", 404); - } - - try { - $record->delete(); - } catch (\Throwable $e) { - throw new BusinessException("删除记录失败: " . $e->getMessage(), 500); - } - - return true; - } -} diff --git a/app/common/logic/CorpFeishuAppLogic.php b/app/common/logic/CorpFeishuAppLogic.php deleted file mode 100644 index 2073aac..0000000 --- a/app/common/logic/CorpFeishuAppLogic.php +++ /dev/null @@ -1,16 +0,0 @@ -first(['id', 'corp_id', 'name', 'app_id', 'r_url', 'state']); - } - -} \ No newline at end of file diff --git a/app/common/logic/CorpLogic.php b/app/common/logic/CorpLogic.php deleted file mode 100644 index cac9672..0000000 --- a/app/common/logic/CorpLogic.php +++ /dev/null @@ -1,14 +0,0 @@ -orderBy('sort', 'asc')->get(['id', 'name', 'abbr', 'tenant_key']); - } -} \ No newline at end of file diff --git a/app/common/model/Role.php b/app/common/model/Role.php index c9eaabd..ea84200 100644 --- a/app/common/model/Role.php +++ b/app/common/model/Role.php @@ -53,6 +53,6 @@ class Role extends Model // 角色拥有的资源(权限点、菜单) public function resources() { - return $this->belongsToMany(Resource::class, 'role_resources', 'role_id', 'resource_id')->orderBy('sort', 'asc'); + return $this->belongsToMany(Resource::class, 'role_resources', 'role_id', 'resource_id'); } } diff --git a/app/common/model/UserFeishuApp_bak.php b/app/common/model/UserFeishuApp_bak.php deleted file mode 100644 index 9aa06c0..0000000 --- a/app/common/model/UserFeishuApp_bak.php +++ /dev/null @@ -1,69 +0,0 @@ - $logic->feishuLogin($data), - // 'qrcode' => $logic->qrCodeLogin($data), + 'qrcode' => $logic->qrCodeLogin($data), default => $logic->uPwdLogin($data), }; } @@ -86,13 +86,4 @@ class AuthService { (new AuthLogic())->blockToken($token, $systemCode); } - - - // public function perms() - // { - // $permService = new PermService(); - // $menuTree = $permService->getMenuTree($uid); - // $permissionCodes = $permService->getPermissionCodes($uid); - // return (new PermService())->getMenuTree($this->userId) - // } } \ No newline at end of file diff --git a/app/common/service/CorpFeishuAppService.php b/app/common/service/CorpFeishuAppService.php deleted file mode 100644 index 0c10be8..0000000 --- a/app/common/service/CorpFeishuAppService.php +++ /dev/null @@ -1,21 +0,0 @@ -logic = (new CorpFeishuAppLogic()); - } - - public function getFeishuApp(int $corpId) - { - return $this->logic->getFeishuApp($corpId); - } -} \ No newline at end of file diff --git a/app/common/service/CorpService.php b/app/common/service/CorpService.php deleted file mode 100644 index 7d18d49..0000000 --- a/app/common/service/CorpService.php +++ /dev/null @@ -1,24 +0,0 @@ -logic = (new CorpLogic()); - } - - /** - * 获取公司list - */ - public function getList() - { - return $this->logic->getList(); - } -} \ No newline at end of file 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..5fc0750 --- /dev/null +++ b/app/crm/controller/CustomerController.php @@ -0,0 +1,519 @@ + $value) { + $grade[] = [ + 'id' => $key, + 'name' => $value, + ]; + } + return $this->success($grade); + } + + /** + * 商机 + * @param Request $request + * @return \support\Response + */ + public function getMagnitude(Request $request) + { + $grade = []; + $magnitudeConstants = Constants::MAGNITUDE_EN; + if('zh_CN' == 'zh_CN'){ + $magnitudeConstants = Constants::MAGNITUDE; + }elseif ('zh_CN' == 'ru'){ + $magnitudeConstants = Constants::MAGNITUDE_RU; + } + foreach ($magnitudeConstants as $key => $value) { + $grade[] = [ + 'id' => $key, + 'name' => $value, + ]; + } + return $this->success($grade); + } + + /** + * 客户渠道 + * @param Request $request + * @return \support\Response + */ + public function getChannel(Request $request) + { + $list = Channel::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); + + } + + /** + * 国家 + * @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); + + } + + /** + * 待跟进客户列表 + * @param Request $request + * @return \support\Response + */ + public function waitFollow(Request $request) + { + $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], + ]; + + 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 $this->success($this->page($customer)); + } + + /** + * 客户列表 + * @param Request $request + * @return \support\Response + */ + public function list(Request $request) + { + 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)); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } + + /** + * 客户恢复 + * @param Request $request + * @return \support\Response + */ + public function restore(Request $request) + { + $id = Util::getParam($request,'id', ''); + if (Util::isEmpty($id)) { + return $this->error(trans('id_empty')); + } + $userId = $request->user->uid; + $where = [ + 'id' => $id, + 'user_id' => $userId, + ]; + $res = Customer::where($where)->restore(); + if($res){ + return $this->success($res, trans('success')); + }else{ + return $this->error(trans('fail')); + } + } + + + /** + * 客户详情 + * @param Request $request + * @return \support\Response + */ + public function detail(Request $request) + { + $id = Util::getParam($request, 'id'); + if (Util::isEmpty($id)) { + 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 = (new CustomerService)->detail($request->all()); + if ($res) { + $res->toArray(); + } else { + return $this->error('记录不存在'); + } + + $res = Customer::getCustomer($res, $request, true); + + return $this->success($res); + } + + /** + * 客户录入 + * @param Request $request + * @return \support\Response + */ + public function save(Request $request) + { + $id = Util::getParam($request, 'id'); + $channel_id = Util::getParam($request, 'channel_id'); + if (Util::isEmpty($channel_id)) { + return $this->error(trans('channel_not_null')); + } + $country_id = Util::getParam($request, 'country_id', 0); + if (Util::isEmpty($country_id)) { +// return $this->error('country_id'.trans('not_null')); + } + $car_type_id = Util::getParam($request, 'car_type_id'); + if (Util::isEmpty($car_type_id)) { + 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 $this->error(trans('contacts_not_null')); + } + + $data = [ + '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, + 'car_type_id' => $car_type_id, + 'magnitude' => Util::getParam($request, 'magnitude', 0), + 'email' => $email, + 'phone' => $phone, + 'WhatsApp' => Util::getParam($request, 'WhatsApp', ''), + 'contacts' => $contacts, + 'describe' => Util::getParam($request, 'describe'), + 'lat' => Util::getParam($request, 'lat', 0), + 'lng' => Util::getParam($request, 'lng', 0), + 'address' => Util::getParam($request, 'address', ''), + 'sex' => Util::getParam($request, 'sex', 0), + ]; + + if (Util::isEmpty($id)) { + $res = Customer::create($data); + } else { + unset($data['grade']); + $res = Customer::where('id', $id) + ->update($data); +// Log::info('update', ['res' => $res]); + (!$res) ?: $res = Customer::find($id)->toArray(); + } + + if ($res) { + return $this->success($res, trans('save_success')); + } else { + return $this->error(trans('save_fail')); + } + } + + + + /** + * 更新下次跟进时间 + * @param Request $request + * @return \support\Response + */ + public function followNext(Request $request) + { + $id = Util::getParam($request, 'id'); + if (Util::isEmpty($id)) { + return $this->error('id' . trans('not_null')); + } + $data = [ + 'follow_next' => Util::getParam($request, 'follow_next', 0), + 'follow_remark' => Util::getParam($request, 'follow_remark', 0), + 'warn' => 0, + ]; + + $res = Customer::where('id', $id) + ->update($data); + + if ($res) { + return $this->success($res, trans('save_success')); + } else { + return $this->error(trans('save_fail')); + } + } + + /** + * 删除客户 + * @param Request $request + * @return \support\Response + */ + public function delete(Request $request) + { + $id = Util::getParam($request, 'id'); + $force = Util::getParam($request, 'force',''); + + $userId = $request->user->uid; + $where = [ + 'id' => $id, + 'user_id' => $userId, + ]; + $customer = Customer::where($where)->withTrashed()->first(); + if(empty($customer)){ + return $this->error( trans('fail')); + } + if($force == 'force'){ + $res = $customer->forceDelete(); + }else{ + $res = $customer->delete(); + } + if ($res) { + return $this->success($res, trans('success')); + } else { + return $this->error(trans('fail')); + } + } + + /** + * 统计客户 + * @param Request $request + * @return \support\Response + */ + public function statistics(Request $request) + { + $created = Util::getParam($request, 'created'); + if (Util::isEmpty($created)) { + return $this->error('created' . trans('not_null')); + } + $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); //获取月份 + $end = mktime(00, 00, 00, $month + 1, 1, $year); + $where[] = ['created_at', '>=', $start]; + $where[] = ['created_at', '<', $end]; + $customer = Customer::where($where)->count(); + + //初步接触 + $whereGrade = $where; + $whereGrade[] = ['grade', '<=', 2]; + $customerInit = Customer::where($whereGrade)->count(); + + //跟进中 + $customeroFllow = Customer::where($where)->whereIn('grade', [3, 4])->count(); + + //已成交 + $whereGrade = $where; + $whereGrade[] = ['grade', '=', 5]; + $customerDeal = Customer::where($whereGrade)->count(); + + //拜访数 + $whereVisit = $where; + $whereVisit[] = ['type', '=', 0]; + $visit = Follow::where($whereVisit)->distinct('customer_id')->count(); + + //跟进数 + $whereVisit = $where; + $whereVisit[] = ['type', '=', 1]; + $follow = Follow::where($whereVisit)->distinct('customer_id')->count(); + + $res = [ + 'customer' => $customer, //客户数 + 'visit' => $visit, //拜访 + 'follow' => $follow, //跟进 + 'day' => $day, //注册天数 + 'customer_init' => $customerInit, //初步接触 + 'customero_fllow' => $customeroFllow, //跟进中 + 'customer_deal' => $customerDeal, //已成交 + ]; + if ($res) { + return $this->success($res, trans('success')); + } else { + return $this->error(trans('fail')); + } + } + + /** + * 领取公海客户 + * @param Request $request + * @return \support\Response + */ + public function claim(Request $request) + { + $customerId = Util::getParam($request, 'customer_id'); + $userId = $request->user->uid; + if (Util::isEmpty($customerId)) { + return $this->error(trans('customer_id').trans('not_null')); + } + $data = [ + 'user_id' => $request->user->uid + ]; + $customer= Customer::withTrashed()->find($customerId); + + if(empty($customer) || $customer->user_id != 0){ + return $this->error( trans('claim_fail')); + } + + $customer->restore(); + $res = $customer->update($data); + + //记录客户关系变化 + $his = CustomerHis::create([ + 'customer_id' => $customerId, + 'user_his' => 0, + 'user_id' => $userId, + ]); + + if ($res) { + return $this->success($res, trans('success')); + } else { + return $this->error(trans('fail')); + } + } + + + + /** + * 批量转让 + * @param Request $request + * @return \support\Response + */ + public function cede(Request $request) + { + $customerId = Util::getParam($request, 'customer_id'); + $user_sn = Util::getParam($request, 'user_sn'); + $userId = $request->user->uid; + if (Util::isEmpty($user_sn)) { + return $this->error('ID'.trans('not_null')); + } + + $user = User::where(['sn' => $user_sn])->first(); + if (Util::isEmpty($user)) { + return $this->error( trans('user_none')); + } + + if(Util::isEmpty($customerId)){ + $data = [ + 'user_id' => $userId + ]; + $query= Customer::where($data); + }else{ + $query= Customer::whereIn('id',explode(',',$customerId)); + } + $customer = $query->get(); + + foreach ($customer as $item) { + //记录客户关系变化 + $his = CustomerHis::create([ + 'customer_id' => $item->id, + 'user_his' => $item->user_id, + 'user_id' => $user['id'], + ]); + } + $res = $query->update(['user_id' => $user->id]); + + + if ($res) { + return $this->success($res, trans('success')); + } else { + return $this->error(trans('fail')); + } + } + + /** + * 跟进状态 + * @param Request $request + * @return \support\Response + */ + public function grade(Request $request) + { + $id = Util::getParam($request, 'id'); + $grade = Util::getParam($request, 'grade'); + if (Util::isEmpty($id)) { + return $this->error( 'id' . trans('not_null')); + } + if (Util::isEmpty($id)) { + return $this->error( 'grade' . trans('not_null')); + } + $data = [ + 'grade' => $grade, + ]; + $res = Customer::where('id', $id) + ->update($data); + + 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/FollowController.php b/app/crm/controller/FollowController.php new file mode 100644 index 0000000..a23749c --- /dev/null +++ b/app/crm/controller/FollowController.php @@ -0,0 +1,141 @@ + $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(), 'list'); + $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()); + } + } + + /** + * 跟进详情 + * @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 = FollowService::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->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); + + $customer = Customer::find($customer_id); + $customer->follow_last = strtotime($res->created_at); + $customer->follow_next = null; + $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 { + 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..4e0619d --- /dev/null +++ b/app/crm/logic/CustomerLogic.php @@ -0,0 +1,15 @@ +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..ac02c71 --- /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',1)->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..f1fffd1 --- /dev/null +++ b/app/crm/model/Country.php @@ -0,0 +1,41 @@ +get(); + 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..f28fb11 --- /dev/null +++ b/app/crm/model/Customer.php @@ -0,0 +1,137 @@ + '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 = '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']]); + + 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'); + $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); + $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, 'crm_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..65d7de6 --- /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..3a0c567 --- /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', // 指定序列化格式 + ]; +} \ 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..e58bb87 --- /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, 'crm_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..5b5e28e --- /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..f085f44 --- /dev/null +++ b/app/crm/service/CustomerService.php @@ -0,0 +1,40 @@ +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::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; + } + + + 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 new file mode 100644 index 0000000..b97d5f1 --- /dev/null +++ b/app/crm/service/FollowService.php @@ -0,0 +1,65 @@ +input('page', 1); +// $perPage = $request->input('per_page', 10); + + //客户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)) { + $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 = self::getFollow($value); + } + + return $data; + } + + + public static function getFollow($follow) + { + $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/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..a92c4a0 --- /dev/null +++ b/app/crm/validate/FollowValidate.php @@ -0,0 +1,21 @@ + 'require', + ]; + + protected $message = [ + 'customer_id.require' => '用户id不能为空', + ]; + + protected $scene = [ + '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 diff --git a/config/route.php b/config/route.php index d970528..8ff4261 100644 --- a/config/route.php +++ b/config/route.php @@ -25,8 +25,6 @@ use Webman\Route; // POST /admin/user/{user_id}/kickout // body: {"tokens": ["..."]} // 踢下线 // POST /admin/user/{user_id}/kickout_all // 一键踢全部 -// 调试 -Route::any('/perm', [app\controller\IndexController::class, 'perm']); Route::group('/common', function () { Route::group('/auth', function () { @@ -66,7 +64,10 @@ Route::group('/ticket', function () { Route::any('/ticket/add', [app\ticket\controller\TicketController::class, 'add']); Route::any('/ticket/edit', [app\ticket\controller\TicketController::class, 'edit']); Route::any('/ticket/list', [app\ticket\controller\TicketController::class, 'index']); +<<<<<<< HEAD Route::any('/ticket/self', [app\ticket\controller\TicketController::class, 'self']); +======= +>>>>>>> feature/crmAdmin0715 Route::any('/ticket/status', [app\ticket\controller\TicketController::class, 'status']); Route::any('/ticket/getStatus', [app\ticket\controller\TicketController::class, 'getStatus']); @@ -87,3 +88,22 @@ 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('/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']); +}); + 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