Merge branch 'develop' into feature/crmAdmin0717
This commit is contained in:
@@ -53,14 +53,14 @@ class PermLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单 component 处理
|
||||
* 构建目录/菜单树
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $resources 全部资源集合
|
||||
* @param int $parentId 当前父级资源 ID
|
||||
* @param string $parentPath 父级完整路径(用于递归)
|
||||
* @return array
|
||||
*/
|
||||
public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
@@ -124,25 +124,16 @@ class PermLogic
|
||||
'keepAlive' => true,
|
||||
'authList' => $authList,
|
||||
'openType' => $node->open_type,
|
||||
'isHide' => $node->is_hide == 0 ? false : true,
|
||||
'isHideTab' => $node->is_hide_tab == 0 ? false : true
|
||||
],
|
||||
'children' => $children,
|
||||
'is_hide' => $node->is_hide,
|
||||
'is_hide_tab' => $node->is_hide_tab
|
||||
'children' => $children
|
||||
];
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单 component 处理
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $resources 全部资源集合
|
||||
* @param int $parentId 当前父级资源 ID
|
||||
* @param string $parentPath 父级完整路径(用于递归)
|
||||
* @return array
|
||||
*/
|
||||
public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
public function buildTree_bak2($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
@@ -166,7 +157,7 @@ class PermLogic
|
||||
|
||||
// —— 递归构建子节点 ——
|
||||
$children = [];
|
||||
if (in_array($node->type, ['directory', 'menu'])) {
|
||||
if ($node->type === 'directory') {
|
||||
$children = $this->buildTree($resources, $node->id, $currentPath);
|
||||
}
|
||||
|
||||
@@ -214,7 +205,64 @@ class PermLogic
|
||||
|
||||
return $tree;
|
||||
}
|
||||
public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
{
|
||||
$tree = [];
|
||||
foreach ($resources as $node) {
|
||||
if ($node->parent_id !== $parentId) continue;
|
||||
|
||||
// 拼接完整路径
|
||||
$currentPath = $parentPath;
|
||||
if ($currentPath && substr($currentPath, -1) === '/') {
|
||||
$currentPath = rtrim($currentPath, '/');
|
||||
}
|
||||
if (!empty($node->url)) {
|
||||
if (!$currentPath) {
|
||||
$currentPath = $node->url;
|
||||
} else {
|
||||
$url = ltrim($node->url, '/');
|
||||
$currentPath = $currentPath . '/' . $url;
|
||||
}
|
||||
}
|
||||
|
||||
// 子节点递归
|
||||
$children = [];
|
||||
if ($node->type === 'directory') {
|
||||
$children = $this->buildTree($resources, $node->id, $currentPath);
|
||||
}
|
||||
|
||||
// 权限
|
||||
$authList = $resources
|
||||
->filter(fn($r) => $r->type === 'permission' && $r->parent_id === $node->id)
|
||||
->map(fn($r) => [
|
||||
'id' => $r->id,
|
||||
'title' => $r->name,
|
||||
'auth_mark' => $r->code,
|
||||
])->values()->all();
|
||||
|
||||
// 判断是否有子级菜单(非权限)
|
||||
$hasChildrenMenu = collect($resources)->where('parent_id', $node->id)
|
||||
->whereIn('type', ['directory', 'menu'])->isNotEmpty();
|
||||
|
||||
$componentValue = $hasChildrenMenu ? '/index/index' : $currentPath;
|
||||
|
||||
$tree[] = [
|
||||
'id' => $node->id,
|
||||
'name' => $node->name,
|
||||
'path' => $node->url,
|
||||
'component' => $componentValue,
|
||||
'meta' => [
|
||||
'title' => $node->name,
|
||||
'icon' => $node->icon,
|
||||
'keepAlive' => true,
|
||||
'authList' => $authList,
|
||||
'openType' => $node->open_type,
|
||||
],
|
||||
'children' => $children,
|
||||
];
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户所有权限code
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
class Country extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'mysql';
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'country';
|
||||
|
||||
/**
|
||||
* 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', 'cn_addr', 'en_addr', 'en_full_name', 'two_letter', 'three_letter', 'num_code', 'steering', 'c_time', 'u_time'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
use app\common\model\User;
|
||||
use app\common\model\Country;
|
||||
|
||||
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 recipient()
|
||||
{
|
||||
return $this->hasOne(User::class, 'id', 'recipient');
|
||||
}
|
||||
|
||||
// public function enter()
|
||||
// {
|
||||
// return $this->belongsTo(User::class, 'enter_user_id');
|
||||
// }
|
||||
|
||||
// public function recipient()
|
||||
// {
|
||||
// return $this->belongsTo(User::class, 'recipient');
|
||||
// }
|
||||
|
||||
public function country()
|
||||
{
|
||||
return $this->hasOne(Country::class, 'id', 'country');
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ trait CrudControllerTrait
|
||||
? [$this, 'indexFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ trait CrudControllerTrait
|
||||
? [$this, 'showFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ trait CrudControllerTrait
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'store');
|
||||
$res = $this->service->serviceStore($request, $data);
|
||||
return $this->success($res, '创建成功');
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ trait CrudControllerTrait
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'update');
|
||||
$res = $this->service->serviceUpdate($request, $data);
|
||||
return $this->success([], '更新成功');
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ trait CrudControllerTrait
|
||||
try {
|
||||
$count = $this->service->serviceDestroy($request);
|
||||
return $this->success([], "成功删除了 {$count} 条");
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+132
-107
@@ -24,6 +24,7 @@ use support\exception\BusinessException;
|
||||
|
||||
class CrudUtil
|
||||
{
|
||||
|
||||
/**
|
||||
* 构建查询,支持:
|
||||
* - 本表字段过滤 where
|
||||
@@ -56,48 +57,62 @@ class CrudUtil
|
||||
$model = new $config['model'];
|
||||
$q = $model->newQuery();
|
||||
|
||||
// 1. eager load
|
||||
if (!empty($config['with'])) {
|
||||
$q->with($config['with']);
|
||||
}
|
||||
|
||||
// 2. 关联表字段选择
|
||||
if (!empty($config['withFields'])) {
|
||||
foreach ($config['withFields'] as $rel => $fields) {
|
||||
$q->with([$rel => function ($qr) use ($fields) {
|
||||
$fk = $qr->getModel()->getForeignKey();
|
||||
$qr->select(array_unique(array_merge($fields, [$fk])));
|
||||
}]);
|
||||
// eager-load:支持 ['rel','rel2'] 和 ['rel'=>fields[], ...]
|
||||
if (! empty($config['with'])) {
|
||||
foreach ($config['with'] as $rel => $fields) {
|
||||
if (is_int($rel)) {
|
||||
// 普通关联
|
||||
$q->with($fields);
|
||||
} else {
|
||||
// 带字段筛选的关联
|
||||
$q->with([$rel => function ($qr) use ($fields) {
|
||||
$key = $qr->getModel()->getKeyName();
|
||||
if (! in_array($key, $fields, true)) {
|
||||
$fields[] = $key;
|
||||
}
|
||||
$qr->select($fields);
|
||||
}]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 本表字段选择
|
||||
// 表字段
|
||||
if (!empty($config['fields'])) {
|
||||
$q->select($config['fields']);
|
||||
}
|
||||
|
||||
// 4. where 条件(支持 dot-notation 关联过滤)
|
||||
// where
|
||||
if (!empty($config['where'])) {
|
||||
foreach ($config['where'] as $col => $val) {
|
||||
if (strpos($col, '.') !== false) {
|
||||
[$rel, $relCol] = explode('.', $col, 2);
|
||||
$q->whereHas($rel, function ($qr) use ($relCol, $val) {
|
||||
self::applyWhere($qr, $relCol, $val);
|
||||
});
|
||||
// 多层支持
|
||||
$segments = explode('.', $col);
|
||||
$leaf = array_pop($segments);
|
||||
self::applyNestedWhere($q, $segments, $leaf, $val);
|
||||
} else {
|
||||
self::applyWhere($q, $col, $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 排序
|
||||
// or where
|
||||
if (!empty($config['orWhere'])) {
|
||||
$q->where(function($q) use($config) {
|
||||
foreach ($config['orWhere'] as $cond) {
|
||||
[$col,$op,$val] = $cond;
|
||||
$q->orWhere($col,$op,$val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 排序
|
||||
if (!empty($config['order'])) {
|
||||
foreach ($config['order'] as $col => $dir) {
|
||||
$q->orderBy($col, strtolower($dir) === 'asc' ? 'asc' : 'desc');
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 数据权限过滤
|
||||
// 数据权限过滤
|
||||
if (!empty($config['dataLimit'])) {
|
||||
self::applyDataLimit($q, $config['dataLimit']);
|
||||
}
|
||||
@@ -152,43 +167,22 @@ class CrudUtil
|
||||
* @return Model
|
||||
* @throws BusinessException
|
||||
*/
|
||||
// public static function findByPk(string $modelClass, $id, array $with = []): Model
|
||||
// {
|
||||
// $m = $modelClass::with($with)->find($id);
|
||||
// if (!$m) {
|
||||
// throw new BusinessException("记录 ID={$id} 不存在", 404);
|
||||
// }
|
||||
// return $m;
|
||||
// }
|
||||
public static function findByPk(string $modelClass, $id, array $with = []): Model
|
||||
{
|
||||
$m = $modelClass::with($with)->find($id);
|
||||
if (!$m) {
|
||||
throw new BusinessException("记录 ID={$id} 不存在", 404);
|
||||
}
|
||||
return $m;
|
||||
}
|
||||
|
||||
/**
|
||||
* 任意条件单条查询,支持 dataLimit
|
||||
*
|
||||
* @param string $modelClass
|
||||
* @param array $where
|
||||
* @param array $with
|
||||
* @param array $dataLimit
|
||||
* @param Builder $query
|
||||
* @return Model
|
||||
* @throws BusinessException
|
||||
*/
|
||||
// public static function findOneBy(
|
||||
// string $modelClass,
|
||||
// array $where,
|
||||
// array $with = [],
|
||||
// array $dataLimit = []
|
||||
// ): Model {
|
||||
// $config = compact('modelClass');
|
||||
// $config['model'] = $modelClass;
|
||||
// $config['where'] = $where;
|
||||
// $config['with'] = $with;
|
||||
// $config['dataLimit'] = $dataLimit;
|
||||
|
||||
// $m = self::buildQuery($config)->first();
|
||||
// if (!$m) {
|
||||
// throw new BusinessException("未找到符合条件的记录", 404);
|
||||
// }
|
||||
// return $m;
|
||||
// }
|
||||
public static function findOneBy(Builder $q): Model
|
||||
{
|
||||
return $q->first();
|
||||
@@ -225,43 +219,32 @@ class CrudUtil
|
||||
* @return Model
|
||||
* @throws BusinessException
|
||||
*/
|
||||
// public static function updateByPk(
|
||||
// string $modelClass,
|
||||
// $id,
|
||||
// array $data,
|
||||
// array $dataLimit = []
|
||||
// ): Model {
|
||||
// /** @var Model $m */
|
||||
// $m = $modelClass::find($id);
|
||||
// if (!$m) {
|
||||
// throw new BusinessException("记录 ID={$id} 不存在", 404);
|
||||
// }
|
||||
// // dataLimit 校验
|
||||
// if (!empty($dataLimit)) {
|
||||
// self::applyDataLimitOnMutate($m, $dataLimit, $data);
|
||||
// }
|
||||
// $m->fill($data)->save();
|
||||
// return $m;
|
||||
// }
|
||||
public static function updateByPk(
|
||||
string $modelClass,
|
||||
$id,
|
||||
array $data,
|
||||
array $dataLimit = []
|
||||
): Model {
|
||||
/** @var Model $m */
|
||||
$m = $modelClass::find($id);
|
||||
if (!$m) {
|
||||
throw new BusinessException("记录 ID={$id} 不存在", 404);
|
||||
}
|
||||
// dataLimit 校验
|
||||
if (!empty($dataLimit)) {
|
||||
self::applyDataLimitOnMutate($m, $dataLimit, $data);
|
||||
}
|
||||
$m->fill($data)->save();
|
||||
return $m;
|
||||
}
|
||||
|
||||
/**
|
||||
* 非主键条件更新(批量),支持 dataLimit
|
||||
*
|
||||
* @param string $modelClass
|
||||
* @param array $where
|
||||
* @param Builder $query
|
||||
* @param array $data
|
||||
* @param array $dataLimit
|
||||
* @return int 受影响行数
|
||||
*/
|
||||
// public static function updateBy(
|
||||
// string $modelClass,
|
||||
// array $where,
|
||||
// array $data,
|
||||
// array $dataLimit = []
|
||||
// ): int {
|
||||
// $config = ['model'=>$modelClass, 'where'=>$where, 'dataLimit'=>$dataLimit];
|
||||
// return self::buildQuery($config)->update($data);
|
||||
// }
|
||||
public static function updateBy(Builder $q, array $data): int
|
||||
{
|
||||
return $q->update($data);
|
||||
@@ -274,27 +257,17 @@ class CrudUtil
|
||||
* @param array $ids
|
||||
* @return int 删除条数
|
||||
*/
|
||||
// public static function deleteByPk(string $modelClass, array $ids): int
|
||||
// {
|
||||
// return $modelClass::destroy($ids);
|
||||
// }
|
||||
public static function deleteByPk(string $modelClass, array $ids): int
|
||||
{
|
||||
return $modelClass::destroy($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 非主键条件删除,支持 dataLimit
|
||||
*
|
||||
* @param string $modelClass
|
||||
* @param array $where
|
||||
* @param array $dataLimit
|
||||
* @param Builder $query
|
||||
* @return int 删除条数
|
||||
*/
|
||||
// public static function deleteBy(
|
||||
// string $modelClass,
|
||||
// array $where,
|
||||
// array $dataLimit = []
|
||||
// ): int {
|
||||
// $config = ['model'=>$modelClass, 'where'=>$where, 'dataLimit'=>$dataLimit];
|
||||
// return self::buildQuery($config)->delete();
|
||||
// }
|
||||
public static function deleteBy(Builder $q): int
|
||||
{
|
||||
return $q->delete();
|
||||
@@ -303,8 +276,29 @@ class CrudUtil
|
||||
|
||||
//=================== Internal Methods ===================//
|
||||
|
||||
|
||||
/**
|
||||
* 应用单字段 where 过滤
|
||||
* 支持多层的 whereHas:$relations=['roles','permissions'],$leaf='name'
|
||||
*/
|
||||
protected static function applyNestedWhere(Builder $q, array $relations, string $leaf, $val): void
|
||||
{
|
||||
$rel = array_shift($relations);
|
||||
$q->whereHas($rel, function (Builder $qr) use ($relations, $leaf, $val) {
|
||||
if ($relations) {
|
||||
// 还有更深层,继续递归
|
||||
self::applyNestedWhere($qr, $relations, $leaf, $val);
|
||||
} else {
|
||||
// 最后一层,使用普通 applyWhere
|
||||
self::applyWhere($qr, $leaf, $val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 单字段 where 支持:
|
||||
* - 多条件数组 [ [op1,val1], [op2,val2], … ]
|
||||
* - 单条件 ['op', val]
|
||||
* - 直接值
|
||||
*
|
||||
* @param Builder $q
|
||||
* @param string $col
|
||||
@@ -313,22 +307,53 @@ class CrudUtil
|
||||
*/
|
||||
protected static function applyWhere(Builder $q, string $col, $val): void
|
||||
{
|
||||
if (is_array($val) && count($val) === 2) {
|
||||
[$op, $v] = $val;
|
||||
switch (strtolower($op)) {
|
||||
case 'like': $q->where($col,'like',$v); break;
|
||||
case 'in': $q->whereIn($col,(array)$v); break;
|
||||
case 'not in': $q->whereNotIn($col,(array)$v); break;
|
||||
case 'null': $q->whereNull($col); break;
|
||||
case 'not null': $q->whereNotNull($col); break;
|
||||
case 'between': $q->whereBetween($col,(array)$v); break;
|
||||
default: $q->where($col,$op,$v);
|
||||
// 多条件数组
|
||||
if (is_array($val) && isset($val[0]) && is_array($val[0])) {
|
||||
foreach ($val as $pair) {
|
||||
if (is_array($pair) && count($pair) === 2) {
|
||||
self::applySingleWhere($q, $col, $pair[0], $pair[1]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
// 单条件
|
||||
elseif (is_array($val) && count($val) === 2) {
|
||||
self::applySingleWhere($q, $col, $val[0], $val[1]);
|
||||
}
|
||||
// 直接等值
|
||||
else {
|
||||
$q->where($col, $val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 真正执行一个条件的 where
|
||||
*/
|
||||
protected static function applySingleWhere(Builder $q, string $col, string $op, $v): void
|
||||
{
|
||||
switch (strtolower($op)) {
|
||||
case 'like':
|
||||
$q->where($col, 'like', $v);
|
||||
break;
|
||||
case 'in':
|
||||
$q->whereIn($col, (array)$v);
|
||||
break;
|
||||
case 'not in':
|
||||
$q->whereNotIn($col, (array)$v);
|
||||
break;
|
||||
case 'null':
|
||||
$q->whereNull($col);
|
||||
break;
|
||||
case 'not null':
|
||||
$q->whereNotNull($col);
|
||||
break;
|
||||
case 'between':
|
||||
$q->whereBetween($col, (array)$v);
|
||||
break;
|
||||
default:
|
||||
$q->where($col, $op, $v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用数据权限过滤到查询(buildQuery 场景)
|
||||
*/
|
||||
|
||||
@@ -26,11 +26,11 @@ class Generate
|
||||
|
||||
// 模板路径
|
||||
$templateDir = __DIR__ . '/templates/';
|
||||
$controllerPath = __DIR__ . "/../../../{$this->options['controller']['module']}/controller/".ucfirst($this->options['controller']['name'])."Controller.php";
|
||||
$servicePath = __DIR__ . "/../../../{$this->options['service']['module']}/service/".ucfirst($this->options['service']['name'])."Service.php";
|
||||
$logicPath = __DIR__ . "/../../../{$this->options['logic']['module']}/logic/".ucfirst($this->options['logic']['name'])."Logic.php";
|
||||
$modelPath = __DIR__ . "/../../../{$this->options['model']['module']}/model/".ucfirst($this->options['model']['name']).".php";
|
||||
$validatePath = __DIR__ . "/../../../{$this->options['validate']['module']}/validate/".ucfirst($this->options['validate']['name'])."Validate.php";
|
||||
$controllerPath = __DIR__ . "/../../../{$this->options['controller']['module']}/controller/".$this->rName($this->options['controller']['name'])."Controller.php";
|
||||
$servicePath = __DIR__ . "/../../../{$this->options['service']['module']}/service/".$this->rName($this->options['service']['name'])."Service.php";
|
||||
$logicPath = __DIR__ . "/../../../{$this->options['logic']['module']}/logic/".$this->rName($this->options['logic']['name'])."Logic.php";
|
||||
$modelPath = __DIR__ . "/../../../{$this->options['model']['module']}/model/".$this->rName($this->options['model']['name']).".php";
|
||||
$validatePath = __DIR__ . "/../../../{$this->options['validate']['module']}/validate/".$this->rName($this->options['validate']['name'])."Validate.php";
|
||||
|
||||
// 创建目录(如果不存在)
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['controller']['module']}/controller");
|
||||
@@ -86,32 +86,32 @@ class Generate
|
||||
case 'controller':
|
||||
$content = str_replace('{{controllerModule}}', $this->options['controller']['module'], $content);
|
||||
$content = str_replace('{{serviceModule}}', $this->options['service']['module'], $content);
|
||||
$content = str_replace('{{serviceName}}', ucfirst($this->options['service']['name']), $content);
|
||||
$content = str_replace('{{controllerName}}', ucfirst($this->options['controller']['name']), $content);
|
||||
$content = str_replace('{{serviceName}}', $this->rName($this->options['service']['name']), $content);
|
||||
$content = str_replace('{{controllerName}}', $this->rName($this->options['controller']['name']), $content);
|
||||
break;
|
||||
case 'service':
|
||||
$content = str_replace('{{serviceModule}}', $this->options['service']['module'], $content);
|
||||
$content = str_replace('{{validateModule}}', $this->options['validate']['module'], $content);
|
||||
$content = str_replace('{{validateName}}', ucfirst($this->options['validate']['name']), $content);
|
||||
$content = str_replace('{{validateName}}', $this->rName($this->options['validate']['name']), $content);
|
||||
$content = str_replace('{{modelModule}}', $this->options['model']['module'], $content);
|
||||
$content = str_replace('{{modelName}}', ucfirst($this->options['model']['name']), $content);
|
||||
$content = str_replace('{{serviceName}}', ucfirst($this->options['service']['name']), $content);
|
||||
$content = str_replace('{{modelName}}', $this->rName($this->options['model']['name']), $content);
|
||||
$content = str_replace('{{serviceName}}', $this->rName($this->options['service']['name']), $content);
|
||||
break;
|
||||
case 'logic':
|
||||
$content = str_replace('{{logicModule}}', $this->options['logic']['module'], $content);
|
||||
$content = str_replace('{{modelModule}}', $this->options['model']['module'], $content);
|
||||
$content = str_replace('{{modelName}}', ucfirst($this->options['model']['name']), $content);
|
||||
$content = str_replace('{{logicName}}', ucfirst($this->options['logic']['name']), $content);
|
||||
$content = str_replace('{{modelName}}', $this->rName($this->options['model']['name']), $content);
|
||||
$content = str_replace('{{logicName}}', $this->rName($this->options['logic']['name']), $content);
|
||||
break;
|
||||
case 'model':
|
||||
$content = str_replace('{{modelModule}}', $this->options['model']['module'], $content);
|
||||
$content = str_replace('{{modelName}}', ucfirst($this->options['model']['name']), $content);
|
||||
$content = str_replace('{{modelName}}', $this->rName($this->options['model']['name']), $content);
|
||||
$content = str_replace('{{table}}', $this->options['table'], $content);
|
||||
$content = str_replace('{{fillable}}', $this->fillableFields(), $content);
|
||||
break;
|
||||
case 'validate':
|
||||
$content = str_replace('{{validateModule}}', $this->options['validate']['module'], $content);
|
||||
$content = str_replace('{{validateName}}', ucfirst($this->options['validate']['name']), $content);
|
||||
$content = str_replace('{{validateName}}', $this->rName($this->options['validate']['name']), $content);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -153,6 +153,14 @@ class Generate
|
||||
echo "删除已存在文件: <comment>{$path}</comment> \n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置名称
|
||||
*/
|
||||
public function rName($name = '')
|
||||
{
|
||||
return ucfirst(camelize($name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class InquiryLogValidate extends Validate
|
||||
{
|
||||
// 规则
|
||||
protected $rule = [
|
||||
|
||||
];
|
||||
|
||||
// 提示
|
||||
protected $message = [
|
||||
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'store' => [
|
||||
|
||||
],
|
||||
|
||||
'update' => [
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -71,26 +71,26 @@ class IndexController
|
||||
{
|
||||
$options = [
|
||||
'controller' => [
|
||||
'module' => 'admin',
|
||||
'name' => 'systems'
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'model' => [
|
||||
'module' => 'common',
|
||||
'name' => 'systems'
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'service' => [
|
||||
'module' => 'admin',
|
||||
'name' => 'systems'
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'logic' => [
|
||||
'module' => 'common',
|
||||
'name' => 'systems'
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'validate' => [
|
||||
'module' => 'common',
|
||||
'name' => 'systems'
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'table' => 'systems'
|
||||
'table' => 'country'
|
||||
];
|
||||
|
||||
$result = (new Generate($options))->doGenerate();
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace app\inquiry\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\inquiry\service\CountryService;
|
||||
|
||||
class CountryController extends BaseController
|
||||
{
|
||||
use CrudControllerTrait;
|
||||
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new CountryService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,694 @@
|
||||
<?php
|
||||
namespace app\inquiry\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\inquiry\service\InquiryLogService;
|
||||
|
||||
class InquiryLogController extends BaseController
|
||||
{
|
||||
use CrudControllerTrait;
|
||||
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new InquiryLogService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
|
||||
|
||||
// 列表
|
||||
public function list(Request $request)
|
||||
{
|
||||
if ($request->method() == 'POST') {
|
||||
$data = $request->all();
|
||||
$limit = isset($data['limit']) && $data['limit'] ? $data['limit'] : 10;
|
||||
|
||||
// 状态
|
||||
$roleId = $request->user->role_id;
|
||||
$where = [];
|
||||
if (in_array($roleId, [RoleRulesModel::ALL_ROLE_ID, RoleRulesModel::KEFU_ROLE_ID])) {
|
||||
if (isset($data["status"]) && $data["status"] != "") {
|
||||
$where[] = [
|
||||
"status", "=", $data["status"]
|
||||
];
|
||||
} else {
|
||||
$where[] = [
|
||||
"status", ">", -1
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$where[] = [
|
||||
"status", "=", 1
|
||||
];
|
||||
}
|
||||
|
||||
// 检索渠道
|
||||
if (isset($data["channel"]) && $data["channel"]) {
|
||||
$where[] = [
|
||||
"log_type", "=", $data["channel"]
|
||||
];
|
||||
}
|
||||
|
||||
// 检索国家
|
||||
if (isset($data["country"]) && $data["country"]) {
|
||||
$where[] = [
|
||||
"log_country", "=", $data["country"]
|
||||
];
|
||||
}
|
||||
|
||||
// 检索时间
|
||||
if (isset($data["ld_time"]) && $data["ld_time"]) {
|
||||
$times = explode(' - ', $data["ld_time"]);
|
||||
$specificDayStart = trim($times[0]);
|
||||
$specificDayEnd = trim($times[1]);
|
||||
$where[] = [
|
||||
"c_time", ">", strtotime($specificDayStart)
|
||||
];
|
||||
$where[] = [
|
||||
"c_time", "<=", strtotime($specificDayEnd)
|
||||
];
|
||||
}
|
||||
|
||||
// 检查渠道(不取缓存中的值)
|
||||
// $channel = $request->user->channel;
|
||||
$uinfos = UsersModel::where('id', $request->user->uid)->first();
|
||||
$channel = $uinfos->channel;
|
||||
if ($channel) {
|
||||
$channel = explode(",", $channel);
|
||||
$InquiryLogModelModel = InquiryLogModel::where($where)->whereIn("log_type", $channel);
|
||||
} else {
|
||||
$InquiryLogModelModel = InquiryLogModel::where($where);
|
||||
}
|
||||
|
||||
// 关键字
|
||||
if (isset($data["kwd"]) && $data["kwd"] != "") {
|
||||
$InquiryLogModelModel->whereRaw("concat(`log_contact_type`,`log_contact_tel`,`log_contact_whatsapp`,`log_contacts`,`order_no`) like '%".$data['kwd']."%'");
|
||||
}
|
||||
|
||||
$list = $InquiryLogModelModel
|
||||
->with([
|
||||
"eUserInfo"=>function($query) {
|
||||
$query->where("id", ">", 0);
|
||||
}, "rUserInfo"=>function($query) {
|
||||
$query->where("id", ">", 0);
|
||||
}, "countryInfo"
|
||||
])
|
||||
->orderBy("id", "desc")
|
||||
->paginate($limit);
|
||||
|
||||
$configsModel = new ConfigsModel();
|
||||
$logLevel = $configsModel->getConfig("log_level");
|
||||
$countdown = (int)($configsModel->getConfig("score_countdown")) * 60;
|
||||
$inquiryChannelList = ChannelModel::all(['id', 'name']);
|
||||
$inquiryChannel = [];
|
||||
foreach ($inquiryChannelList as $key => $val) {
|
||||
$inquiryChannel[$val->id] = $val->name;
|
||||
}
|
||||
|
||||
$arr = [];
|
||||
foreach ($list->items() as $key => $val) {
|
||||
$expiry_time = $val->r_time + $countdown;
|
||||
$is_expiry = 0;
|
||||
$expiry_ts = 0;
|
||||
if ($expiry_time <= time()) {
|
||||
$is_expiry = 1;
|
||||
} else {
|
||||
$diff = $expiry_time - (int)time();
|
||||
$expiry_ts = $diff * 1000;
|
||||
}
|
||||
$rUinfo = "";
|
||||
if ($val->rUserInfo) {
|
||||
$rUinfo = $val->rUserInfo->name;
|
||||
}
|
||||
$eUinfo = "";
|
||||
if ($val->eUserInfo) {
|
||||
$eUinfo = $val->eUserInfo->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示联系方式条件:
|
||||
* 1.已跟单并且当前用户是接单人
|
||||
* 2.主权限
|
||||
* 3.当前用户是录单人
|
||||
*/
|
||||
if (
|
||||
($val->status == 2 && $request->user->uid == $val->recipient) ||
|
||||
($roleId == RoleRulesModel::ALL_ROLE_ID) ||
|
||||
($request->user->uid == $val->enter_user_id)
|
||||
) {
|
||||
$log_contact_type = $val->log_contact_type == "" ? " 无 " : $val->log_contact_type;
|
||||
$log_contact_tel = $val->log_contact_tel == "" ? " 无 " : $val->log_contact_tel;
|
||||
$log_contact_whatsapp = $val->log_contact_whatsapp == "" ? " 无 " : $val->log_contact_whatsapp;
|
||||
} else {
|
||||
$log_contact_type = "******";
|
||||
$log_contact_tel = "******";
|
||||
$log_contact_whatsapp = "******";
|
||||
}
|
||||
$arr[] = [
|
||||
"id" => $val->id,
|
||||
"order_no" => $val->order_no,
|
||||
"enter_user_id" => $val->enter_user_id,
|
||||
"recipient" => $val->recipient,
|
||||
"log_quality" => $val->log_quality,
|
||||
"log_quality_desc" => $logLevel[$val->log_quality],
|
||||
"log_quality_color" => InquiryLogModel::LEVEL_BUTTON_COLOR[$val->log_quality],
|
||||
"log_type" => $val->log_type,
|
||||
"log_type_desc" => $inquiryChannel[$val->log_type],
|
||||
"log_contact_type" => $log_contact_type,
|
||||
"log_contact_tel" => $log_contact_tel,
|
||||
"log_contact_whatsapp" => $log_contact_whatsapp,
|
||||
"log_country" => $val->countryInfo->cn_addr."(".$val->countryInfo->two_letter.")",
|
||||
"log_country_steering" => $val->countryInfo->steering,
|
||||
"log_contacts" => $val->log_contacts,
|
||||
"log_content" => $val->log_content,
|
||||
"e_time" => $val->status==1?date("Y-m-d H:i:s", $expiry_time):"",
|
||||
"status" => $val->status,
|
||||
"status_color" => InquiryLogModel::STATUS_BUTTON_COLOR[$val->status],
|
||||
"status_desc" => InquiryLogModel::STATUS[$val->status],
|
||||
"is_expiry" => $is_expiry,
|
||||
"expiry_ts" => $expiry_ts,
|
||||
"rUinfo" => $rUinfo,
|
||||
"eUinfo" => $eUinfo,
|
||||
"r_time" => $val->r_time?date("Y-m-d H:i:s", $val->r_time):"",
|
||||
"n_time" => date("Y-m-d H:i:s", time()),
|
||||
"c_time" => date("Y-m-d H:i:s", strtotime($val->c_time)),
|
||||
"u_time" => date("Y-m-d H:i:s", strtotime($val->u_time))
|
||||
];
|
||||
}
|
||||
$data = [
|
||||
'lastPage' => $list->lastPage(),
|
||||
'currentPage' => $list->currentPage(),
|
||||
'hasMorePages' => $list->hasMorePages(),
|
||||
'list' => $arr,
|
||||
'counts' => $list->total()
|
||||
];
|
||||
return $this->successResponse($data);
|
||||
}
|
||||
return view('inquiry-log/list');
|
||||
}
|
||||
|
||||
// 添加
|
||||
public function add(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$enterUserId = $request->user->uid;
|
||||
$data = $request->all();
|
||||
|
||||
if ($data["log_contact_type"]) {
|
||||
$check1 = InquiryLogModel::where("log_contact_type", trim($data["log_contact_type"]))->first();
|
||||
if ($check1 != NULL) {
|
||||
return $this->errorResponse('邮箱-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_tel"]) {
|
||||
$check2 = InquiryLogModel::where("log_contact_tel", trim($data["log_contact_tel"]))->first();
|
||||
if ($check2 != NULL) {
|
||||
return $this->errorResponse('电话-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_whatsapp"]) {
|
||||
$check3 = InquiryLogModel::where("log_contact_whatsapp", trim($data["log_contact_whatsapp"]))->first();
|
||||
if ($check3 != NULL) {
|
||||
return $this->errorResponse('whatsapp-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data["log_contact_type"] && !$data["log_contact_tel"] && !$data["log_contact_whatsapp"]) {
|
||||
$check4 = InquiryLogModel::where("log_contacts", trim($data["log_contacts"]))->where("log_country", $data["country"])->first();
|
||||
if ($check4 != NULL) {
|
||||
return $this->errorResponse('联系人已存在');
|
||||
}
|
||||
}
|
||||
|
||||
$model = new InquiryLogModel();
|
||||
$model->order_no = orderNum();
|
||||
$model->enter_user_id = $enterUserId;
|
||||
$model->recipient = 0;
|
||||
$model->log_type = $data["log_type"];
|
||||
$model->log_contact_type = trim($data["log_contact_type"]);
|
||||
$model->log_contact_tel = trim($data["log_contact_tel"]);
|
||||
$model->log_contact_whatsapp = trim($data["log_contact_whatsapp"]);
|
||||
$model->log_country = $data["country"];
|
||||
$model->log_contacts = $data["log_contacts"];
|
||||
$model->log_content = $data["log_content"];
|
||||
$model->log_quality = $data["log_quality"];
|
||||
$model->status = 0;
|
||||
if ($model->save()) {
|
||||
return $this->successResponse([], '添加成功');
|
||||
} else {
|
||||
return $this->errorResponse('添加失败,请重试');
|
||||
}
|
||||
}
|
||||
return view('inquiry-log/add');
|
||||
}
|
||||
|
||||
// 编辑
|
||||
public function edit(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$data = $request->all();
|
||||
$model = new InquiryLogModel();
|
||||
$info = $model->where("id", $data["id"])->first();
|
||||
|
||||
if ($data["log_contact_type"]) {
|
||||
$check1 = InquiryLogModel::where("log_contact_type", trim($data["log_contact_type"]))->first();
|
||||
if ($check1 != NULL && $check1->id != $data["id"]) {
|
||||
return $this->errorResponse('邮箱-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_tel"]) {
|
||||
$check2 = InquiryLogModel::where("log_contact_tel", trim($data["log_contact_tel"]))->first();
|
||||
if ($check2 != NULL && $check2->id != $data["id"]) {
|
||||
return $this->errorResponse('电话-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_whatsapp"]) {
|
||||
$check3 = InquiryLogModel::where("log_contact_whatsapp", trim($data["log_contact_whatsapp"]))->first();
|
||||
if ($check3 != NULL && $check3->id != $data["id"]) {
|
||||
return $this->errorResponse('whatsapp-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data["log_contact_type"] && !$data["log_contact_tel"] && !$data["log_contact_whatsapp"]) {
|
||||
$check4 = InquiryLogModel::where("log_contacts", trim($data["log_contacts"]))->where("log_country", $data["country"])->first();
|
||||
if ($check4 != NULL && $check4->id != $data["id"]) {
|
||||
return $this->errorResponse('联系人已存在');
|
||||
}
|
||||
}
|
||||
|
||||
$info->log_type = $data["log_type"];
|
||||
$info->log_contact_type = $data["log_contact_type"];
|
||||
$info->log_contact_tel = $data["log_contact_tel"];
|
||||
$info->log_contact_whatsapp = $data["log_contact_whatsapp"];
|
||||
$info->log_country = $data["country"];
|
||||
$info->log_contacts = $data["log_contacts"];
|
||||
$info->log_content = $data["log_content"];
|
||||
$info->log_quality = $data["log_quality"];
|
||||
if (!$info->save()) {
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
return $this->successResponse([], '操作成功');
|
||||
}
|
||||
return view('inquiry-log/edit');
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function del(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->post("id");
|
||||
$rst = InquiryLogModel::where("id", $id)->first();
|
||||
if (!$rst) {
|
||||
return $this->errorResponse('询单未找到');
|
||||
}
|
||||
if ($rst->enter_user_id != $request->user->uid) {
|
||||
return $this->errorResponse('只能删除自己录入的询单');
|
||||
}
|
||||
$res = InquiryLogModel::where("id", $id)->where("enter_user_id", $request->user->uid)->delete();
|
||||
if (!$res) {
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
fileLog('ID:'.$request->user->uid.' - 删除:询单ID:'.$id);
|
||||
return $this->successResponse([], '操作成功');
|
||||
}
|
||||
return $this->errorResponse('请求方式错误');
|
||||
}
|
||||
|
||||
// 单条信息
|
||||
public function info(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->all("id");
|
||||
$info = InquiryLogModel::where("id", $id)->first()->toArray();
|
||||
$list = CountryModel::all(["cn_addr", "two_letter", "id"]);
|
||||
$arr = [];
|
||||
foreach ($list as $vo) {
|
||||
$arr[] = [
|
||||
"value" => $vo->id,
|
||||
"name" => $vo->cn_addr."(".$vo->two_letter.")"
|
||||
];
|
||||
}
|
||||
$info["guojia"] = $arr;
|
||||
$info["guojia_id"] = [$info["log_country"]];
|
||||
|
||||
$configsModel = new ConfigsModel();
|
||||
// $data = $configsModel->getConfig("inquiry_channel");
|
||||
$inquiryChannelList = ChannelModel::all(['id', 'name']);
|
||||
$data = [];
|
||||
foreach ($inquiryChannelList as $key => $val) {
|
||||
$data[$val->id] = $val->name;
|
||||
}
|
||||
|
||||
$arr = [];
|
||||
foreach ($data as $ky => $vo) {
|
||||
$arr[] = [
|
||||
"id" => $ky,
|
||||
"name" => $vo
|
||||
];
|
||||
}
|
||||
$info["qudao"] = $arr;
|
||||
|
||||
$data1 = $configsModel->getConfig("log_level");
|
||||
$arr1 = [];
|
||||
foreach ($data1 as $ky => $vo) {
|
||||
$arr1[] = [
|
||||
"id" => $ky,
|
||||
"name" => $vo
|
||||
];
|
||||
}
|
||||
$info["dengji"] = $arr1;
|
||||
if (!$info) {
|
||||
return $this->errorResponse('查询失败,请重试');
|
||||
}
|
||||
$info["log_content"] = strTh($info["log_content"]);
|
||||
return $this->successResponse($info, 'success');
|
||||
}
|
||||
return $this->errorResponse('请求方式错误');
|
||||
}
|
||||
|
||||
// 立即发布
|
||||
public function release(Request $request)
|
||||
{
|
||||
try {
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->post("id");
|
||||
if (!in_array($request->user->role_id, [RoleRulesModel::ALL_ROLE_ID, RoleRulesModel::KEFU_ROLE_ID])) {
|
||||
return $this->errorResponse('无操作权限');
|
||||
}
|
||||
$info = InquiryLogModel::where("id", $id)->first();
|
||||
if (!$info) {
|
||||
return $this->errorResponse('询单信息未找到');
|
||||
}
|
||||
if ($info->status != 0) {
|
||||
return $this->errorResponse('状态异常,无法发布');
|
||||
}
|
||||
$info->r_time = time();
|
||||
$info->status = 1;
|
||||
if (!$info->save()) {
|
||||
return $this->errorResponse('发布失败,请重试');
|
||||
}
|
||||
|
||||
// 发送飞书群消息通知
|
||||
$data = ["order_id"=>$id];
|
||||
RedisQueueRedis::send("release", $data);
|
||||
// 发送飞书群消息通知
|
||||
|
||||
return $this->successResponse([], '发布成功');
|
||||
}
|
||||
return $this->errorResponse('电话-请求方式错误');
|
||||
} catch (\Throwable $th) {
|
||||
fileLog($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
return $this->errorResponse($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 立即跟单
|
||||
public function track(Request $request)
|
||||
{
|
||||
// Db::beginTransaction();
|
||||
try {
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->post("id");
|
||||
$uid = $request->user->uid;
|
||||
if (!in_array($request->user->role_id, [RoleRulesModel::ALL_ROLE_ID, RoleRulesModel::YEWU_ROLE_ID])) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('无操作权限');
|
||||
}
|
||||
$info = InquiryLogModel::where("id", $id)->first();
|
||||
if (!$info) {
|
||||
return $this->errorResponse('询单信息未找到');
|
||||
}
|
||||
if ($info->status != 1) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('状态异常,无法跟单');
|
||||
}
|
||||
// 更新询单
|
||||
$info->recipient = $uid;
|
||||
$info->t_time = time();
|
||||
$info->status = 2;
|
||||
// 记录跟单
|
||||
$model = new UserOrderModel();
|
||||
$model->uid = $request->user->uid;
|
||||
$model->log_id = $id;
|
||||
$model->score = (new InquiryLogModel())->score($info->log_quality, $info->r_time);
|
||||
if (!$info->save() || !$model->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
// Db::commit();
|
||||
|
||||
// // 发送飞书群消息通知
|
||||
$data1 = ["order_id"=>$id];
|
||||
RedisQueueRedis::send("track", $data1);
|
||||
// // 发送飞书群消息通知
|
||||
|
||||
// // 同步询单到crm
|
||||
$data2 = ["order_id"=>$id];
|
||||
RedisQueueRedis::send("inquiry-sync", $data2);
|
||||
// // 同步询单到crm
|
||||
|
||||
return $this->successResponse([], '跟单操作成功');
|
||||
} else {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('请求方式错误');
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
// Db::rollBack();
|
||||
fileLog($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
return $this->errorResponse($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 详情
|
||||
public function detail(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->all("id");
|
||||
$res = InquiryLogModel::where("id", $id)->first()->toArray();
|
||||
return $this->successResponse(["detail"=>$res["log_content"]], '操作成功');
|
||||
|
||||
}
|
||||
return view('inquiry-log/detail');
|
||||
}
|
||||
|
||||
// 客服分单给业务
|
||||
public function allocation(Request $request)
|
||||
{
|
||||
// Db::beginTransaction();
|
||||
try {
|
||||
if ($request->method() == "POST") {
|
||||
$data = $request->all();
|
||||
|
||||
$userInfo = UsersModel::where("id", $data["gd_user"])->first();
|
||||
if (!$userInfo) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('用户未找到');
|
||||
}
|
||||
|
||||
$model = new InquiryLogModel();
|
||||
$info = $model->where("id", $data["id"])->first();
|
||||
if (!$info) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('询单未找到');
|
||||
}
|
||||
|
||||
$uomodel = new UserOrderModel();
|
||||
$uoInfo = $uomodel->where("log_id", $data["id"])->first();
|
||||
if (!$uoInfo) {
|
||||
// 记录跟单
|
||||
$HsUserOrderModel = new UserOrderModel();
|
||||
$HsUserOrderModel->uid = $data["gd_user"];
|
||||
$HsUserOrderModel->log_id = $data["id"];
|
||||
$HsUserOrderModel->score = (new InquiryLogModel())->score($info->log_quality, $info->r_time);
|
||||
if (!$HsUserOrderModel->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('记录跟单操作失败,请重试');
|
||||
}
|
||||
} else {
|
||||
$uoInfo->uid = $data["gd_user"];
|
||||
if (!$uoInfo->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
if ($info->status != 2) {
|
||||
$info->t_time = time();
|
||||
$info->status = 2;
|
||||
}
|
||||
$info->recipient = $data["gd_user"];
|
||||
if (!$info->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
// Db::commit();
|
||||
|
||||
// 发送飞书群消息通知
|
||||
$data1 = ["order_id"=>$data["id"]];
|
||||
RedisQueueRedis::send("allocation", $data1);
|
||||
// 发送飞书群消息通知
|
||||
|
||||
// // 同步询单到crm
|
||||
$data2 = ["order_id"=>$data["id"]];
|
||||
RedisQueueRedis::send("inquiry-sync", $data2);
|
||||
// // 同步询单到crm
|
||||
|
||||
return $this->successResponse([], '操作成功');
|
||||
}
|
||||
return view('inquiry-log/allocation');
|
||||
} catch (\Throwable $th) {
|
||||
// Db::rollBack();
|
||||
fileLog($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
return $this->errorResponse($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
public function export(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$data = $request->all();
|
||||
|
||||
$where = [];
|
||||
if (isset($data['log_lusers']) && $data['log_lusers']) {
|
||||
$where[] = ['enter_user_id', '=', $data['log_lusers']];
|
||||
}
|
||||
if (isset($data['log_gusers']) && $data['log_gusers']) {
|
||||
$where[] = ['recipient', '=', $data['log_gusers']];
|
||||
}
|
||||
if (isset($data['log_country']) && $data['log_country']) {
|
||||
$where[] = ['log_country', '=', $data['log_country']];
|
||||
}
|
||||
if (isset($data['log_channel']) && $data['log_channel']) {
|
||||
$where[] = ['log_type', '=', $data['log_channel']];
|
||||
}
|
||||
if (isset($data['log_times']) && $data['log_times']) {
|
||||
$times = explode(' - ', $data["log_times"]);
|
||||
$specificDayStart = trim($times[0]);
|
||||
$specificDayEnd = trim($times[1]);
|
||||
$where[] = [
|
||||
"c_time", ">", strtotime($specificDayStart)
|
||||
];
|
||||
$where[] = [
|
||||
"c_time", "<=", strtotime($specificDayEnd)
|
||||
];
|
||||
}
|
||||
|
||||
// 查询
|
||||
$results = InquiryLogModel::with(['enterUser', 'recipientUser', 'country'])
|
||||
->where($where)
|
||||
->get()
|
||||
->map(function ($log) use($data) {
|
||||
$arr = [];
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['订单号'] = $log->order_no;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['录入人'] = $log->enterUser->name ?? null;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['接单人'] = $log->recipientUser->name ?? null;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['等级'] = $log->log_quality;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['邮箱'] = $log->log_contact_type;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['电话'] = $log->log_contact_tel;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['WhatsApp'] = $log->log_contact_whatsapp;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['联系人'] = $log->log_contacts;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['国家(中文)'] = $log->country->cn_addr ?? null;
|
||||
}
|
||||
if (isset($data['hsl_order_no']) && $data['hsl_order_no']) {
|
||||
$arr['国家(英文)'] = $log->country->en_full_name ?? null;
|
||||
}
|
||||
if (isset($data['hsl_r_time']) && $data['hsl_r_time']) {
|
||||
$arr['发单时间'] = $log->r_time ? date('Y-m-d H:i:s', $log->r_time) : null;
|
||||
}
|
||||
if (isset($data['hsl_t_time']) && $data['hsl_t_time']) {
|
||||
$arr['跟单时间'] = $log->t_time ? date('Y-m-d H:i:s', $log->t_time) : null;
|
||||
}
|
||||
return $arr;
|
||||
});
|
||||
// 创建一个新的 Spreadsheet 对象
|
||||
$spreadsheet = new Spreadsheet();
|
||||
// 设置当前活动的工作表
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
// 设置工作表的标题
|
||||
$sheet->setCellValue('A1', '订单号');
|
||||
$sheet->setCellValue('B1', '录入人');
|
||||
$sheet->setCellValue('C1', '接单人');
|
||||
$sheet->setCellValue('D1', '等级');
|
||||
$sheet->setCellValue('E1', '邮箱');
|
||||
$sheet->setCellValue('F1', '电话');
|
||||
$sheet->setCellValue('G1', 'WhatsApp');
|
||||
$sheet->setCellValue('H1', '联系人');
|
||||
$sheet->setCellValue('I1', '国家(中文)');
|
||||
$sheet->setCellValue('J1', '国家(英文)');
|
||||
$sheet->setCellValue('K1', '发单时间');
|
||||
$sheet->setCellValue('L1', '跟单时间');
|
||||
$data = $results->toArray();
|
||||
|
||||
// 将数据填充到工作表中
|
||||
$row = 2; // 从第2行开始填充
|
||||
foreach ($data as $item) {
|
||||
$sheet->setCellValue('A' . $row, $item['订单号']);
|
||||
$sheet->setCellValue('B' . $row, $item['录入人']);
|
||||
$sheet->setCellValue('C' . $row, $item['接单人']);
|
||||
|
||||
$sheet->setCellValue('D' . $row, $item['等级']);
|
||||
$sheet->setCellValue('E' . $row, $item['邮箱']);
|
||||
$sheet->setCellValue('F' . $row, $item['电话']);
|
||||
|
||||
$sheet->setCellValue('G' . $row, $item['WhatsApp']);
|
||||
$sheet->setCellValue('H' . $row, $item['联系人']);
|
||||
$sheet->setCellValue('I' . $row, $item['国家(中文)']);
|
||||
|
||||
$sheet->setCellValue('J' . $row, $item['国家(英文)']);
|
||||
$sheet->setCellValue('K' . $row, $item['发单时间']);
|
||||
$sheet->setCellValue('L' . $row, $item['跟单时间']);
|
||||
$row++;
|
||||
}
|
||||
|
||||
// 创建 Excel 文件的写入器
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
// 名称
|
||||
$fileName = $request->user->name.'_'.date('Ymd').'_'.uniqid().'.xlsx';
|
||||
// 路径
|
||||
$filePath = '/export/'.$fileName;
|
||||
// 将文件保存到本地
|
||||
$writer->save(public_path().$filePath);
|
||||
|
||||
return $this->successResponse(['url'=>$filePath, 'name'=>$fileName]);
|
||||
}
|
||||
return view('inquiry-log/export');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace app\inquiry\logic;
|
||||
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\inquiry\model\Country;
|
||||
|
||||
class CountryLogic
|
||||
{
|
||||
use CrudLogicTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = Country::class;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace app\inquiry\logic;
|
||||
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\common\model\InquiryLog;
|
||||
|
||||
class InquiryLogLogic
|
||||
{
|
||||
use CrudLogicTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = InquiryLog::class;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\inquiry\service;
|
||||
|
||||
use app\inquiry\validate\CountryValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\inquiry\model\Country;
|
||||
|
||||
class CountryService
|
||||
{
|
||||
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = Country::class;
|
||||
|
||||
/**
|
||||
* 验证器
|
||||
*/
|
||||
protected $validator = CountryValidate::class;
|
||||
|
||||
/**
|
||||
* 获取验证器
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return new $this->validator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace app\inquiry\service;
|
||||
|
||||
use app\common\validate\InquiryLogValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InquiryLog;
|
||||
use support\Request;
|
||||
|
||||
class InquiryLogService
|
||||
{
|
||||
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = InquiryLog::class;
|
||||
|
||||
/**
|
||||
* 验证器
|
||||
*/
|
||||
protected $validator = InquiryLogValidate::class;
|
||||
|
||||
/**
|
||||
* 获取验证器
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'index'): array
|
||||
{
|
||||
$p = $request->all();
|
||||
|
||||
$config = [];
|
||||
$config['model'] = $this->modelClass;
|
||||
switch ($scene) {
|
||||
case 'index':
|
||||
// 排序
|
||||
$config['order']['id'] = 'desc';
|
||||
|
||||
// 渠道
|
||||
if (isset($p['channel']) && $p['channel']) {
|
||||
$config['where']['channel'] = $p['channel'];
|
||||
}
|
||||
|
||||
// 国家
|
||||
if (isset($p['country']) && $p['country']) {
|
||||
$config['where']['country'] = $p['country'];
|
||||
}
|
||||
|
||||
// 时间
|
||||
if (isset($p['time']) && $p['time']) {
|
||||
// $time = explode(' - ', $p['time']);
|
||||
// $config['where']['created_at'] = [
|
||||
// ['>=', strtotime($time[0])],
|
||||
// ['<=', strtotime($time[1])],
|
||||
// ];
|
||||
$config['where']['created_at'] = [
|
||||
strtotime(explode(' - ', $p['time'])[0]),
|
||||
strtotime(explode(' - ', $p['time'])[1]),
|
||||
];
|
||||
}
|
||||
|
||||
// 状态
|
||||
if (isset($p['status']) && $p['status']) {
|
||||
$config['where']['status'] = $p['status'];
|
||||
}
|
||||
|
||||
// 关键字
|
||||
if (isset($p['keyword']) && $p['keyword']) {
|
||||
$k = '%' . $p['keyword'] . '%';
|
||||
foreach (['order_no','email','tel','whatsapp','contacts'] as $col) {
|
||||
$config['orWhere'][] = [$col, 'like', $k];
|
||||
}
|
||||
}
|
||||
|
||||
// 关联
|
||||
$config['with'][] = 'country';
|
||||
$config['with']['enter'][] = 'id';
|
||||
$config['with']['enter'][] = 'name';
|
||||
$config['with']['recipient'][] = 'id';
|
||||
$config['with']['recipient'][] = 'name';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
$config['where']['status'] = 1;
|
||||
break;
|
||||
case 'store':
|
||||
break;
|
||||
case 'update':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'destroy':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,15 @@ Route::group('/admin', function () {
|
||||
Route::any('/update', [app\admin\controller\CorpController::class, 'update']);
|
||||
Route::any('/destroy', [app\admin\controller\CorpController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// 询单
|
||||
Route::group('/inquiry', function () {
|
||||
Route::any('/list', [app\inquiry\controller\InquiryLogController::class, 'index']);
|
||||
// Route::any('/show', [app\admin\controller\CorpController::class, 'show']);
|
||||
// Route::any('/store', [app\admin\controller\CorpController::class, 'store']);
|
||||
// Route::any('/update', [app\admin\controller\CorpController::class, 'update']);
|
||||
// Route::any('/destroy', [app\admin\controller\CorpController::class, 'destroy']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user