131 Commits

Author SHA1 Message Date
18338781771 69ae53f545 客户线索重复检查 2025-08-29 18:49:42 +08:00
18338781771 1500e39bb0 获取客户时间 2025-08-25 15:05:49 +08:00
18338781771 a2b01ad9a1 头像处理 2025-07-31 15:55:33 +08:00
18338781771 7052f8128a 公海数据隔离 2025-07-31 09:41:42 +08:00
18338781771 e78a1189ad 1 2025-07-30 18:23:14 +08:00
18338781771 c8fdbd5773 修改密码 2025-07-30 18:20:41 +08:00
18338781771 4e3616e973 重置密码 2025-07-30 18:13:24 +08:00
18338781771 e4aebe8ca7 商机 2025-07-29 09:34:13 +08:00
18338781771 aac0d4be6a 1 2025-07-28 18:04:33 +08:00
18338781771 601c299c2b 1 2025-07-28 18:00:52 +08:00
18338781771 4ef9784559 oss配置 2025-07-28 16:35:35 +08:00
18338781771 4080bfca42 脱敏优化 2025-07-25 16:59:26 +08:00
18338781771 8ef4abded4 1 2025-07-25 16:38:53 +08:00
18338781771 a43cdd9ba1 1 2025-07-25 15:49:41 +08:00
18338781771 e84be2be04 公海数据脱敏 2025-07-25 15:31:30 +08:00
18338781771 494e66488a 登录注册 2025-07-24 17:26:30 +08:00
18338781771 99d5c0c81d 1 2025-07-24 16:40:15 +08:00
18338781771 060c1a89c1 客户转让 2025-07-24 15:49:04 +08:00
18338781771 1c1b1dab23 客户转让 2025-07-24 15:41:25 +08:00
18338781771 c04f60c7e4 1 2025-07-24 15:07:11 +08:00
18338781771 20b394de65 渠道 2025-07-24 15:04:47 +08:00
18338781771 ea88566112 渠道 2025-07-24 15:03:30 +08:00
18338781771 a327b56d1b 获取用户 2025-07-24 14:57:35 +08:00
18338781771 ed479e026f 国家筛选 2025-07-24 13:42:17 +08:00
18338781771 ef66ecbbef 使用fdesk库 2025-07-23 16:55:18 +08:00
18338781771 fa4ade4b35 版权信息修改 2025-07-21 09:45:07 +08:00
18338781771 1ccaced113 1 2025-07-16 13:58:51 +08:00
18338781771 bfd458aeb7 1 2025-07-16 10:35:07 +08:00
18338781771 d42167bf14 1 2025-07-11 14:04:16 +08:00
18338781771 7711b76ac3 1 2025-06-24 13:43:45 +08:00
18338781771 c9674a6ad9 1 2025-06-23 14:06:39 +08:00
18338781771 7ab9151e4a 1 2025-06-23 13:46:11 +08:00
18338781771 a8041c4785 1 2025-06-23 13:44:55 +08:00
18338781771 f9175f7dd4 1 2025-04-09 10:56:49 +08:00
18338781771 b2b96dd1bd 1 2025-04-09 10:44:42 +08:00
18338781771 3a5c8b4304 1 2025-04-09 10:43:53 +08:00
18338781771 85009b64ef 1 2025-04-09 10:42:00 +08:00
18338781771 541fbd8557 Merge branch 'feature/ru' into develop
# Conflicts:
#	app/controller/UserController.php
#	config/constants/Constants.php
2025-04-07 14:20:08 +08:00
18338781771 698448dcc6 语言类型 2025-04-07 14:18:06 +08:00
18338781771 012cc4d5aa Merge branch 'feature/ru' into develop 2025-04-07 13:13:08 +08:00
18338781771 25aed90f46 ru 2025-04-07 13:12:56 +08:00
18338781771 6baf3dd44f Merge branch 'feature/ru' into develop
# Conflicts:
#	config/constants/Constants.php
2025-04-07 11:54:29 +08:00
18338781771 6247d8cf4d ru 2025-04-07 11:52:11 +08:00
18338781771 40fff988ce no message 2025-04-07 10:59:35 +08:00
18338781771 facbae2a95 fix 2025-04-03 16:35:08 +08:00
18338781771 833d82c19a 客户 2025-04-02 17:48:45 +08:00
18338781771 aa1d458467 图片 2025-04-02 17:35:45 +08:00
18338781771 a2d10d1a1c img 2025-04-02 17:28:12 +08:00
18338781771 de7dcdf011 俄文 2025-04-02 17:04:02 +08:00
18338781771 7595e24cef 用户 2025-04-02 15:39:47 +08:00
18338781771 522183cb71 接入公共服务 2025-04-02 15:17:13 +08:00
18338781771 8bb0826b06 Merge branch 'hotfix/collect' into develop 2025-04-02 09:06:41 +08:00
18338781771 fa54dcca48 询盘推送 2025-04-02 09:06:24 +08:00
18338781771 7b5be3e732 Merge branch 'master' into develop 2025-04-01 17:34:07 +08:00
18338781771 c0ff3916ee Merge branch 'hotfix/collect' 2025-04-01 17:33:53 +08:00
18338781771 ba5c874c74 数据编码 2025-04-01 17:32:08 +08:00
18338781771 4934e4482c Merge branch 'master' into develop 2025-04-01 16:20:41 +08:00
18338781771 b9b3f49964 Merge branch 'hotfix/collect' 2025-04-01 16:20:30 +08:00
18338781771 4e0e8cf264 日志 2025-04-01 16:20:22 +08:00
18338781771 76466db0fb ru 2025-04-01 16:09:47 +08:00
18338781771 bc270c8c24 Merge branch 'feature/tagCustomer' into develop 2025-04-01 15:20:32 +08:00
18338781771 4aaf782633 领取客户 2025-04-01 15:20:23 +08:00
18338781771 77e38a2883 Merge branch 'feature/tagCustomer' into develop 2025-04-01 15:09:05 +08:00
18338781771 47a7aa345a 标签关联 2025-04-01 15:08:52 +08:00
18338781771 0011443a04 1 2025-04-01 14:41:55 +08:00
18338781771 5b297966e5 Merge branch 'feature/tagCustomer' into develop 2025-04-01 13:50:55 +08:00
18338781771 eed1968f92 no message 2025-04-01 13:50:46 +08:00
18338781771 c79bb1f8af Merge branch 'master' into develop 2025-04-01 11:31:03 +08:00
18338781771 bbe494400f log 2025-04-01 11:30:47 +08:00
18338781771 3d68efed14 Merge branch 'master' into develop
# Conflicts:
#	app/controller/CustomerController.php
2025-04-01 11:15:10 +08:00
18338781771 64d294f3c8 客户类型 2025-04-01 11:13:53 +08:00
18338781771 2cf5eacfe7 Merge branch 'master' into develop 2025-04-01 11:10:43 +08:00
18338781771 a005d98532 询盘对接 2025-04-01 11:10:11 +08:00
18338781771 c1fb19dbf7 Merge branch 'master' into feature/tagCustomer 2025-03-31 14:26:04 +08:00
18338781771 4cde16f76a 公海,转让,名片 2025-03-31 14:25:38 +08:00
18338781771 d9f6ee8ea2 文本 2025-03-28 13:32:04 +08:00
18338781771 ee51bc3899 Merge branch 'test' 2025-03-28 13:18:26 +08:00
18338781771 8b19071d1c Merge branch 'feature/tag' into develop 2025-03-27 15:39:36 +08:00
18338781771 a9e83695ae 标签列表修复 2025-03-27 15:39:26 +08:00
18338781771 aae930a16e 进程数调整 2025-03-27 14:37:07 +08:00
18338781771 7f6bf16440 Merge branch 'feature/en' into develop 2025-03-27 14:27:21 +08:00
18338781771 1e890f8f06 获取客户详情语言处理 2025-03-27 14:27:06 +08:00
18338781771 fa27b28ca8 Merge branch 'feature/tag' into feature/en 2025-03-27 14:06:25 +08:00
18338781771 2ce58106f7 Merge branch 'feature/tag' into develop 2025-03-27 14:05:23 +08:00
18338781771 80a7541d0c 标签处理 2025-03-27 14:05:14 +08:00
18338781771 4d28cd88ca Merge branch 'feature/tag' into develop 2025-03-27 13:34:24 +08:00
18338781771 16a7ea2976 语言 2025-03-27 13:34:10 +08:00
18338781771 a908619084 Merge branch 'feature/tag' into develop 2025-03-27 11:14:01 +08:00
18338781771 aff152e40d 标签关系 2025-03-27 11:13:46 +08:00
18338781771 eeca83c3df Merge branch 'master' into develop 2025-03-27 10:28:51 +08:00
18338781771 9a68f72826 oss 2025-03-27 10:27:39 +08:00
18338781771 6e79dd47c4 标签 2025-03-26 17:13:11 +08:00
18338781771 9f3bfacc2f Merge branch 'master' into develop 2025-03-26 14:11:31 +08:00
18338781771 90ec9a7ad8 图片目录调整 2025-03-26 14:07:29 +08:00
18338781771 af3398fa70 Merge branch 'feature/login' into develop 2025-03-26 13:41:37 +08:00
18338781771 1a263900e8 Merge branch 'feature/recycle' into develop 2025-03-26 11:49:45 +08:00
18338781771 aaf8981369 Merge branch 'feature/follow' into develop 2025-03-26 11:48:57 +08:00
18338781771 1a947df500 Merge branch 'feature/collect' into develop 2025-03-26 11:48:49 +08:00
ylyg5690 4742b37391 客户线索分配 2025-03-26 11:47:09 +08:00
ylyg5690 a643694bfa Finish Hotfix-1调整默认头像 2025-03-26 09:57:25 +08:00
ylyg5690 1833eb012d Merge branch 'master' into develop 2025-03-26 09:57:25 +08:00
ylyg5690 d511b2fdb5 调整默认头像 2025-03-26 09:56:52 +08:00
18338781771 8cbf82fb2d 筛选跟进列表 2025-03-26 09:50:10 +08:00
18338781771 23ffdab0f6 下次跟进时间格式 2025-03-25 14:25:16 +08:00
18338781771 d5c9d1a7a5 通知状态 2025-03-25 13:45:35 +08:00
18338781771 68eb23e316 待跟进列表 2025-03-25 13:42:24 +08:00
18338781771 cef8472965 客户回收站 2025-03-25 10:26:17 +08:00
18338781771 fc1825a1c7 登录优化 2025-03-25 09:10:31 +08:00
18338781771 6184f69ddd 英文下拉 2025-03-25 09:06:08 +08:00
18338781771 06f2531ec0 oss目录 2025-03-25 09:03:38 +08:00
18338781771 fc6e7c2063 1 2025-03-24 15:24:51 +08:00
18338781771 1773ab9863 sn 2025-03-24 15:22:13 +08:00
18338781771 d14945e546 1 2025-03-24 14:48:29 +08:00
18338781771 8cee9fa81b 邮箱 2025-03-24 14:32:16 +08:00
18338781771 d8d790f96e 客户回收 2025-03-24 13:57:06 +08:00
18338781771 b7775cafcf 提示校验优化 2025-03-24 11:09:59 +08:00
18338781771 b9f5e671bc 邮箱配置 2025-03-24 10:30:32 +08:00
mzl92 a1f20d4877 修改部分问题 2025-03-23 01:12:59 +08:00
18338781771 656733c00a 飞书消息 2025-03-22 20:09:17 +08:00
18338781771 b6409a69ed 飞书消息 2025-03-22 20:08:01 +08:00
18338781771 97250ca23e 1 2025-03-22 18:45:39 +08:00
18338781771 3fd7183b70 1 2025-03-22 18:41:50 +08:00
18338781771 625b5123bb 1 2025-03-22 18:36:09 +08:00
18338781771 504bf7885c 修复 2025-03-22 18:30:38 +08:00
18338781771 e58ed1ee14 图片路径 2025-03-22 17:44:42 +08:00
18338781771 b6d2e285d2 图片 2025-03-22 17:34:21 +08:00
18338781771 3c313b4f34 暂时不登录 2025-03-22 17:16:19 +08:00
18338781771 c0c5138ac8 文件上传 2025-03-22 16:20:12 +08:00
18338781771 e2e506a91f 用户信息 2025-03-22 15:41:25 +08:00
18338781771 6e1eb75bb1 邮箱 2025-03-22 15:35:57 +08:00
18338781771 eae3e9c09f 上传 2025-03-22 15:31:54 +08:00
46 changed files with 3308 additions and 1685 deletions
+4 -1
View File
@@ -16,4 +16,7 @@ JWT_SECRET_KEY = 'Hj3$kLm8NpQrStUvXwZ1y2C4D6E8G'
JWT_ALGORITHM = 'HS256'
JWT_EXPIRATION = 2592000
WEBMAN_LISTEN = 'http://0.0.0.0:9007'
WEBMAN_LISTEN = 'http://0.0.0.0:9007'
WEBMAN_COUNT = 8
RPC_DOMAIN = http://219.157.255.213:25015
Generated
-20
View File
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/webman/." isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/webman/./app" isTestSource="false" packagePrefix="app\" />
<sourceFolder url="file://$MODULE_DIR$/webman/./app/view/components" isTestSource="false" packagePrefix="app\View\Components\" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/nikic/fast-route" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/workerman/coroutine" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/workerman/webman-framework" />
<excludeFolder url="file://$MODULE_DIR$/webman/vendor/workerman/workerman" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+25 -2
View File
@@ -4,7 +4,11 @@ namespace app\controller;
use app\model\Area;
use app\model\Country;
use app\util\HttpClient;
use app\util\RedisHelper;
use app\util\Util;
use support\Log;
use support\Redis;
use support\Request;
class AreaController
@@ -41,10 +45,29 @@ class AreaController
public function getCountry (Request $request)
{
$level = Util::getParam($request,'level')?:1;
$list = RedisHelper::get("rpc_country");
$list = null;
// if(!$list){
// $res = HttpClient::get(config('const.rpc_domain') . '/country/all');
// if ($res['code'] != 200 && $res['data']['code'] != 0){
// Log::info('register_rpc',$res);
// return Util::fail($res, trans('register_fail'));
// }
// $list = $res['data']['data']['data'];
// RedisHelper::set("rpc_country", $list, 600);
// }
$list = Country::get()->toArray();
$name = 'en_addr';
//$language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
if($language == 'zh_CN'){
$name = 'cn_addr';
}
foreach ($list as &$row) {
$row['name'] = $row['cn_addr'];
$row['name'] = $row[$name];
}
return Util::success($list);
}
+14
View File
@@ -16,6 +16,20 @@ class CarTypeController
public function getAll(Request $request)
{
$list = CarType::getAll();
//$language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
if($language == 'en'){
foreach ($list as &$value) {
$value['name'] = $value['name_en'];
}
}elseif ($language == 'ru'){
foreach ($list as &$value) {
$value['name'] = $value['name_ru'];
}
}
return Util::success($list);
}
+427 -46
View File
@@ -3,15 +3,28 @@
namespace app\controller;
use app\model\Channel;
use app\model\Corp;
use app\model\Customer;
use app\model\CustomerHis;
use app\model\Follow;
use app\model\InquiryLog;
use app\model\User;
use app\service\UserService;
use app\util\Util;
use config\constants\Constants;
use Illuminate\Database\Eloquent\Builder;
use support\Log;
use support\Request;
class CustomerController
{
/**
* 不需要登录的方法
*/
protected $noNeedLogin = ['collect'];
/**
* 客户分级
* @param Request $request
@@ -20,7 +33,17 @@ class CustomerController
public function getGrade(Request $request)
{
$grade = [];
foreach (Constants::GRADE as $key => $value) {
$gradeConstants = Constants::GRADE_EN;
//$language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
if($language == 'zh_CN'){
$gradeConstants = Constants::GRADE;
}elseif ($language == 'ru'){
$gradeConstants = Constants::GRADE_RU;
}
foreach ($gradeConstants as $key => $value) {
$grade[] = [
'id' => $key,
'name' => $value,
@@ -37,7 +60,16 @@ class CustomerController
public function getMagnitude(Request $request)
{
$grade = [];
foreach (Constants::MAGNITUDE as $key => $value) {
$magnitudeConstants = Constants::MAGNITUDE_EN;
//$language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
if($language == 'zh_CN'){
$magnitudeConstants = Constants::MAGNITUDE;
}elseif ($language == 'ru'){
$magnitudeConstants = Constants::MAGNITUDE_RU;
}
foreach ($magnitudeConstants as $key => $value) {
$grade[] = [
'id' => $key,
'name' => $value,
@@ -54,10 +86,59 @@ class CustomerController
public function getChannel(Request $request)
{
$list = Channel::getAll();
//$language = $request->user['language'];
//$language = 'zh_CN';
// $language = $request->language;
// if($language != 'zh_CN'){
// foreach ($list as &$value) {
// $value['name'] = $value['name_en'];
// }
// }elseif ($language == 'ru'){
// foreach ($list as &$value) {
// $value['name'] = $value['name_ru'];
// }
// }
return Util::success($list);
}
/**
* 待跟进客户列表
* @param Request $request
* @return \support\Response
*/
public function waitFollow(Request $request)
{
$userId = $request->user['id'];
$filter = Util::getParam($request, 'filter');
$page = $request->input('page', 1);
$perPage = $request->input('per_page', 10);
$where = [
['user_id', '=', $userId],
['follow_next', '<>', 0],
];
if($filter == 0){
$where[] = ['follow_next', '<=', time() + 3600 * 24];
}elseif($filter == 1){
$where[] = ['follow_next', '<=', time() + 3600 * 24*3];
}elseif($filter == 2){
$where[] = ['follow_next', '<=', time() + 3600 * 24*7];
}
$customer = Customer::where($where)
->whereNotNull('follow_next')
->orderBy('follow_next')
->paginate($perPage, ['*'], 'page', $page);
foreach ($customer as &$item) {
$item['follow_remaining'] = $item->follow_next-time();
$item['follow_next'] = date('Y-m-d H:i:s',$item->follow_next);
}
return Util::page($customer);
}
/**
* 客户列表
* @param Request $request
@@ -68,9 +149,12 @@ class CustomerController
$page = $request->input('page', 1);
$perPage = $request->input('per_page', 10);
$follow = $request->input('follow',''); //跟进状态
$keyword = $request->input('keyword',''); //follow_last
$follow_last = $request->input('follow_last',''); //最后跟进:1:当天跟进客户,2:近三天跟进客户,3:近七天跟进客户
$follow = $request->input('follow', ''); //跟进状态
$keyword = $request->input('keyword', ''); //follow_last
$follow_last = $request->input('follow_last', ''); //最后跟进:1:当天跟进客户,2:近三天跟进客户,3:近七天跟进客户
$tagId = $request->input('tag_id', ''); //打有某个标签的客户
$countryId = $request->input('country_id', ''); //打有某个标签的客户
$seas = $request->input('seas', ''); //公海客户
$where = [];
@@ -78,54 +162,122 @@ class CustomerController
if (Util::isEmpty($userId)) {
return Util::fail(['user_id' => $userId], trans('user_none'));
}
$where[] =['user_id',$userId] ;
// $where[] = ['type', 0];
if($seas == 'seas'){
$where[] = ['user_id', 0];
}else{
$where[] = ['user_id', $userId];
}
$where[] = ['status', 1];
if (!empty($countryId)){
$where[] = ['country_id', $countryId];
}
//验证权限
// if ($request->user['role'] != 1) {
// $where[] =['user_id',$userId] ;
// }
$grade = [];
if (!Util::isEmpty($follow) && $follow == 0) {
$where[] = ['grade','<=', 2];
$where[] = ['grade', '<=', 2];
} elseif (!Util::isEmpty($follow) && $follow == 1) {
$grade = [3, 4];
$grade = [3, 4];
} elseif (!Util::isEmpty($follow) && $follow == 2) {
$where[] = ['grade','=', 5];
$where[] = ['grade', '=', 5];
}
if (!Util::isEmpty($follow_last) && $follow_last == 0) {
$where[] = ['follow_last','>', strtotime('-1 day')];
}elseif (!Util::isEmpty($follow_last) && $follow_last == 1) {
$where[] = ['follow_last','>', strtotime('-3 day')];
}elseif (!Util::isEmpty($follow_last) && $follow_last == 2) {
$where[] = ['follow_last','>', strtotime('-7 day')];
$where[] = ['follow_last', '>', strtotime('-1 day')];
} elseif (!Util::isEmpty($follow_last) && $follow_last == 1) {
$where[] = ['follow_last', '>', strtotime('-3 day')];
} elseif (!Util::isEmpty($follow_last) && $follow_last == 2) {
$where[] = ['follow_last', '>', strtotime('-7 day')];
}
// 执行分页查询 //关联标签tags //关联标签及分组tags.group
$query = Customer::with('tags')->where($where)
->orderBy('crm_customer.id', 'desc');
if(!empty($tagId)){
//查询有$tagId 里任意一个标签的客户
// $query->whereHas('tags', function($query) use ($tagId){
// $query->where('tag.id', $tagId);
// });
// 执行分页查询
$query = Customer::where($where)
->orderBy('id', 'desc');
//查询有$tagId 里所有标签的客户
$tagId = explode(',', $tagId);
foreach ($tagId as $id) {
$query->whereHas('tags', function($query) use ($id){
$query->where('tag_id', $id);
});
}
}
if (!Util::isEmpty($keyword)) {
$query->where(function ($query) use ($keyword) {
$query->where('contacts', 'like', "%{$keyword}%")
->orWhere('phone', 'like', "%{$keyword}%");
});
}
if (!Util::isEmpty($grade)) {
$query->whereIn('grade', $grade);
}
// return Util::success($query->toSql().serialize($where),$follow);
$recycle = Util::getParam($request,'recycle', '');
if ($recycle == 'recycle') {
$query->onlyTrashed();
}
if ($seas == 'seas') {
$user = User::where('id', $userId)->first();
$corpId = $user?$user->corp_id:0;
if($corpId == 1){
$query->whereIn('channel_id', [1,2,3,4,5,6,7,8]);
} elseif($corpId == 3) {
$query->whereIn('channel_id', [9,10,11]);
} else{
$query->whereIn('channel_id', [0]);
}
$query->withTrashed();
}
$data = $query->paginate($perPage, ['*'], 'page', $page);
foreach ($data->items() as &$value) {
$value = Customer::getCustomer($value);
$value = Customer::getCustomer($value, $request);
if($seas == 'seas'){
$value['phone'] = Util::mask($value['phone']);
$value['email'] = Util::mask($value['email']);
$value['WhatsApp'] = Util::mask($value['WhatsApp']);
$value['seas_time'] = time()-(empty($value['deleted_at'])?strtotime($value['updated_at']):strtotime($value['deleted_at']));
}
}
return Util::page($data);
}
/**
* 客户恢复
* @param Request $request
* @return \support\Response
*/
public function restore(Request $request)
{
$id = Util::getParam($request,'id', '');
if (Util::isEmpty($id)) {
return Util::fail([], trans('id_empty'));
}
$userId = $request->user['id'];
$where = [
'id' => $id,
'user_id' => $userId,
];
$res = Customer::where($where)->restore();
if($res){
return Util::success($res, trans('success'));
}else{
return Util::fail([], trans('fail'));
}
}
/**
* 客户详情
* @param Request $request
@@ -138,7 +290,7 @@ class CustomerController
return Util::fail([], 'id' . trans('not_null'));
}
$res = Customer::select('id', 'user_id', 'grade', 'channel_id', 'car_type_id', 'country_id', 'magnitude', 'email', 'phone', 'WhatsApp', 'contacts', 'describe', 'address', 'lat', 'lng', 'follow_next', 'follow_remark', 'sex')
$res = Customer::with('tags')->select('id', 'user_id', 'grade', 'channel_id', 'car_type_id', 'country_id', 'magnitude', 'email', 'phone', 'WhatsApp', 'contacts', 'describe', 'address', 'lat', 'lng', 'follow_next', 'follow_remark', 'sex')
->where('id', $id)
->first();
if ($res) {
@@ -147,7 +299,7 @@ class CustomerController
return Util::fail([], '记录不存在');
}
$res = Customer::getCustomer($res);
$res = Customer::getCustomer($res, $request, true);
return Util::success($res);
}
@@ -168,27 +320,30 @@ class CustomerController
if (Util::isEmpty($country_id)) {
// return Util::fail([],'country_id'.trans('not_null'));
}
$car_type_id = Util::getParam($request, 'car_type_id');
if (Util::isEmpty($car_type_id)) {
return Util::fail([], trans('car_type_not_null'));
}
// $car_type_id = Util::getParam($request, 'car_type_id');
// if (Util::isEmpty($car_type_id)) {
// return Util::fail([], trans('car_type_not_null'));
// }
$contacts = Util::getParam($request, 'contacts');
$email = Util::getParam($request, 'email');
$phone = Util::getParam($request, 'phone');
if (Util::isEmpty($contacts) && Util::isEmpty($email) && Util::isEmpty($phone)) {
return Util::fail([], trans('contacts_not_null'));
return Util::fail([], trans('contacts_not_null'));
}
$user = User::where(['id' => $request->user['id']])->first();
$whatsApp = Util::getParam($request, 'WhatsApp', '');
$data = [
'user_id' => $request->user['id'],
'corp_id' => $user->corp_id,
'grade' => Util::getParam($request, 'grade', 0),
'channel_id' => $channel_id,
'country_id' => $country_id,
'car_type_id' => $car_type_id,
// 'car_type_id' => $car_type_id,
'magnitude' => Util::getParam($request, 'magnitude', 0),
'email' => $email,
'phone' => $phone,
'WhatsApp' => Util::getParam($request, 'WhatsApp', ''),
'WhatsApp' => $whatsApp,
'contacts' => $contacts,
'describe' => Util::getParam($request, 'describe'),
'lat' => Util::getParam($request, 'lat', 0),
@@ -198,6 +353,16 @@ class CustomerController
];
if (Util::isEmpty($id)) {
$data['enter_user_id'] = $request->user->uid;
$distinct = [
'email' => $email,
'phone' => $phone,
'whatsapp' => $whatsApp,
];
$dis = $this->distinct($distinct, $user->corp_id);
if($dis){
return Util::fail([], '客户线索重复,已经有人在跟进');
}
$res = Customer::create($data);
} else {
unset($data['grade']);
@@ -214,6 +379,148 @@ class CustomerController
}
}
public function distinct($params, $corpId){
$customer = Customer::where('corp_id', $corpId)
->where((function (Builder $query) use ($params) {
if(!empty($params['email']))
$query->Orwhere('email', '=', $params['email']);
if(!empty($params['phone']))
$query->Orwhere('phone', '=', $params['phone']);
if(!empty($params['whatsApp']))
$query->Orwhere('whatsApp', '=', $params['whatsApp']);
return $query;
}))
->first();
if (!empty($customer)) {
return true;
}
return false;
}
/**
* 领取公海客户
* @param Request $request
* @return \support\Response
*/
public function claim(Request $request)
{
$customerId = Util::getParam($request, 'customer_id');
$userId = $request->user['id'];
if (Util::isEmpty($customerId)) {
return Util::fail([], trans('customer_id').trans('not_null'));
}
$user = User::where(['id' => $userId])->first();
$data = [
'user_id' => $request->user['id'],
'obtain' => time(),
'corp_id' => $user->corp_id,
];
$customer= Customer::withTrashed()->find($customerId);
if(empty($customer) || $customer->user_id != 0){
return Util::fail('', trans('claim_fail'));
}
$customer->restore();
$res = $customer->update($data);
//记录客户关系变化
$his = CustomerHis::create([
'customer_id' => $customerId,
'user_his' => 0,
'user_id' => $userId,
]);
self::inquiryUpdate($customer,$request->user['id']);
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
/**
* 询单修改
*/
public static function inquiryUpdate($customer,$userId = null)
{
if(empty($customer->sn) || $customer->type!=1){
return false;
}
$inquiryLog = InquiryLog::where('order_no', $customer->sn)->first();
if(empty($inquiryLog)){
return false;
}
$userId = $userId??$customer->user_id;
if ($userId == 0){
$inquiryLog->recipient = 0;
$inquiryLog->t_time = time();
$inquiryLog->status = 1;
$inquiryLog->r_time = time();
$inquiryLog->save();
}else {
$inquiryLog->recipient = $customer->user_id;
$inquiryLog->t_time = time();
$inquiryLog->save();
}
return true;
}
/**
* 批量转让
* @param Request $request
* @return \support\Response
*/
public function cede(Request $request)
{
$customerId = Util::getParam($request, 'customer_id');
$userId = Util::getParam($request, 'user_id');
$selfId = $request->user['id'];
if (Util::isEmpty($userId)) {
return Util::fail([], 'user_id'.trans('not_null'));
}
if (Util::isEmpty($customerId)) {
return Util::fail([], 'customer_id'.trans('not_null'));
}
$user = User::where(['id' => $userId])->first();
if (Util::isEmpty($user)) {
return Util::fail(null, trans('user_none'));
}
$query= Customer::where('user_id',$selfId)->where('id',$customerId);
$customer = $query->get();
foreach ($customer as $item) {
//记录客户关系变化
$his = CustomerHis::create([
'customer_id' => $item->id,
'user_his' => $item->user_id,
'user_id' => $user['id'],
]);
self::inquiryUpdate($customer,$user->id);
}
$data = [
'user_id' => $user->id,
'obtain' => time(),
];
$res = $query->update($data);
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
/**
* 跟进状态
* @param Request $request
@@ -256,10 +563,11 @@ class CustomerController
$data = [
'follow_next' => Util::getParam($request, 'follow_next', 0),
'follow_remark' => Util::getParam($request, 'follow_remark', 0),
'warn' => 0,
];
$res = Customer::where('id', $id)
->update($data);
->update($data);
if ($res) {
return Util::success($res, trans('save_success'));
@@ -276,8 +584,22 @@ class CustomerController
public function delete(Request $request)
{
$id = Util::getParam($request, 'id');
$customer = Customer::where('id', $id)->first();
$res = $customer->delete();
$force = Util::getParam($request, 'force','');
$userId = $request->user['id'];
$where = [
'id' => $id,
'user_id' => $userId,
];
$customer = Customer::where($where)->withTrashed()->first();
if(empty($customer)){
return Util::fail('', trans('fail'));
}
if($force == 'force'){
$res = $customer->forceDelete();
}else{
$res = $customer->delete();
}
if ($res) {
return Util::success($res, trans('success'));
} else {
@@ -298,19 +620,19 @@ class CustomerController
}
$userId = $request->user['id'];
$created_at = $request->user['created_at'];
$day = ceil((time()-$created_at+1)/60/60/24);
$day = ceil((time() - $created_at + 1) / 60 / 60 / 24);
$where[] = ['user_id', '=', $userId];
$start = strtotime($created.'-01');
$start = strtotime($created . '-01');
$year = date('Y', $start);
$month = date('n',$start); //获取月份
$end = mktime(00, 00, 00, $month+1, 1, $year);
$month = date('n', $start); //获取月份
$end = mktime(00, 00, 00, $month + 1, 1, $year);
$where[] = ['created_at', '>=', $start];
$where[] = ['created_at', '<', $end];
$customer = Customer::where($where)->count();
//初步接触
$whereGrade = $where;
$whereGrade[] = ['grade','<=', 2];
$whereGrade[] = ['grade', '<=', 2];
$customerInit = Customer::where($whereGrade)->count();
//跟进中
@@ -318,7 +640,7 @@ class CustomerController
//已成交
$whereGrade = $where;
$whereGrade[] = ['grade','=', 5];
$whereGrade[] = ['grade', '=', 5];
$customerDeal = Customer::where($whereGrade)->count();
//拜访数
@@ -332,13 +654,13 @@ class CustomerController
$follow = Follow::where($whereVisit)->distinct('customer_id')->count();
$res = [
'customer'=>$customer, //客户数
'visit'=>$visit, //拜访
'follow'=>$follow, //跟进
'day'=>$day, //注册天数
'customer_init'=>$customerInit, //初步接触
'customero_fllow'=>$customeroFllow, //跟进中
'customer_deal'=>$customerDeal, //已成交
'customer' => $customer, //客户数
'visit' => $visit, //拜访
'follow' => $follow, //跟进
'day' => $day, //注册天数
'customer_init' => $customerInit, //初步接触
'customero_fllow' => $customeroFllow, //跟进中
'customer_deal' => $customerDeal, //已成交
];
if ($res) {
return Util::success($res, trans('success'));
@@ -347,4 +669,63 @@ class CustomerController
}
}
/**
* 线索分配
* @param Request $request
* @return \support\Response
*/
public function collect(Request $request)
{
Log::info('receive collect start',$request->all());
$user_sn = Util::getParam($request, 'user_sn'); //用户sn
// $user_email = Util::getParam($request, 'user_email'); //邮箱
$user_id = Util::getParam($request, 'user_id'); //邮箱
$sn = Util::getParam($request, 'order_no'); //客户sn验证客户唯一性
$channel_id = Util::getParam($request, 'channel_id'); //渠道
$country_id = Util::getParam($request, 'country_id'); //国家
$magnitude = Util::getParam($request, 'magnitude'); //商机
$describe = Util::getParam($request, 'describe'); //客户详情
$phone = Util::getParam($request, 'phone'); //用户详情
$email = Util::getParam($request, 'email'); //用户详情
$WhatsApp = Util::getParam($request, 'WhatsApp');
$contacts = Util::getParam($request, 'contacts'); //联系人
if (Util::isEmpty($user_sn)) {
return Util::fail([], '用户sn不能为空');
}
if (Util::isEmpty($sn)) {
return Util::fail([], '客户sn不能为空');
}
// $user = UserService::updateSn($user_sn, $user_email);
// if(!$user){
// return Util::fail($user, $user_email.'用户不存在');
// }
$res = Customer::firstOrCreate(
['sn' => $sn],
[
'user_sn' => $user_sn,
'user_id' => $user_id,
'type' => 0,
'channel_id' => $channel_id,
'country_id' => $country_id,
'magnitude' => $magnitude,
'desc_collect' => $describe,
'phone' => $phone,
'email' => $email,
'WhatsApp' => $WhatsApp,
'contacts' => $contacts,
]
);
if ($res) {
return Util::success($res, trans('success'));
} else {
return Util::fail($res, trans('fail'));
}
}
}
+51 -62
View File
@@ -5,6 +5,7 @@ namespace app\controller;
use app\model\FeishuUser;
use app\model\User;
use app\util\Util;
use config\constants\Constants;
use support\Log;
use support\Request;
use support\exception\BusinessException;
@@ -25,13 +26,18 @@ class FeishuController
*/
public function getinfo(Request $request)
{
$config = Util::getParam($request, 'config');
if (Util::isEmpty($config)) {
$config = $this->config;
// $config = Util::getParam($request, 'config');
// if (Util::isEmpty($config)) {
// $config = $this->config;
// }
$userId = $request->user['id'];
$config = User::where('id',$userId)->value('sign');
if(Util::isEmpty($config)){
return Util::fail(null,trans('sign_not_null'));
}
// 获取凭证
$certificate = config($config);
$certificate = config('feishu.'.$config);
$arr = [
'app_id' => $certificate['appId'],
'redirect_uri' => $certificate['rUrl'],
@@ -48,13 +54,10 @@ class FeishuController
public function getSign(Request $request)
{
// 获取凭证
$certificate = config('feishu');
$res = [];
foreach ($certificate as $k => $v) {
$res []=$k;
}
$res = Constants::SIGN;
// foreach ($certificate as $k => $v) {
// $res []=['id'=>$k,'name'=>$k];
// }
return Util::success($res,trans('success'));
}
@@ -70,8 +73,14 @@ class FeishuController
public function auth(Request $request)
{
$param = $request->all();
$userId = $request->user['id'];
$config = User::where('id',$userId)->value('sign');
if(Util::isEmpty($config)){
return Util::fail(null,trans('sign_not_null'));
}
// 获取凭证
$certificate = config($this->config);
$certificate = config('feishu.'.$config);
// 飞书服务
$class = new \app\service\FeishuService($certificate['appId'], $certificate['appSecret'], $certificate['state']);
@@ -89,54 +98,33 @@ class FeishuController
}
Log::info('feishu user_info', ['res' => $rst]);
$state = explode(",", $param['state']);
$state = explode("_", $param['state']);
//$userId = $request->user['id'];
$userId = $state[2];
$user = FeishuUser::where('id', $userId)->first();
$userId = $state[1];
// $user = FeishuUser::where('id', $userId)->first();
// $user = FeishuUser::create();
//保存用户open_id
$user->user_id = $userId;
$user->sign = $state[0];
$user->tenant_key = $rst['data']['tenant_key'];
$user->open_id = $rst['data']['open_id'];
$user->feishu_user_id = $rst['data']['user_id'];
$user->union_id = $rst['data']['union_id'];
$user->save();
// //保存用户open_id
// $user->user_id = $userId;
// $user->sign = $state[0];
// $user->tenant_key = $rst['data']['tenant_key'];
// $user->open_id = $rst['data']['open_id'];
// $user->feishu_user_id = $rst['data']['user_id'];
// $user->union_id = $rst['data']['union_id'];
// $user->save();
// var_dump($rst);
// array(3) {
// ["code"]=>
// int(0)
// ["data"]=>
// array(11) {
// ["avatar_big"]=>
// string(168) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=640x640&cut_type=&quality=&format=image&sticker_format=.webp"
// ["avatar_middle"]=>
// string(168) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=240x240&cut_type=&quality=&format=image&sticker_format=.webp"
// ["avatar_thumb"]=>
// string(166) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=72x72&cut_type=&quality=&format=image&sticker_format=.webp"
// ["avatar_url"]=>
// string(166) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=72x72&cut_type=&quality=&format=image&sticker_format=.webp"
// ["en_name"]=>
// string(9) "李佳博"
// ["mobile"]=>
// string(14) "+8615738985690"
// ["name"]=>
// string(9) "李佳博"
// ["open_id"]=>
// string(35) "ou_37bb7cfc4311c858ea32461700fa1a43"
// ["tenant_key"]=>
// string(16) "14e7bc0fe5985740"
// ["union_id"]=>
// string(35) "on_a3fdbca48cd9477a140c7f2167a63691"
// ["user_id"]=>
// string(8) "481g947d"
// }
// ["msg"]=>
// string(7) "success"
// }
$user = new FeishuUser();
$user->firstOrCreate([
'user_id' => $userId,
'sign' => $state[0],
'tenant_key' => $rst['data']['tenant_key'],
'open_id' => $rst['data']['open_id'],
'feishu_user_id' => $rst['data']['user_id'],
'union_id' => $rst['data']['union_id']
]);
return json($rst);
// return json($rst);
return Util::success($rst['data'], trans('success'));
} else {
//需要登录并且未提供token
if (!Util::isEmpty($request->user['id'])) {
@@ -159,11 +147,11 @@ class FeishuController
* @param $href 详情链接
* @return \support\Response
*/
public function send($receiveId,$title,$content,$href)
public static function send($config='xinyouhe',$receiveId='ou_e33bb3017ada6c4781398a68e55a4696',$title='ceshi',$content='测试',$href='http://219.157.255.213:8085/pages/index/mine')
{
Log::info('feishu send', ['receiveId' => $receiveId, 'title' => $title, 'content' => $content, 'href' => $href]);
// 获取凭证
$certificate = config($this->config);
$certificate = config('feishu.'.$config);
Log::info('feishu send', [$certificate,'config'=>$config,'receiveId' => $receiveId, 'title' => $title, 'content' => $content, 'href' => $href]);
// 飞书服务
$class = new \app\service\FeishuService($certificate['appId'], $certificate['appSecret'], $certificate['state']);
@@ -194,7 +182,7 @@ class FeishuController
}";
// 卡片 类型
/* $content = "{
/*$content = "{
\"config\":{
\"wide_screen_mode\":true
},
@@ -223,7 +211,8 @@ class FeishuController
}
}
}";*/
$msgType = 'interactive';
// $msgType = 'interactive';
$msgType = 'post'; //卡片消息:interactive,富文本消息:post
$receiveIdtype = 'open_id';
$result = $class->sendMessages($receiveId, $content, $msgType, $receiveIdtype);
+11 -8
View File
@@ -55,9 +55,7 @@ class FollowController
if(Util::isEmpty($userId)){
return Util::fail(['user_id'=>$userId],trans('user_none'));
}
if($request->user['role']!=1){
$where['user_id'] = $userId;
}
$where['user_id'] = $userId;
//跟进id
$id = Util::getParam($request,'id');
@@ -123,10 +121,13 @@ class FollowController
if(Util::isEmpty($type)){
return Util::fail([],'type'.trans('not_null'));
}
$picture = Util::getParam($request,'picture');
if(Util::isEmpty($picture)){
return Util::fail([],trans('picture_not_null'));
}
$picture = Util::getParam($request,'picture');
$audio_text = Util::getParam($request,'audio_text');
$remark = Util::getParam($request,'remark');
if(Util::isEmpty($picture) && Util::isEmpty($audio_text) && Util::isEmpty($remark)){
return Util::fail([],trans('follow_not_null'));
}
$data = [
'user_id'=>$request->user['id'],
@@ -135,7 +136,7 @@ class FollowController
'picture'=>$picture,
'remark'=>Util::getParam($request,'remark',''),
'audio'=>Util::getParam($request,'audio',''),
'audio_text'=>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'),
@@ -146,6 +147,8 @@ class FollowController
$customer = Customer::find($customer_id);
$customer->follow_last = strtotime($res->created_at);
$customer->follow_next = null;
$customer->warn = 0;
$customer->save();
if ($res) {
+68
View File
@@ -0,0 +1,68 @@
<?php
namespace app\controller;
use app\model\CustomerTag;
use app\model\TagGroup;
use app\util\Util;
use config\constants\Constants;
use support\Request;
class TagGroupController
{
// 列表
public function list(Request $request)
{
$list = TagGroup::with('tags')->get();
$languageArr = Constants::LANGUAGE;
// $language = $request->user['language'];
//$language = 'zh_CN';
$language = $request->language;
foreach ($list as &$item) {
$item['names'] = unserialize($item['names']);
if (in_array($language, $languageArr)) {
$item['name'] = $item['names'][$language];
}
foreach ($item['tags'] as &$tag) {
$tag['names'] = unserialize($tag['names']);
if (in_array($language, $languageArr)) {
$tag['name'] = $tag['names'][$language];
}
}
}
return Util::success($list);
}
/**
* 更新客户标签关系
* @param Request $request
* @return \support\Response
*/
public function updatePivot(Request $request)
{
$customerId = Util::getParam($request, 'customer_id');
$groupId = Util::getParam($request, 'group_id');
$tagId = Util::getParam($request, 'tag_id');
if (Util::isEmpty($customerId)) {
return Util::fail([], trans('customer_id') . trans('not_null'));
}
if (Util::isEmpty($groupId)) {
return Util::fail([], trans('tag_group_id') . trans('not_null'));
}
if(empty($tagId)){
$res = CustomerTag::where(['customer_id' => $customerId, 'group_id' => $groupId])->delete();
}else{
$res = CustomerTag::updateOrCreate(['customer_id' => $customerId, 'group_id' => $groupId], ['tag_id' => $tagId]);
}
if($res){
return Util::success($res, trans('success'));
}else{
return Util::fail($res, trans('fail'));
}
}
}
+6 -1
View File
@@ -14,6 +14,11 @@ use support\Request;
class UploadController
{
/**
* 不需要登录的方法
*/
protected $noNeedLogin = ['uploadImage'];
// 允许的文件类型
protected $allowedMimeTypes = [
'image/jpeg',
@@ -110,7 +115,7 @@ class UploadController
}
$result = Storage::adapter('oss')
->path('vehicle_album/'.date('Ymd'))
->path('lingke_crm/'.date('Ymd'))
->size(1024*1024*5)
->extYes(['image/jpeg','image/png'])
->extNo(['image/gif'])
+171 -50
View File
@@ -2,11 +2,20 @@
namespace app\controller;
use app\model\Corp;
use app\model\Country;
use app\model\FeishuUser;
use app\model\User;
use app\model\UserSn;
use app\service\AuthService;
use app\service\MailService;
use app\service\UserService;
use app\util\HttpClient;
use app\util\JwtUtil;
use app\util\Util;
use config\constants\Constants;
use support\exception\BusinessException;
use support\Log;
use support\Redis;
use support\Request;
@@ -15,24 +24,40 @@ class UserController
/**
* 不需要登录的方法
*/
protected $noNeedLogin = ['login', 'sendCode', 'register'];
protected $noNeedLogin = ['login', 'sendCode', 'register', 'step', 'savePassword'];
public function login(Request $request)
{
$email = Util::getParam($request, 'email');
$corpAbbr = Util::getParam($request, 'abbr');
$language = Util::getParam($request, 'language');
if (Util::isEmpty($email)) {
return Util::fail([], trans('required_not_null'));
}
if (Util::isEmpty($corpAbbr)) {
return Util::fail([], 'abbr'.trans('not_null'));
}
$password = Util::getParam($request, 'password');
if (Util::isEmpty($password)) {
return Util::fail([], trans('required_not_null'));
}
$user = User::select(['id', 'name', 'sex', 'role', 'avatar', 'email', 'password'])
->where('status', 0)
->where('email', $request->post('email'))
// 获取企业ID
$corpInfo = Corp::where('abbr', $corpAbbr)->first();
if (!$corpInfo) {
return Util::fail([], '公司不存在');
}
$corpId = $corpInfo->id;
$user = User::where('status', 0)
// ->where('email', $request->post('email'))
->where('corp_id', $corpId)
->OrWhere(['email' => $request->post('email'),'phone' => $request->post('email')])
->first();
// $builder = User::where('status', 0)
// ->where('email', $request->post('email'));
// $sql = str_replace(['?'], ['\'%s\''], $builder->toSql());
// $fullSql = vsprintf($sql, $builder->getBindings());
if (!$user) {
return Util::fail(['user' => $user], trans('user_none'));
}
@@ -41,14 +66,20 @@ class UserController
$userPassword = $user['password'];
//加密
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
//验证密码
// if (!password_verify($userPassword, $hashedPassword)) {
if ($userPassword == $hashedPassword) {
// if ($userPassword == $hashedPassword) {
if (!password_verify($password, $userPassword)) {
locale($language);
return Util::fail([], trans('password_error'));
}
if ($user['status'] != 1) {
return Util::fail([], '账号已禁用',403);
}
$userId = $user['id']; // 实际从数据库获取
@@ -59,17 +90,29 @@ class UserController
$result = $user;
unset($result['password']);
$result['token'] = $token;
$result['feishu_openid'] = FeishuUser::where('user_id', $userId)->value('open_id');
// $result['feishu_openid'] = FeishuUser::where('user_id', $userId)->value('open_id');
$result['feishu_openid'] = $result['openid']??'';
if (Util::isEmpty($language)) {
User::where('id', $userId)
->update(['language' => $language]);
if (!Util::isEmpty($language)) {
// User::where('id', $userId)
// ->update(['language' => $language]);
locale($language);
}
return Util::success($result, trans('login_success'));
}
public function loginNew(Request $request)
{
try {
$authService = new AuthService();
$result = $authService->uPwdLogin($request->all());
return Util::success($result, '登录成功');
} catch (\Throwable $e) {
Util::fail([],$e->getMessage());
}
}
/**
* 发送邮箱验证码
* @param Request $request
@@ -80,7 +123,7 @@ class UserController
{
$email = Util::getParam($request, 'email');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return Util::fail([], trans('required_not_null'));
return Util::fail([], trans('email_error'));
}
// 生成验证码
@@ -108,12 +151,13 @@ class UserController
*/
public function register(Request $request)
{
$email = Util::getParam($request, 'email', 'asdf');
$email = Util::getParam($request, 'email', '');
$code = Util::getParam($request, 'code');
$sex = Util::getParam($request, 'sex', 0);
$name = Util::getParam($request, 'name', '');
$password = Util::getParam($request, 'password');
$mobile = Util::getParam($request, 'mobile');
$corpAbbr = Util::getParam($request, 'abbr');
$id = Util::getParam($request, 'id');
$language = Util::getParam($request, 'language');
@@ -124,9 +168,9 @@ class UserController
$res = User::select('id', 'email')
->where('email', $email)
->first();
// if (!Util::isEmpty($res)) {
// return Util::fail([], trans('email_repeat'));
// }
if (!empty($res)) {
return Util::fail($res, trans('email_repeat'));
}
if (Util::isEmpty($name)) {
// return Util::fail([], trans('required_not_null'));
@@ -137,28 +181,41 @@ class UserController
if ($code != $verification_code) {
return Util::fail([], trans('code_error'));
}
if(strlen($password) < 8) {
return Util::fail([], trans('password_short'));
}
//加密
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$data = [
'mobile' => $mobile,
'phone' => $mobile,
'email' => $email,
'name' => $name,
'name' => '用户_'.rand(111111, 999999),
'sex' => $sex,
'role' => 1,
'password' => $hashedPassword,
'status' => 0,
'status' => 1,
'avatar' => ''
];
if (Util::isEmpty($id)) {
$res = User::create($data);
} else {
$res = User::where('id', $id)
->update($data);
// Log::info('update', ['res' => $res]);
(!$res) ?: $res = User::find($id)->toArray();
// 获取可用用户编号
$userSnModel = new UserSn();
$sn = $userSnModel->where('user_id', '=', 0)->inRandomOrder()->first();
if (!$sn) {
Log::error('用户注册时未找到适用编号');
return Util::fail([], '未找到适用编号');
}
$data['sn'] = $sn->user_sn;
// 获取企业ID
$corpInfo = Corp::where('abbr', $corpAbbr)->first();
if (!$corpInfo) {
return Util::fail([], '公司不存在');
}
$data['corp_id'] = $corpInfo->id;
$res = User::create($data);
unset($res['password']);
locale($language);
@@ -169,6 +226,28 @@ class UserController
}
}
public function step()
{
$users = User::where(['sn'=>0])->get();
$r = [];
foreach ($users as $user) {
$option = ['email' => $user->email];
$userService = new UserService;
$res = $userService->createOrquery($option);
Log::info('register_rpc',$res);
// return Util::fail($res, trans('register_fail'));
if ($res['code'] != 200 && $res['data']['code'] != 0){
return Util::fail($res, trans('register_fail'));
}
$data[] = [];
$data['sn'] = $res['data']['data']['sn'];
$data['id'] = $res['data']['data']['uid'];
$res = User::where('id',$user->id)->update(['sn' => $data['sn'],'id' => $data['id']]);
$r[]=$data;
}
return Util::success($r, trans('register_success'));
}
public function getInfo(Request $request)
{
@@ -177,9 +256,32 @@ class UserController
->first();
$user->toArray();
unset($user->password);
$user['feishu_openid'] = FeishuUser::where('user_id', $userId)->value('open_id');
// $user['feishu_openid'] = FeishuUser::where('user_id', $userId)->value('open_id');
$user['feishu_openid'] = $user['openid']??'';
$user['country_name'] = Country::where('id', $user['country_id'])->value('cn_addr');
$ossservice = new \app\service\OssService();
$user['avatar_url'] = $user['avatar'];
$user['socialize_pic_url'] = $user['socialize_pic'] ? $ossservice->generatePrivateUrl($user['socialize_pic']) : '';
return Util::success($user, trans('save_success'));
// 重构数组
$sign = array_column(Constants::SIGN, 'name', 'id');
$user['company'] = isset($sign[$user['sign']])?$sign[$user['sign']]:'';
return Util::success($user, trans('success'));
}
public function getUsers(Request $request)
{
$userId = $request->user['id'];
$abbr = $request->input('abbr');
if(empty($abbr)){
return Util::fail([], 'abbr'.trans('not_null'));
}
$corpId = Corp::where('abbr', $abbr)->value('id');
$where[] = ['corp_id' , $corpId];
$where[] = ['status' , 1];
$user = User::select('id','name')->where($where)
->get();
return Util::success($user, trans('success'));
}
/**
@@ -190,23 +292,32 @@ class UserController
*/
public function save(Request $request)
{
$name = Util::getParam($request, 'name');
$sex = Util::getParam($request, 'sex');
$position = Util::getParam($request, 'position');
$country_id = Util::getParam($request, 'country_id');
$sign = Util::getParam($request, 'sign');
$id = $request->user['id'];
$avatar = Util::getParam($request, 'avatar');
$socializePic = Util::getParam($request, 'socialize_pic');
$data = [
'name' => $name,
'sex' => $sex,
'position' => $position,
'country_id' => $country_id,
'sign' => $sign,
];
$user = User::where('id', $id)->first();
// 只填充前端传递的字段
$user->fill($request->only(['name', 'sex', 'position', 'country_id', 'sign', 'mobile', 'address', 'socialize', 'socialize_pic']));
$res = User::where('id', $id)
->update($data);
if(!Util::isEmpty($avatar)){
$user->avatar = $avatar;
}
if(!Util::isEmpty($socializePic)){
$user->socialize_pic = $socializePic;
}
$mobile = $user->isDirty('mobile');
$name = $user->isDirty('name');
$sign = $user->isDirty('sign');
if($mobile || $name || $sign){
$userService = new UserService;
$option = ['uid' => $user->id, 'phone' => $user->mobile, 'name' => $user->name, 'sign' => $user->sign, ];
$res = $userService->update($option);
Log::info('register_rpc',$res);
}
$res = $user->save();
if ($res) {
return Util::success($res, trans('save_success'));
@@ -227,16 +338,24 @@ class UserController
$email = Util::getParam($request, 'email');
$code = Util::getParam($request, 'code');
$verification_code = Redis::get("verification_code:{$email}");
$id = $request->user['id'];
// $id = $request->user->uid;
if ($code != $verification_code) {
return Util::fail([], trans('code_error'));
}
$res = User::where('id', $id)
// $res = User::where('id', $id)
// ->first();
// if($res['email'] != $email) {
// return Util::fail([], trans('email_consistent'));
// }
$user = User::where('status', 0)
// ->where('corp_id', $corpId)
->OrWhere(['email' => $request->post('email'),'phone' => $request->post('email')])
->first();
if($res['email'] != $email) {
return Util::fail([], trans('email_consistent'));
if(!$user) {
return Util::fail([], trans('user_none'));
}
//加密
@@ -246,9 +365,11 @@ class UserController
$data = [
'password' => $hashedPassword
];
$user->password = $hashedPassword;
$res = $user->save();
$res = User::where('id', $id)
->update($data);
// $res = User::where('id', $id)
// ->update($data);
if ($res) {
return Util::success($res, trans('save_success'));
@@ -270,11 +391,11 @@ class UserController
if (Util::isEmpty($language)) {
return Util::fail([], 'language' . trans('not_null'));
}
if (!in_array($language, ['en', 'zh_CN'])) {
if (!in_array($language, Constants::LANGUAGE)) {
return Util::fail([], trans('param_error'));
}
$data = [
'language' => $language,
// 'language' => $language,
];
$res = User::where('id', $id)
+15 -6
View File
@@ -54,11 +54,15 @@ class AuthMiddleware implements MiddlewareInterface
// 从 Header 获取 Token
$token = $request->header('Authorization');
$language = Util::getParam($request, 'language');
$language = $language=='zh_CN'?:'en';
//需要登录并且未提供token
if ($isLogin && (!$token || !str_starts_with($token, 'Bearer '))) {
return Util::fail('','请先登录',401);
locale($language);
return Util::fail('',trans('user_login'),401);
// throw new BusinessException('未提供 Token'.$isLogin, 401);
}elseif(!$isLogin){
locale($language);
return $handler($request);
}
@@ -68,19 +72,24 @@ class AuthMiddleware implements MiddlewareInterface
// 验证 Token 并获取用户ID
$decoded = JwtUtil::verifyToken($token);
$userId = $decoded->sub;
if (!isset($decoded->sub)) {
return Util::fail('', trans('user_login'),401);
}
$user = User::select(['id','name','sex','role','avatar','email','password','language','created_at'])
->find($userId);
$userId = $decoded->sub;
$user = User::find($userId);
if(!$user){
return Util::fail(['user'=>$user],trans('user_none'));
return Util::fail(['user'=>$userId],trans('user_none'));
}
$user = $user->toArray();
// 将用户ID存入请求对象,供后续使用
// $request->user = ['id' => $userId];
$request->user = $user;
locale($user['language']);
$request->language = $request->header('fdesk-language');
// locale($user['language']);
locale($request->language);
return $handler($request);
} catch (BusinessException $e) {
return json(['code' => 401, 'msg' => $e->getMessage()]);
+28 -11
View File
@@ -7,19 +7,36 @@ use Webman\MiddlewareInterface;
class CrossDomain implements MiddlewareInterface
{
public function process(Request $request, callable $next): Response
{
// 动态允许请求来源(支持携带Cookie)
$origin = $request->header('origin', '*');
$response = $next($request);
// public function process(Request $request, callable $next): Response
// {
// // 动态允许请求来源(支持携带Cookie)
// $origin = $request->header('origin', '*');
// $response = $next($request);
//
// // 设置跨域响应头
// $response->withHeaders([
// 'Access-Control-Allow-Origin' => $origin,
// 'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
// 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With',
// 'Access-Control-Allow-Credentials' => 'true', // 允许携带Cookie
// 'Access-Control-Max-Age' => 86400, // 预检请求缓存时间(秒)
// 'Vary' => 'Origin' // 避免缓存干扰
// ]);
//
// return $response;
// }
// 设置跨域响应头
public function process(Request $request, callable $handler) : Response
{
// 如果是options请求则返回一个空响应,否则继续向洋葱芯穿越,并得到一个响应
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
// 给响应添加跨域相关的http头
$response->withHeaders([
'Access-Control-Allow-Origin' => $origin,
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With',
'Access-Control-Allow-Credentials' => 'true', // 允许携带Cookie
'Access-Control-Max-Age' => 86400, // 预检请求缓存时间(秒)
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Origin' => $request->header('origin', '*'),
'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
'Vary' => 'Origin' // 避免缓存干扰
]);
+1 -1
View File
@@ -30,7 +30,7 @@ class CarType extends Model
public static function getAll()
{
$list = self::get()->select('id','name','status')->where('status',0)->toArray();
$list = self::get()->select('id','name','name_en','status')->where('status',0)->toArray();
return $list;
}
}
+2 -2
View File
@@ -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','status')->where('status',0)->toArray();
$list = self::get()->select('id','name','name_en','status')->where('status',1)->toArray();
return $list;
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
namespace app\model;
use app\util\Util;
use config\constants\Constants;
use DateTimeInterface;
use Illuminate\Support\Carbon;
use support\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Corp extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'corp';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
//设置黑名单
protected $guarded = ['id','created_at','updated_at'];
// 指定日期字段存储格式为时间戳
protected $dateFormat = 'U';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
}
+47 -11
View File
@@ -17,7 +17,7 @@ class Customer extends Model
*
* @var string
*/
protected $table = 'customer';
protected $table = 'crm_customer';
/**
* The primary key associated with the table.
@@ -59,21 +59,31 @@ class Customer extends Model
return $date->format(Carbon::parse($date)->toDateTimeString());
}
public static function getCustomer($customer)
/**
* @param $customer
* @param $request
* @param $tag 是否返回客户标签
* @return mixed
*/
public static function getCustomer($customer, $request, $tag = false)
{
$customer['grade_txt'] = Constants::GRADE[$customer['grade']];
$customer['magnitude_txt'] = Constants::MAGNITUDE[$customer['magnitude']];
$customer['sex_txt'] = Constants::SEX[$customer['sex']];
//$language = $request->user['language'] ?: 'en';
//$language = 'zh_CN';
$language = $request->language;
$customer['grade_txt'] = Util::language($language, Constants::GRADE_EN[$customer['grade']], Constants::GRADE[$customer['grade']], Constants::GRADE_RU[$customer['grade']]);
$customer['magnitude'] = ($customer['magnitude']==0)?1:$customer['magnitude'];
$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'] = '跟进中';
$customer['follow_txt'] = Util::language($language,'Following','跟进中','Продолжение');
}elseif ($customer['grade']<5) {
$customer['follow'] = 1;
$customer['follow_txt'] = '已成交';
$customer['follow_txt'] = Util::language($language,'transacted','已成交','Транзакция завершена');
}else{
$customer['follow'] = 2;
$customer['follow_txt'] = '已流失';
$customer['follow_txt'] = Util::language($language,'lost','已流失','Потерянный');
}
$where = [
@@ -89,11 +99,37 @@ class Customer extends Model
// $customer['updated_at'] = Util::timeTotDate($customer['updated_at']);
$customer = Util::formatDate($customer,['follow_last']);
$customer['car_type_name'] = empty($customer['car_type_id'])?'':CarType::where(['id'=>$customer['car_type_id']])->value('name');
$customer['country_name'] = empty($customer['country_id'])?'':Country::where(['id'=>$customer['country_id']])->value('cn_addr');
$customer['channel_name'] = empty($customer['channel_id'])?'':Channel::where(['id'=>$customer['channel_id']])->value('name');
$nameLang = $language=='en'?'name_en':($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');
}
}
+68
View File
@@ -0,0 +1,68 @@
<?php
namespace app\model;
use app\util\Util;
use config\constants\Constants;
use DateTimeInterface;
use Illuminate\Support\Carbon;
use support\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class CustomerHis extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'crm_customer_his';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
//设置黑名单
protected $guarded = ['id','created_at'];
// 指定日期字段存储格式为时间戳
protected $dateFormat = 'U';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $casts = [
'created_at' => '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; // 不做任何操作
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace app\model;
use app\util\Util;
use support\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class CustomerTag extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'crm_customer_tag';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
//设置黑名单
protected $guarded = ['id', 'created_at'];
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
+12 -5
View File
@@ -3,6 +3,7 @@
namespace app\model;
use app\service\OssService;
use app\util\Util;
use config\constants\Constants;
use support\Model;
@@ -15,7 +16,7 @@ class Follow extends Model
*
* @var string
*/
protected $table = 'follow';
protected $table = 'crm_follow';
/**
* The primary key associated with the table.
@@ -37,8 +38,6 @@ class Follow extends Model
*/
public $timestamps = true;
protected $dates = ['created_at', 'updated_at', 'follow_time'];
protected $casts = [
'updated_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式
'created_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式
@@ -50,8 +49,16 @@ class Follow extends Model
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'];
$follow['oss_picture'] = $domain.'/'.$follow['picture'];
$follow['firstFollowtime'] = $follow['follow_time'];
if (isset($follow['picture']) && !empty($follow['picture'])) {
$ossservice = new OssService();
$oss_picture = $ossservice->generatePrivateUrl($follow['picture'],86400);
$follow['oss_picture'] = $oss_picture;
}else {
$follow['oss_picture'] = '';
}
$follow['created_at'] = (!empty($follow['created_at']))?date('Y-m-d H:i:s',strtotime($follow['created_at'])+(3600*8)):'';
$follow['updated_at'] = (!empty($follow['updated_at']))?date('Y-m-d H:i:s',strtotime($follow['updated_at'])+(3600*8)):'';
// $follow = Util::formatDate($follow);
return $follow;
}
+74
View File
@@ -0,0 +1,74 @@
<?php
namespace app\model;
use support\Model;
class InquiryLog extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'inquiry_log';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = [
'id', 'order_no', 'enter_user_id', 'recipient',
'quality', 'channel', 'email', 'tel', 'whatsapp',
'country', 'contacts', 'content', 'status',
'r_time', 't_time', 'created_at', 'updated_at'
];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
public function enter()
{
return $this->hasOne(User::class, 'id', 'enter_user_id');
}
// public function recipientInfo()
// {
// return $this->hasOne(User::class, 'id', 'recipient')->where('status', 1);
// }
public function recipientInfo()
{
return $this->hasOne(User::class, 'id', 'recipient');
}
public function countryInfo()
{
return $this->hasOne(Country::class, 'id', 'country');
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
namespace app\model;
use app\util\Util;
use config\constants\Constants;
use DateTimeInterface;
use Illuminate\Support\Carbon;
use support\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tag extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'crm_tag';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
//设置黑名单
protected $guarded = ['id','created_at','updated_at'];
// 指定日期字段存储格式为时间戳
protected $dateFormat = 'U';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
// 定义反向多对一关联
public function group()
{
return $this->belongsTo(TagGroup::class, 'group_id', 'id');
}
public function customers()
{
return $this->belongsToMany(Customer::class, 'customer_tag', 'tag_id', 'customer_id');
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace app\model;
use app\util\Util;
use config\constants\Constants;
use DateTimeInterface;
use Illuminate\Support\Carbon;
use support\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class TagGroup extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'crm_tag_group';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
//设置黑名单
protected $guarded = ['id','created_at','updated_at'];
// 指定日期字段存储格式为时间戳
protected $dateFormat = 'U';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
// 定义与 Tag 的一对多关系
public function tags()
{
return $this->hasMany(Tag::class, 'group_id', 'id');
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ class User extends Model
protected $dateFormat = 'U';
//设置黑名单
protected $guarded = ['id','created_at','updated_at'];
protected $guarded = ['created_at','updated_at'];
protected $casts = [
// 'updated_at' => 'datetime:Y-m-d H:i:s', // 指定序列化格式
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace app\model;
use support\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class UserSn extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'user_sn';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
+22 -19
View File
@@ -1,39 +1,42 @@
<?php
namespace process;
namespace app\process;
use app\controller\FeishuController;
use app\model\Customer;
use app\model\CustomerHis;
use app\model\FeishuUser;
use app\model\User;
use support\Log;
use Webman\App;
use Workerman\Crontab\Crontab;
class Task
{
public function onWorkerStart()
{
// 每半小时执行一次
new Crontab('30/* * * * *', function () {
// 每小时执行一次
new Crontab('0 10 * * * *', function(){
echo date('Y-m-d H:i:s') . "\n";
$customer = Customer::where(['follow_next', '<=', time() + 3600])
->where(['follow_next', '>', time()])
->where(['warn', '<', 1])
->get();
Log::info('send high seas start',[time()]);
$where = [
['deleted_at', '<=', time() - 3600],
['user_id', '<>', 0],
];
$customer = Customer::where($where)->onlyTrashed()->get();
foreach ($customer as $item) {
$feishuUser = FeishuUser::where(['user_id' => $item->user_id])->first();
if ($feishuUser) {
// 获取凭证
$certificate = config($this->config);
// 使用parse_url解析URL
$parsedUrl = parse_url($certificate['rUrl']);
// 获取域名和端口
$host = $parsedUrl['host'];
$port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
$url = $host .$port. '/pages/customer/detile?id='.$customer->id;
FeishuController::class->send($feishuUser->open_id, '跟进提醒', '您有新的跟进提醒', $url);
}
$item->update(['user_id' => 0, 'deleted_at' => time()]);
CustomerHis::create([
'customer_id' => $item->_id,
'user_his' => $item->user_id,
'user_id' => 0,
]);
}
Log::info('send high seas end',[time()]);
});
}
+1 -1
View File
@@ -192,7 +192,7 @@ class FeishuService
"client_id" => $this->appId,
"client_secret" => $this->appSecret,
"code" => $code,
"redirect_uri" => 'http://219.157.255.213:8085/pages/index/webview'
"redirect_uri" => $redirect_uri
];
return $this->requestResult('authen/v2/oauth/token');
}
+11 -3
View File
@@ -19,10 +19,18 @@ class MailService
{
// SMTP 配置
$this->mailer->isSMTP();
$this->mailer->Host = 'smtp.gmail.com';
// $this->mailer->Host = 'smtp.gmail.com';
$this->mailer->Host = 'smtp.feishu.cn';
$this->mailer->SMTPAuth = true;
$this->mailer->Username = 'xinyouhe25@gmail.com'; // 替换为你的 Gmail
$this->mailer->Password = 'zhjkkaplncykzymo'; // 替换为应用专用密码
// $this->mailer->Username = 'xinyouhe25@gmail.com'; // 替换为你的 Gmail
// $this->mailer->Password = 'zhjkkaplncykzymo'; // 替换为应用专用密码
// $this->mailer->Username = 'linyang0618@gmail.com'; // 替换为你的 Gmail
// $this->mailer->Password = 'mrjefuahbwbpqakb'; // 替换为应用专用密码
$this->mailer->Username = 'app@hnxinyouhe.com'; // 替换为你的 Gmail
$this->mailer->Password = 'akyIUFJ6ihGGjI5h'; // 替换为应用专用密码
// $this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // 使用 TLS
$this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // SSL 加密
// $this->mailer->Port = 587;
+4 -4
View File
@@ -15,10 +15,10 @@ class OssService
public function __construct()
{
$this->accessKeyId = 'LTAI5tAGiH7bkVkmrniXnfkA';
$this->accessKeySecret = 'nqklJBft6t3S0A4ZvxF4ci9ni91kmm';
$this->bucket = 'vehicle-album';
$this->endpoint = 'https://oss-cn-beijing.aliyuncs.com';
$this->accessKeyId = getenv('OSS_ACCESSID');
$this->accessKeySecret = getenv('OSS_ACCESSSECRET');
$this->bucket = getenv('OSS_BUCKET');
$this->endpoint = getenv('OSS_ENDPOINT');
$this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
}
+63
View File
@@ -0,0 +1,63 @@
<?php
namespace app\service;
use app\model\User;
use app\model\UserSn;
use app\util\HttpClient;
class UserService
{
protected $domain;
public function __construct(){
$this->domain = config('const.rpc_domain');
}
/**
* 更新用户sn
* @param $sn
* @param $email
*/
public static function updateSn($sn, $email)
{
$user = User::first()
->where('email', $email)
->first();
if (!$user) {
return false;
}
if ($user->sn != $sn) {
UserSn::where(['sn' => $user->sn])->update(['user_id' => 0]);
UserSn::where(['sn' => $sn])->update(['user_id' => $user->id]);
$user->sn = $sn;
$user->save();
}
return $user;
}
/**
* 创建或查询用户
* @param array $data ['email'=>'','phone'=>'','company_tag'=>'','name'=>''];
* @return array
*/
public function createOrquery(array $data)
{
$result = HttpClient::post($this->domain . '/user/create/query', $data);
return $result;
}
/**
* 创建或查询用户
* @param array $data ['email'=>'','phone'=>'','company_tag'=>'','name'=>''];
* @return array
*/
public function update(array $data)
{
$result = HttpClient::post($this->domain . '/user/update', $data);
return $result;
}
}
+227
View File
@@ -0,0 +1,227 @@
<?php
namespace app\util;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
class HttpClient
{
/**
* @var Client Guzzle客户端实例
*/
private static $client;
/**
* 获取Guzzle客户端单例
* @return Client
*/
private static function getClient(): Client
{
if (!self::$client) {
self::$client = new Client([
'timeout' => 10, // 默认超时时间10秒
'verify' => false, // 不验证SSL证书(生产环境建议设为true)
'http_errors' => false, // 不抛出HTTP异常,自己处理
]);
}
return self::$client;
}
/**
* 发送GET请求
* @param string $url 请求地址
* @param array $query 查询参数
* @param array $headers 请求头
* @return array
*/
public static function get(string $url, array $query = [], array $headers = []): array
{
$options = [
'query' => $query,
'headers' => $headers
];
return self::request('GET', $url, $options);
}
/**
* 发送POST请求
* @param string $url 请求地址
* @param array|string $data 请求数据
* @param array $headers 请求头
* @param string $contentType 内容类型(form/json/xml)
* @return array
*/
public static function post(string $url, $data = [], array $headers = [], string $contentType = 'form'): array
{
$options = ['headers' => $headers];
switch ($contentType) {
case 'json':
$options['json'] = $data;
$options['headers']['Content-Type'] = 'application/json';
break;
/*case 'xml':
$options['body'] = is_array($data) ? self::arrayToXml($data) : $data;
$options['headers']['Content-Type'] = 'application/xml';
break;*/
default: // form
$options['form_params'] = $data;
$options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
}
return self::request('POST', $url, $options);
}
/**
* 发送PUT请求
* @param string $url 请求地址
* @param array|string $data 请求数据
* @param array $headers 请求头
* @return array
*/
public static function put(string $url, $data = [], array $headers = []): array
{
$options = [
'json' => $data,
'headers' => $headers
];
return self::request('PUT', $url, $options);
}
/**
* 发送DELETE请求
* @param string $url 请求地址
* @param array $data 请求数据
* @param array $headers 请求头
* @return array
*/
public static function delete(string $url, array $data = [], array $headers = []): array
{
$options = [
'json' => $data,
'headers' => $headers
];
return self::request('DELETE', $url, $options);
}
/**
* 发送HTTP请求
* @param string $method 请求方法
* @param string $url 请求地址
* @param array $options 请求选项
* @return array
*/
public static function request(string $method, string $url, array $options = []): array
{
try {
$response = self::getClient()->request($method, $url, $options);
return self::formatResponse($response);
} catch (GuzzleException $e) {
return [
'status' => false,
'code' => $e->getCode(),
'message' => $e->getMessage(),
'data' => null
];
}
}
/**
* 上传文件
* @param string $url 请求地址
* @param array $files 文件数组 [['name' => 'field_name', 'path' => 'file_path']]
* @param array $form 其他表单数据
* @param array $headers 请求头
* @return array
*/
public static function upload(string $url, array $files, array $form = [], array $headers = []): array
{
$multipart = [];
// 添加文件
foreach ($files as $file) {
if (file_exists($file['path'])) {
$multipart[] = [
'name' => $file['name'],
'contents' => fopen($file['path'], 'r'),
'filename' => basename($file['path'])
];
}
}
// 添加其他表单数据
foreach ($form as $name => $value) {
$multipart[] = [
'name' => $name,
'contents' => $value
];
}
$options = [
'multipart' => $multipart,
'headers' => $headers
];
return self::request('POST', $url, $options);
}
/**
* 格式化响应
* @param ResponseInterface $response
* @return array
*/
private static function formatResponse(ResponseInterface $response): array
{
$contents = $response->getBody()->getContents();
$contentType = $response->getHeaderLine('Content-Type');
$data = $contents;
if (strpos($contentType, 'application/json') !== false) {
$data = json_decode($contents, true) ?? $contents;
}
return [
'status' => $response->getStatusCode() === 200,
'code' => $response->getStatusCode(),
'message' => $response->getReasonPhrase(),
'data' => $data,
'headers' => $response->getHeaders()
];
}
/**
* 数组转XML
* @param array $data
* @param string $rootNode
* @return string
*/
private static function arrayToXml(array $data, string $rootNode = 'root'): string
{
$xml = new \SimpleXMLElement('<' . $rootNode . '/>');
self::addDataToXml($xml, $data);
return $xml->asXML();
}
/**
* 递归添加数据到XML
* @param \SimpleXMLElement $xml
* @param array $data
*/
private static function addDataToXml(\SimpleXMLElement $xml, array $data)
{
foreach ($data as $key => $value) {
if (is_array($value)) {
if (is_numeric($key)) {
$key = 'item';
}
$subNode = $xml->addChild($key);
self::addDataToXml($subNode, $value);
} else {
$xml->addChild($key, htmlspecialchars($value));
}
}
}
}
+171
View File
@@ -0,0 +1,171 @@
<?php
namespace app\util;
use support\Redis;
use support\Log;
class RedisHelper
{
/**
* 存储数据(自动序列化数组)
* @param string $key 键名
* @param mixed $value 值
* @param int|null $ttl 过期时间(秒)
* @return bool
*/
public static function set(string $key, $value, ?int $ttl = null): bool
{
try {
$storageValue = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value;
if ($ttl !== null) {
return Redis::setex($key, $ttl, $storageValue);
}
return Redis::set($key, $storageValue);
} catch (\Throwable $e) {
Log::error("Redis存储失败: {$e->getMessage()}", ['key' => $key]);
return false;
}
}
/**
* 获取数据(自动反序列化数组)
* @param string $key 键名
* @param mixed $default 默认值
* @return mixed
*/
public static function get(string $key, $default = null)
{
try {
$value = Redis::get($key);
if ($value === false || $value === null) {
return $default;
}
// 尝试JSON解码
$decoded = json_decode($value, true);
return json_last_error() === JSON_ERROR_NONE ? $decoded : $value;
} catch (\Throwable $e) {
Log::error("Redis读取失败: {$e->getMessage()}", ['key' => $key]);
return $default;
}
}
/**
* 删除键
* @param string|array $keys 键名或键名数组
* @return int 删除的键数量
*/
public static function del($keys): int
{
try {
return Redis::del(...(array)$keys);
} catch (\Throwable $e) {
Log::error("Redis删除失败: {$e->getMessage()}", ['keys' => $keys]);
return 0;
}
}
/**
* 检查键是否存在
* @param string $key 键名
* @return bool
*/
public static function exists(string $key): bool
{
try {
return (bool)Redis::exists($key);
} catch (\Throwable $e) {
Log::error("Redis检查存在失败: {$e->getMessage()}", ['key' => $key]);
return false;
}
}
/**
* 设置带过期时间的缓存
* @param string $key 键名
* @param mixed $value 值
* @param int $ttl 过期时间(秒)
* @return bool
*/
public static function setex(string $key, $value, int $ttl): bool
{
return self::set($key, $value, $ttl);
}
/**
* 哈希表设置字段值
* @param string $key 键名
* @param string $field 字段名
* @param mixed $value 值
* @return bool
*/
public static function hSet(string $key, string $field, $value): bool
{
try {
$storageValue = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value;
return Redis::hSet($key, $field, $storageValue);
} catch (\Throwable $e) {
Log::error("Redis哈希设置失败: {$e->getMessage()}", ['key' => $key, 'field' => $field]);
return false;
}
}
/**
* 哈希表获取字段值
* @param string $key 键名
* @param string $field 字段名
* @param mixed $default 默认值
* @return mixed
*/
public static function hGet(string $key, string $field, $default = null)
{
try {
$value = Redis::hGet($key, $field);
if ($value === false) {
return $default;
}
$decoded = json_decode($value, true);
return json_last_error() === JSON_ERROR_NONE ? $decoded : $value;
} catch (\Throwable $e) {
Log::error("Redis哈希获取失败: {$e->getMessage()}", ['key' => $key, 'field' => $field]);
return $default;
}
}
/**
* 自增计数器
* @param string $key 键名
* @param int $increment 增量
* @return int|false
*/
public static function incr(string $key, int $increment = 1)
{
try {
return $increment === 1
? Redis::incr($key)
: Redis::incrBy($key, $increment);
} catch (\Throwable $e) {
Log::error("Redis自增失败: {$e->getMessage()}", ['key' => $key]);
return false;
}
}
/**
* 获取剩余过期时间
* @param string $key 键名
* @return int 剩余秒数(-2表示键不存在,-1表示没有设置过期时间)
*/
public static function ttl(string $key): int
{
try {
return Redis::ttl($key);
} catch (\Throwable $e) {
Log::error("Redis获取TTL失败: {$e->getMessage()}", ['key' => $key]);
return -2;
}
}
}
+21
View File
@@ -105,4 +105,25 @@ class Util
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;
}
public static function mask($str)
{
if(empty($str)){
return '';
}
return substr($str, 0, 3) . '****' . substr($str, -4);
}
}
+3 -4
View File
@@ -43,7 +43,7 @@
<body>
<div class="container">
<h1>隐私协议</h1>
<p><strong>生效日期:</strong>[2025-03]</p>
<p><strong>生效日期:</strong>[2024-06]</p>
<h2>一、引言</h2>
<p>欢迎使用 [领客](以下简称“本应用”)。我们非常重视您的隐私保护,并致力于通过本隐私协议(以下简称“本协议”)向您说明我们如何收集、使用、存储和保护您的个人信息。请您在使用本应用前仔细阅读并理解本协议。</p>
@@ -92,13 +92,12 @@
<h2>八、联系我们</h2>
<p>如您对本协议或隐私保护有任何疑问,请联系我们:</p>
<ul>
<li>邮箱:[app@hnxinyouhe.com]</li>
<li>电话:[18137110386]</li>
<li>公司:[河南新友合科技有限公司]</li>
<li>公司:[河南晋海科技环保有限公司]</li>
</ul>
<div class="footer">
<p>© 2025 河南新友合科技有限公司. 保留所有权利。</p>
<p>© 2024 河南新友合科技环保有限公司. 保留所有权利。</p>
</div>
</div>
</body>
+3 -3
View File
@@ -43,10 +43,10 @@
<body>
<div class="container">
<h1>用户协议</h1>
<p><strong>生效日期:</strong>[2025-03]</p>
<p><strong>生效日期:</strong>[2024-06]</p>
<h2>一、总则</h2>
<p>1. 欢迎使用 [领客](以下简称“本应用”)。本应用由 [河南新友合科技有限公司](以下简称“我们”或“本公司”)提供。</p>
<p>1. 欢迎使用 [领客](以下简称“本应用”)。本应用由 [河南晋海科技环保有限公司](以下简称“我们”或“本公司”)提供。</p>
<p>2. 在注册或使用本应用前,请仔细阅读本《用户协议》(以下简称“本协议”)。您一旦注册、登录或使用本应用,即表示您已充分阅读、理解并同意接受本协议的全部条款。</p>
<h2>二、服务内容</h2>
@@ -90,7 +90,7 @@
<p>2. 如因本协议产生争议,双方应友好协商解决;协商不成的,任何一方可向 管辖地 有管辖权的人民法院提起诉讼。</p>
<div class="footer">
<p>© 2025 河南新友合科技有限公司. 保留所有权利。</p>
<p>© 2024 河南新友合科技有限公司. 保留所有权利。</p>
</div>
</div>
</body>
+3 -3
View File
@@ -36,12 +36,12 @@
"firebase/php-jwt": "^6.11",
"illuminate/database": "^11.44",
"phpmailer/phpmailer": "^6.9",
"shopwwi/webman-filesystem": "^2.0",
"iidestiny/flysystem-oss": "^4",
"vlucas/phpdotenv": "^5.6",
"guzzlehttp/guzzle": "^7.9",
"webman/cache": "^2.1",
"workerman/crontab": "^1.0"
"workerman/crontab": "^1.0",
"shopwwi/webman-filesystem": "1.1",
"shopwwi/filesystem-oss": "^1.0"
},
"suggest": {
"ext-event": "For better performance. "
Generated
+1403 -327
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
<?php
return [
'rpc_domain' => getenv('RPC_DOMAIN'),
];
+52 -3
View File
@@ -19,17 +19,44 @@ class Constants
self::CUSTOMER_GRADE_SALES => '售后阶段',
self::CUSTOMER_GRADE_LOSS => '停滞或流失',
];
public const GRADE_EN = [
self::CUSTOMER_GRADE_INITIAL => 'Initial contact',
self::CUSTOMER_GRADE_COMMUNICATE => 'Demand Chat',
self::CUSTOMER_GRADE_PLAN => 'promotion of the plan',
self::CUSTOMER_GRADE_DEAL => 'Transaction Stage',
self::CUSTOMER_GRADE_SALES => 'After Sales',
self::CUSTOMER_GRADE_LOSS => 'Stagnation or loss',
];
public const GRADE_RU = [
self::CUSTOMER_GRADE_INITIAL => 'Первоначальные контакты',
self::CUSTOMER_GRADE_COMMUNICATE => 'Потребности в общении',
self::CUSTOMER_GRADE_PLAN => 'Продвижение программы',
self::CUSTOMER_GRADE_DEAL => 'Этап сделки',
self::CUSTOMER_GRADE_SALES => 'Послепродажный этап',
self::CUSTOMER_GRADE_LOSS => 'Застой или потеря',
];
//客户重要性
public const CUSTOMER_MAGNITUDE_INITIAL = 0; // 金牌商机
public const CUSTOMER_MAGNITUDE_COMMUNICATE = 1; // 银牌商机
public const CUSTOMER_MAGNITUDE_PLAN = 2; // 铜牌商机
public const CUSTOMER_MAGNITUDE_INITIAL = 1; // 金牌商机
public const CUSTOMER_MAGNITUDE_COMMUNICATE = 2; // 银牌商机
public const CUSTOMER_MAGNITUDE_PLAN = 3; // 铜牌商机
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 => 'Бронзовый бизнес.',
];
//跟进类型
@@ -40,6 +67,10 @@ class Constants
self::CUSTOMER_FOLLOW_VISIT => '线下拜访',
self::CUSTOMER_FOLLOW_UP => '线上跟进',
];
public const FOLLOW_EN = [
self::CUSTOMER_FOLLOW_VISIT => 'Visit',
self::CUSTOMER_FOLLOW_UP => 'On line',
];
//跟进类型
public const CUSTOMER_SEX_UNKNOWN = 0; // 未知
@@ -51,4 +82,22 @@ class Constants
self::CUSTOMER_SEX_MAN => '男',
self::CUSTOMER_SEX_WOMAN => '女',
];
public const SEX_EN = [
self::CUSTOMER_SEX_UNKNOWN => 'unknown',
self::CUSTOMER_SEX_MAN => 'man',
self::CUSTOMER_SEX_WOMAN => 'woman',
];
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'];
}
+2 -2
View File
@@ -13,8 +13,8 @@ return [
'username' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'unix_socket' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
+2 -2
View File
@@ -4,7 +4,7 @@ return [
'xinyouhe' => [
'appId' => "cli_a73e1e6406fa501c",
'appSecret' => "9cMfxujjGG9JPmNfNcOwUdCoIXqaM1wY",
'rUrl' => "http://219.157.255.213:25321/feishu/auth",
'rUrl' => "http://219.157.255.213:8085/pages/index/webview",
'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot",
'state' => "xinyouhe",
'baseUri' => "https://open.feishu.cn/open-apis/"
@@ -12,7 +12,7 @@ return [
'mbaf' => [
'appId' => "cli_a75839fb4ff85028",
'appSecret' => "VsqLvwsRzpmisBVbrTIuKdNCvRCO447d",
'rUrl' => "http://219.157.255.213:25321/feishu/auth",
'rUrl' => "http://219.157.255.213:8085/pages/index/webview",
'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot",
'state' => "mbaf",
'baseUri' => "https://open.larksuite.com/open-apis/"
+23 -13
View File
@@ -1,4 +1,17 @@
<?php
/**
*-------------------------------------------------------------------------p*
* 配置文件
*-------------------------------------------------------------------------h*
* @copyright Copyright (c) 2015-2022 Shopwwi Inc. (http://www.shopwwi.com)
*-------------------------------------------------------------------------c*
* @license http://www.shopwwi.com s h o p w w i . c o m
*-------------------------------------------------------------------------e*
* @link http://www.shopwwi.com by 象讯科技 phcent.com
*-------------------------------------------------------------------------n*
* @since shopwwi象讯·PHP商城系统Pro
*-------------------------------------------------------------------------t*
*/
return [
'enable' => true,
@@ -64,21 +77,18 @@ return [
],
'oss' => [
'driver' => \Shopwwi\WebmanFilesystem\Adapter\AliyunOssAdapterFactory::class,
// 'accessId' => 'OSS_ACCESS_ID',
// 'accessSecret' => 'OSS_ACCESS_SECRET',
// 'bucket' => 'OSS_BUCKET',
// 'endpoint' => 'OSS_ENDPOINT',
// 'url' => '', // 静态文件访问域名
'accessKey' => 'LTAI5tAGiH7bkVkmrniXnfkA',
'secretKey' => 'nqklJBft6t3S0A4ZvxF4ci9ni91kmm',
'bucket' => 'vehicle-album',
'endpoint' => 'https://oss-cn-beijing.aliyuncs.com',
'url' => '', // 静态文件访问域名
// 'accessKey' => getenv('OSS_ACCESSID'),
// 'secretKey' => getenv('OSS_ACCESSSECRET'),
// 'bucket' => getenv('OSS_BUCKET'),
// 'endpoint' => getenv('OSS_ENDPOINT'),
'accessId' => getenv('OSS_ACCESSID'),
'accessSecret' => getenv('OSS_ACCESSSECRET'),
'bucket' => getenv('OSS_BUCKET'),
'endpoint' => getenv('OSS_ENDPOINT'),
'url' => '' // 静态文件访问域名
// 'timeout' => 3600,
// 'connectTimeout' => 10,
'isCName' => false,
'prefix' => '',
// 'isCName' => false,
// 'token' => null,
// 'proxy' => null,
],
+2 -2
View File
@@ -22,7 +22,7 @@ return [
'webman' => [
'handler' => Http::class,
'listen' => getenv('WEBMAN_LISTEN'),
'count' => cpu_count() * 4,
'count' => getenv('WEBMAN_COUNT'),
'user' => '',
'group' => '',
'reusePort' => false,
@@ -60,6 +60,6 @@ return [
]
],
'task' => [
'handler' => process\Task::class
'handler' => app\process\Task::class
],
];
+10
View File
@@ -6,10 +6,13 @@ return [
'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',
@@ -19,8 +22,15 @@ return [
'param_error' => ' param error',
'required_not_null' => ' required not_ ull',
'picture_not_null' => ' picture not null',
'follow_not_null' => ' The image and follow-up content cannot be empty at the same time',
'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 8 characters',
'id_empty' => ' ID cannot be empty',
'customer_id' => ' customer ID',
'tag_group_id' => ' tag group ID',
'claim_fail' => ' Cannot claim ownership of customers',
];
+36
View File
@@ -0,0 +1,36 @@
<?php
return [
'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' => ' Фотографии не могут быть пустыми',
'follow_not_null' => ' Изображение и последующий контент не могут быть пустыми одновременно.X',
'contacts_not_null' => ' Контакты, почтовый ящик, телефон не может быть одновременно пустым',
'car_type_not_null' => ' Предпочтения не могут быть пустыми',
'channel_not_null' => ' Каналы не могут быть пустыми',
'email_consistent' => ' Почтовый ящик не совпадает',
'sign_not_null' => ' Компания не создана',
'password_short' => ' Пароль не может быть меньше 8.',
'id_empty' => ' ID не может быть пустым',
'customer_id' => ' Идентификатор клиента',
'tag_group_id' => ' Идентификатор группы меток',
'claim_fail' => ' Невозможность получения принадлежащего клиенту',
];
+10
View File
@@ -6,10 +6,13 @@ return [
'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' => ' 注册成功',
@@ -19,8 +22,15 @@ return [
'param_error' => ' 参数错误',
'required_not_null' => ' 必填项不能为空',
'picture_not_null' => ' 图片不能为空',
'follow_not_null' => ' 图片与跟进内容不能同时为空',
'contacts_not_null' => ' 联系人,邮箱,电话不能同时为空',
'car_type_not_null' => ' 偏好不能为空',
'channel_not_null' => ' 渠道不能为空',
'email_consistent' => ' 邮箱不一致',
'sign_not_null' => ' 未设置所属公司',
'password_short' => ' 密码不能少于8位',
'id_empty' => ' id不能为空',
'customer_id' => ' 客户ID',
'tag_group_id' => ' 标签组ID',
'claim_fail' => ' 不能领取有归属客户',
];
File diff suppressed because it is too large Load Diff