Merge branch 'develop'
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\admin\service\CorpFeishuAppService;
|
||||
|
||||
class CorpFeishuAppController extends BaseController
|
||||
{
|
||||
use CrudControllerTrait;
|
||||
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new CorpFeishuAppService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @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,33 @@
|
||||
<?php
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\admin\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;
|
||||
// }
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace app\admin\controller;
|
||||
use app\common\controller\BaseController;
|
||||
use app\admin\service\RoleService;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use support\Request;
|
||||
|
||||
class RoleController extends BaseController
|
||||
{
|
||||
@@ -27,91 +28,16 @@ class RoleController extends BaseController
|
||||
return $data;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 获取角色列表
|
||||
// */
|
||||
// public function list(Request $request)
|
||||
// {
|
||||
// try {
|
||||
// $params = $request->all();
|
||||
// $result = (new RoleService())->getRoleList($params);
|
||||
// // 定义后处理器
|
||||
// $postProcessor = function($formattedData) {
|
||||
// if (isset($formattedData['created_at']))
|
||||
// $formattedData['created_at'] = date('Y-m-d H:i:s', $formattedData['created_at']);
|
||||
// if (isset($formattedData['updated_at']))
|
||||
// $formattedData['updated_at'] = date('Y-m-d H:i:s', $formattedData['updated_at']);
|
||||
// return $formattedData;
|
||||
// };
|
||||
// return $this->success($this->transformData($result, $postProcessor), '角色列表获取成功');
|
||||
// } catch (\Throwable $e) {
|
||||
// return $this->error($e->getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 获取角色详情
|
||||
// */
|
||||
// public function detail(Request $request)
|
||||
// {
|
||||
// try {
|
||||
// $roleId = $request->get('role_id');
|
||||
// if (!$roleId) {
|
||||
// return $this->error('缺少角色ID', 422);
|
||||
// }
|
||||
// $result = (new RoleService())->getRoleDetail($roleId);
|
||||
// return $this->success($result, '角色详情获取成功');
|
||||
// } catch (\Throwable $e) {
|
||||
// return $this->error($e->getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 增加角色
|
||||
// */
|
||||
// public function create(Request $request)
|
||||
// {
|
||||
// try {
|
||||
// $data = $this->validate(new RoleValidate(), $request->post(), 'role_create');
|
||||
// $result = (new RoleService())->createRole($data);
|
||||
// return $this->success($result, '角色创建成功');
|
||||
// } catch (\think\exception\ValidateException $e) {
|
||||
// return $this->error($e->getError(), 422);
|
||||
// } catch (\Throwable $e) {
|
||||
// return $this->error($e->getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 修改角色
|
||||
// */
|
||||
// public function update(Request $request)
|
||||
// {
|
||||
// try {
|
||||
// $data = $this->validate(new RoleValidate(), $request->post(), 'role_update');
|
||||
// $result = (new RoleService())->updateRole($data);
|
||||
// return $this->success($result, '角色更新成功');
|
||||
// } catch (\think\exception\ValidateException $e) {
|
||||
// return $this->error($e->getError(), 422);
|
||||
// } catch (\Throwable $e) {
|
||||
// return $this->error($e->getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 删除角色
|
||||
// */
|
||||
// public function delete(Request $request)
|
||||
// {
|
||||
// try {
|
||||
// $roleId = $request->get('role_id');
|
||||
// if (!$roleId) {
|
||||
// return $this->error('缺少角色ID', 422);
|
||||
// }
|
||||
// (new RoleService())->deleteRole($roleId);
|
||||
// return $this->success([], '角色删除成功');
|
||||
// } catch (\Throwable $e) {
|
||||
// return $this->error($e->getMessage());
|
||||
// }
|
||||
// }
|
||||
public function menuResource(Request $request)
|
||||
{
|
||||
try {
|
||||
// $data = $this->validate($this->service->getValidator(), $request->post(), 'allocation');
|
||||
$data = $request->post();
|
||||
$res = $this->service->menuResource($request, $data);
|
||||
return $this->success($res);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,12 @@ class SystemsController extends BaseController
|
||||
* @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;
|
||||
// }
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use app\common\model\Corp;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\admin\service\UserService;
|
||||
use app\crm\model\Customer;
|
||||
use support\Request;
|
||||
|
||||
class UserController extends BaseController
|
||||
{
|
||||
@@ -17,6 +18,60 @@ class UserController extends BaseController
|
||||
{
|
||||
$this->service = new UserService();
|
||||
}
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回更新成功的数据或信息
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->post();
|
||||
$res = $this->service->serviceUpdateUser($request, $data);
|
||||
return $this->success([], '更新成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
* @throws \Random\RandomException
|
||||
*/
|
||||
public function savePassword(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->all();
|
||||
if(empty($data['password'])){
|
||||
return $this->error('密码不能为空');
|
||||
}
|
||||
$result = $this->service->savePassword($request,$data);;
|
||||
return $this->success($result, '编辑成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回更新成功的数据或信息
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->post();
|
||||
$data['id'] = $data['id']??$request->user->uid;
|
||||
$res = $this->service->serviceUpdate($request, $data);
|
||||
return $this->success([], '更新成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
@@ -24,32 +79,79 @@ class UserController extends BaseController
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if(isset($data['records'])){
|
||||
return $data;
|
||||
}
|
||||
$data['sex_txt'] = '';
|
||||
if (isset($data['sex']) && $data['sex'] == 1){
|
||||
$data['sex_txt'] = '男';
|
||||
}elseif(isset($data['sex']) && $data['sex'] == 2){
|
||||
$data['sex_txt'] = '女';
|
||||
}
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if(isset($data['records'])){
|
||||
return $data;
|
||||
}
|
||||
$data['sex_txt'] = '';
|
||||
if (isset($data['sex']) && $data['sex'] == 1){
|
||||
$data['sex_txt'] = '男';
|
||||
}elseif(isset($data['sex']) && $data['sex'] == 2){
|
||||
$data['sex_txt'] = '女';
|
||||
}
|
||||
|
||||
switch ($data['status']){
|
||||
case 1:
|
||||
$data['status_txt'] = '正常';
|
||||
break;
|
||||
case 2:
|
||||
$data['status_txt'] = '离职';
|
||||
break;
|
||||
default:
|
||||
$data['status_txt'] = '';
|
||||
break;
|
||||
}
|
||||
switch ($data['status']){
|
||||
case 1:
|
||||
$data['status_txt'] = '正常';
|
||||
break;
|
||||
case 2:
|
||||
$data['status_txt'] = '离职';
|
||||
break;
|
||||
default:
|
||||
$data['status_txt'] = '';
|
||||
break;
|
||||
}
|
||||
|
||||
$data['corp_name'] = Corp::where('id', $data['corp_id'])->value('name');
|
||||
$data['customer_count'] = Customer::where('user_id', $data['id'])->count();
|
||||
return $data;
|
||||
}
|
||||
$data['corp_name'] = Corp::where('id', $data['corp_id'])->value('name');
|
||||
$data['customer_count'] = Customer::where('user_id', $data['id'])->count();
|
||||
|
||||
$data['role_ids'] = [];
|
||||
$data['system_ids'] = [];
|
||||
if (isset($data['roles']) && count($data['roles']) > 0) {
|
||||
foreach ($data['roles'] as $role) {
|
||||
$data['role_ids'][] = $role['id'];
|
||||
}
|
||||
}
|
||||
if (isset($data['systems']) && count($data['systems']) > 0) {
|
||||
foreach ($data['systems'] as $system) {
|
||||
$data['system_ids'][] = $system['id'];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function authorize(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->post();
|
||||
$res = $this->service->authorize($request, $data);
|
||||
return $this->success([], '分配成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接授权
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateResources(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->post();
|
||||
$res = $this->service->updateResources($request, $data);
|
||||
return $this->success([], '分配成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace app\admin\logic;
|
||||
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\common\model\User;
|
||||
use support\Db;
|
||||
|
||||
class UserLogic
|
||||
{
|
||||
@@ -14,4 +15,79 @@ class UserLogic
|
||||
*/
|
||||
protected string $modelClass = User::class;
|
||||
|
||||
|
||||
public function updateRoleAndSystem(array $data): bool
|
||||
{
|
||||
$roleIds = $data['role_ids'] ?? [];
|
||||
$systemIds = $data['system_ids'] ?? [];
|
||||
$userId = $data['user_id'] ?? 0;
|
||||
|
||||
Db::beginTransaction();
|
||||
try {
|
||||
Db::table('user_roles')->where('user_id', $userId)->delete();
|
||||
if (count($roleIds) > 0) {
|
||||
$insertDataRole = [];
|
||||
foreach ($roleIds as $roleId) {
|
||||
$insertDataRole[] = [
|
||||
'role_id' => $roleId,
|
||||
'user_id' => $userId
|
||||
];
|
||||
}
|
||||
Db::table('user_roles')->insert($insertDataRole);
|
||||
}
|
||||
|
||||
Db::table('user_systems')->where('user_id', $userId)->delete();
|
||||
if (count($systemIds) > 0) {
|
||||
$insertDataSystem = [];
|
||||
foreach ($systemIds as $systemId) {
|
||||
$insertDataSystem[] = [
|
||||
'system_id' => $systemId,
|
||||
'user_id' => $userId
|
||||
];
|
||||
}
|
||||
Db::table('user_systems')->insert($insertDataSystem);
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (\Throwable $exception) {
|
||||
Db::rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function updateUserResources(array $data): bool
|
||||
{
|
||||
$userId = $data['user_id'] ?? 0;
|
||||
$resources = $data['resources'] ?? [];
|
||||
|
||||
if (empty($userId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Db::beginTransaction();
|
||||
try {
|
||||
// 删除原有资源关联
|
||||
Db::table('user_resources')->where('user_id', $userId)->delete();
|
||||
|
||||
// 批量插入新角色资源关联
|
||||
if (!empty($resources)) {
|
||||
$insertData = [];
|
||||
foreach ($resources as $resourceId) {
|
||||
$insertData[] = [
|
||||
'user_id' => $userId,
|
||||
'resource_id' => $resourceId
|
||||
];
|
||||
}
|
||||
Db::table('user_resources')->insert($insertData);
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (\Throwable $exception) {
|
||||
Db::rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\common\validate\CorpFeishuAppValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\CorpFeishuApp;
|
||||
use support\Request;
|
||||
|
||||
class CorpFeishuAppService
|
||||
{
|
||||
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = CorpFeishuApp::class;
|
||||
|
||||
/**
|
||||
* 验证器
|
||||
*/
|
||||
protected $validator = CorpFeishuAppValidate::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['where']['status'] = 1;
|
||||
$config['order']['sort'] = 'desc';
|
||||
$config['order']['id'] = 'desc';
|
||||
|
||||
$config['with']['corpInfo'][] = 'name';
|
||||
$config['with']['systemInfo'][] = 'name';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
$config['where']['status'] = 1;
|
||||
|
||||
$config['with']['corpInfo'][] = 'name';
|
||||
$config['with']['systemInfo'][] = 'name';
|
||||
break;
|
||||
case 'store':
|
||||
break;
|
||||
case 'update':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'destroy':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\common\validate\CountryValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\CorpFeishuApp;
|
||||
|
||||
class CountryService
|
||||
{
|
||||
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = CorpFeishuApp::class;
|
||||
|
||||
/**
|
||||
* 验证器
|
||||
*/
|
||||
protected $validator = CountryValidate::class;
|
||||
|
||||
/**
|
||||
* 获取验证器
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return new $this->validator;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\common\logic\RoleLogic;
|
||||
use app\common\validate\RoleValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\Role;
|
||||
use support\Db;
|
||||
|
||||
class RoleService
|
||||
{
|
||||
@@ -28,4 +30,21 @@ class RoleService
|
||||
{
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色资源
|
||||
*/
|
||||
public function menuResource($request, $data)
|
||||
{
|
||||
return (new RoleLogic)->updateRoleResources($data);
|
||||
}
|
||||
|
||||
|
||||
public function getList()
|
||||
{
|
||||
$config['where']['status'] = 1;
|
||||
$config['order']['sort'] = 'asc';
|
||||
$config['order']['id'] = 'asc';
|
||||
return $this->logicListAll($config);
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace app\admin\service;
|
||||
|
||||
use app\admin\validate\UserValidate;
|
||||
use app\admin\logic\UserLogic;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\User;
|
||||
use app\common\validate\UserValidate;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
|
||||
class UserService
|
||||
@@ -30,6 +32,25 @@ class UserService
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
/** 更新 */
|
||||
public function serviceUpdateUser(Request $request, array $data = [])
|
||||
{
|
||||
$data = $this->preProcess('Update', $data, $request);
|
||||
$config = $this->buildQueryConfig($request, 'update');
|
||||
$updated = $this->logicUpdateBy($config, $data);
|
||||
return $this->postProcess('Update', $data);
|
||||
}
|
||||
|
||||
/** 更新 */
|
||||
public function serviceUpdate(Request $request, array $data = [])
|
||||
{
|
||||
unset($data['roles']);
|
||||
unset($data['corp_name']);
|
||||
$data = $this->preProcess('Update', $data, $request);
|
||||
$config = $this->buildQueryConfig($request, 'edit');
|
||||
$updated = $this->logicUpdateBy($config, $data);
|
||||
return $this->postProcess('Update', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造 CrudUtil 查询配置
|
||||
@@ -61,7 +82,12 @@ class UserService
|
||||
$config['where']['id'] = $p['id'];
|
||||
}
|
||||
|
||||
$config['fields'] = ['id','sn', 'name', 'email', 'sex', 'phone', 'avatar', 'corp_id', 'country_id', 'position', 'status', 'created_at'];
|
||||
$config['fields'] = ['id','sn', 'name', 'email', 'sex', 'phone', 'avatar', 'corp_id', 'country_id', 'position', 'report_to', 'status', 'created_at'];
|
||||
|
||||
$config['with']['roles'][] = 'id';
|
||||
$config['with']['roles'][] = 'name';
|
||||
$config['with']['systems'][] = 'id';
|
||||
$config['with']['systems'][] = 'name';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
@@ -74,8 +100,49 @@ class UserService
|
||||
case 'destroy':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'savePassword':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'edit':
|
||||
$config['where']['id'] = $request->user->uid;
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(Request $request, array $data = [])
|
||||
{
|
||||
return (new UserLogic())->updateRoleAndSystem($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户资源权限
|
||||
*
|
||||
* @param Request $request
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function updateResources(Request $request, array $data = [])
|
||||
{
|
||||
return (new UserLogic())->updateUserResources($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码
|
||||
*/
|
||||
public function savePassword(Request $request, array $data)
|
||||
{
|
||||
$config = $this->buildQueryConfig($request, 'savePassword');
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
$user = $this->logicUpdateBy($config,$data);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,8 @@ class CustomerCodeCommand extends SymfonyCommand
|
||||
$code = 'CM' . $unique;
|
||||
}
|
||||
|
||||
$obtain = $customer->created_at>strtotime('2025-07-29')?$customer->created_at:strtotime('2025-07-29');
|
||||
$created_at = $customer->created_at->getTimestamp();
|
||||
$obtain = $created_at > strtotime('2025-07-29')?$created_at:strtotime('2025-07-29');
|
||||
|
||||
$customer->code = $code;
|
||||
$customer->obtain = $obtain;
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
namespace app\common\controller;
|
||||
|
||||
use app\admin\service\RoleService;
|
||||
use support\Request;
|
||||
use app\common\service\CorpService;
|
||||
use app\common\service\CorpFeishuAppService;
|
||||
use app\common\service\SystemsService;
|
||||
use app\common\service\UserService;
|
||||
use support\Cache;
|
||||
use app\common\service\PermService;
|
||||
|
||||
class PresetController extends BaseController
|
||||
{
|
||||
@@ -61,4 +64,44 @@ class PresetController extends BaseController
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function roles()
|
||||
{
|
||||
try {
|
||||
$result = (new RoleService)->getList();
|
||||
return $this->success($result, '获取角色列表');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function cacheClear()
|
||||
{
|
||||
try {
|
||||
Cache::clear();
|
||||
return $this->success([], '操作成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function menus(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$systemCode = $request->system_code;
|
||||
$permService = new PermService();
|
||||
$menuTree = $permService->getMenuTree($uid, $systemCode);
|
||||
$permissionCodes = $permService->getPermissionCodes($uid, $systemCode);
|
||||
$result = [
|
||||
'menu' => $menuTree,
|
||||
'permissions' => $permissionCodes
|
||||
];
|
||||
return $this->success($result, '获取菜单权限');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace app\common\controller;
|
||||
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\common\service\ResourceService;
|
||||
use support\Request;
|
||||
|
||||
class ResourceController extends BaseController
|
||||
{
|
||||
use CrudControllerTrait;
|
||||
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new ResourceService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表页数据格式化
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function allFormat($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 listTree(Request $request)
|
||||
{
|
||||
try {
|
||||
$raw = $this->service->serviceListAll($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'allFormat')
|
||||
? [$this, 'allFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
public function menuList(Request $request)
|
||||
{
|
||||
try {
|
||||
$raw = $this->service->serviceMenuList($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'allFormat')
|
||||
? [$this, 'allFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
public function menuTreeList(Request $request)
|
||||
{
|
||||
try {
|
||||
$raw = $this->service->serviceMenuTreeList($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'allFormat')
|
||||
? [$this, 'allFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,63 @@
|
||||
|
||||
namespace app\common\controller;
|
||||
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use support\Request;
|
||||
use app\common\service\UserService;
|
||||
|
||||
class UserController extends BaseController
|
||||
{
|
||||
|
||||
use CrudControllerTrait;
|
||||
|
||||
protected $service;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->service = new UserService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
* 获取组员列表
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回分页数据及总数
|
||||
*/
|
||||
public function team(Request $request)
|
||||
{
|
||||
try {
|
||||
$raw = $this->service->serviceTeam($request);
|
||||
$data = $this->transformData($raw, method_exists($this, 'indexFormat')
|
||||
? [$this, 'indexFormat']
|
||||
: null);
|
||||
return $this->success($data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记组员离职
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return mixed 返回分页数据及总数
|
||||
*/
|
||||
public function resignMember(Request $request)
|
||||
{
|
||||
try {
|
||||
$userId = $request->get('user_id');
|
||||
if(empty($userId)){
|
||||
return $this->error('组员id不能为空');
|
||||
}
|
||||
$user = $this->service->resignMember($request);
|
||||
return $this->success($user, '获取用户信息');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息(登录后调用)
|
||||
*/
|
||||
public function info(Request $request)
|
||||
{
|
||||
@@ -23,57 +72,57 @@ class UserController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
public function getUser(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$corp_abbr = $request->basic_data['corp_abbr'];
|
||||
$result = (new UserService())->getUser($uid,$corp_abbr);
|
||||
return $this->success($result, '获取用户信息');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
public function getUser(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$corp_abbr = $request->basic_data['corp_abbr'];
|
||||
$result = (new UserService())->getUser($uid,$corp_abbr);
|
||||
return $this->success($result, '获取用户信息');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$data = $request->all();
|
||||
$result = (new UserService())->edit($uid,$data);
|
||||
unset($result['password']);
|
||||
unset($result['union_id']);
|
||||
unset($result['open_id']);
|
||||
unset($result['tenant_key']);
|
||||
return $this->success($result, '编辑成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 编辑用户
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$data = $request->all();
|
||||
$result = (new UserService())->edit($uid,$data);
|
||||
unset($result['password']);
|
||||
unset($result['union_id']);
|
||||
unset($result['open_id']);
|
||||
unset($result['tenant_key']);
|
||||
return $this->success($result, '编辑成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
* @throws \Random\RandomException
|
||||
*/
|
||||
public function savePassword(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$data = $request->all();
|
||||
$result = (new UserService())->savePassword($uid,$data);;
|
||||
return $this->success($result, '编辑成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
* @throws \Random\RandomException
|
||||
*/
|
||||
public function savePassword(Request $request)
|
||||
{
|
||||
try {
|
||||
$uid = $request->user->uid;
|
||||
$data = $request->all();
|
||||
$result = (new UserService())->savePassword($uid,$data);;
|
||||
return $this->success($result, '编辑成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -118,6 +118,12 @@ class AuthLogic
|
||||
}
|
||||
// 是否登陆
|
||||
$user->isLogin = false;
|
||||
|
||||
$options = [
|
||||
'corp_id' => $user->corp_id,
|
||||
'user_id' => $user->id
|
||||
];
|
||||
\Webman\RedisQueue\Redis::send('perm-agt', $options);
|
||||
} else {
|
||||
$updated = [
|
||||
'union_id' => $feishuUserInfo['union_id'],
|
||||
|
||||
@@ -2,10 +2,17 @@
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\common\model\CorpFeishuApp;
|
||||
|
||||
class CorpFeishuAppLogic
|
||||
{
|
||||
use CrudLogicTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = CorpFeishuApp::class;
|
||||
|
||||
|
||||
public function getFeishuApp($corpId, $systemId)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\common\model\CorpFeishuApp;
|
||||
|
||||
class CountryLogic
|
||||
{
|
||||
use CrudLogicTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = CorpFeishuApp::class;
|
||||
|
||||
}
|
||||
@@ -23,13 +23,16 @@ class PermLogic
|
||||
}
|
||||
|
||||
$all = collect();
|
||||
|
||||
// 合并角色资源,排除不需要权限认证的资源
|
||||
// 遍历用户的所有角色,合并每个角色所拥有的资源
|
||||
foreach ($user->roles as $role) {
|
||||
$all = $all->merge(
|
||||
// 过滤当前角色的资源列表
|
||||
$role->resources->filter(function ($resource) use($system) {
|
||||
// var_dump($resource->toArray());
|
||||
// 只保留需要权限认证的资源(或公共资源)
|
||||
// 资源过滤条件:
|
||||
// 1. !$resource->no_auth:资源需要权限认证(排除公共资源)
|
||||
// 2. 系统匹配条件:
|
||||
// - $system->id == $resource->system_id:资源属于当前系统
|
||||
// - $resource->system_id == 0:资源为全局公共资源(所有系统可用)
|
||||
return !$resource->no_auth && ($system->id == $resource->system_id || $resource->system_id == 0);
|
||||
})
|
||||
);
|
||||
@@ -64,151 +67,6 @@ class PermLogic
|
||||
* @param string $parentPath 父级完整路径(用于递归)
|
||||
* @return array
|
||||
*/
|
||||
public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
foreach ($resources as $node) {
|
||||
// 只处理目录和菜单,不把 permission 当作菜单节点
|
||||
if ($node->parent_id !== $parentId || $node->type === 'permission') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// —— 拼接当前节点的完整路径 ——
|
||||
$currentPath = rtrim($parentPath, '/');
|
||||
if (!empty($node->url)) {
|
||||
$urlSegment = ltrim($node->url, '/');
|
||||
$currentPath = $currentPath === ''
|
||||
? $urlSegment
|
||||
: "{$currentPath}/{$urlSegment}";
|
||||
}
|
||||
|
||||
// —— 递归构建子节点 ——
|
||||
// 这里只会继续收目录和菜单,permission 永远不会进入此方法
|
||||
$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 = ! empty($children);
|
||||
|
||||
// —— 计算 component 字段 ——
|
||||
if ($hasChildrenMenu) {
|
||||
if ($node->type === 'menu' && !empty($node->url)) {
|
||||
// menu 类型且自身有 url,用自身 url(加前导 slash)
|
||||
$componentValue = '/' . ltrim($node->url, '/');
|
||||
} else {
|
||||
// 其它含子项的节点,固定 Layout 组件
|
||||
$componentValue = '/index/index';
|
||||
}
|
||||
} else {
|
||||
// 叶子节点:拼接路径,确保以 slash 开头
|
||||
$componentValue = $currentPath !== ''
|
||||
? '/' . ltrim($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,
|
||||
'isHide' => $node->is_hide == 0 ? false : true,
|
||||
'isHideTab' => $node->is_hide_tab == 0 ? false : true
|
||||
],
|
||||
'children' => $children
|
||||
];
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
public function buildTree_bak2($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
foreach ($resources as $node) {
|
||||
if ($node->parent_id !== $parentId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// —— 拼接当前节点的完整路径 ——
|
||||
$currentPath = $parentPath;
|
||||
// 去掉末尾多余 slash
|
||||
$currentPath = rtrim($currentPath, '/');
|
||||
|
||||
if (!empty($node->url)) {
|
||||
// 如果当前节点有 url,则拼接
|
||||
$urlSegment = ltrim($node->url, '/');
|
||||
$currentPath = $currentPath === ''
|
||||
? $urlSegment
|
||||
: "{$currentPath}/{$urlSegment}";
|
||||
}
|
||||
|
||||
// —— 递归构建子节点 ——
|
||||
$children = [];
|
||||
if ($node->type === 'directory') {
|
||||
$children = $this->buildTree($resources, $node->id, $currentPath);
|
||||
}
|
||||
|
||||
// —— 收集本级的 permission 权限列表 ——
|
||||
$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 = $resources
|
||||
->where('parent_id', $node->id)
|
||||
->whereIn('type', ['directory', 'menu'])
|
||||
->isNotEmpty();
|
||||
|
||||
// —— 计算 component 字段 ——
|
||||
if ($hasChildrenMenu) {
|
||||
// 只要有子项,就一律显示顶层 Layout 组件
|
||||
$componentValue = '/index/index';
|
||||
} else {
|
||||
// 叶子节点:如果定义了 url,就使用拼接后的路径;否则用占位符(这里用空串,你可替换)
|
||||
$componentValue = $currentPath !== '' ? $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;
|
||||
}
|
||||
public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array
|
||||
{
|
||||
$tree = [];
|
||||
@@ -258,7 +116,7 @@ class PermLogic
|
||||
'meta' => [
|
||||
'title' => $node->name,
|
||||
'icon' => $node->icon,
|
||||
'keepAlive' => true,
|
||||
'keepAlive' => $node->keep_alive == 1 ? true : false,
|
||||
'authList' => $authList,
|
||||
'openType' => $node->open_type,
|
||||
'isHide' => $node->is_hide == 0 ? false : true,
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\common\model\Resource;
|
||||
use support\Request;
|
||||
|
||||
class ResourceLogic
|
||||
{
|
||||
use CrudLogicTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = Resource::class;
|
||||
|
||||
|
||||
public function logicListAllResources(Request $request, array $config)
|
||||
{
|
||||
$data = $this->logicListAll($config);
|
||||
|
||||
if ($request->get('role_id')) {
|
||||
$selected = (new RoleLogic())->getRoleResources($request->get('role_id'));
|
||||
} else if ($request->get('user_id')) {
|
||||
$selected = (new RoleLogic())->getUserResources($request->get('user_id'));
|
||||
} else {
|
||||
$selected = [];
|
||||
}
|
||||
|
||||
foreach ($data as &$item) {
|
||||
$item['selected'] = in_array($item['id'], $selected) ? true : false;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,84 @@
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\model\Role;
|
||||
use support\exception\BusinessException;
|
||||
use support\Log;
|
||||
use support\Db;
|
||||
|
||||
class RoleLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* 更新角色资源权限
|
||||
*
|
||||
* @param array $data 包含 role_id 和 resources 的数据
|
||||
* @return bool 操作是否成功
|
||||
*/
|
||||
public function updateRoleResources(array $data): bool
|
||||
{
|
||||
$roleId = $data['role_id'] ?? 0;
|
||||
$resources = $data['resources'] ?? [];
|
||||
|
||||
if (empty($roleId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Db::beginTransaction();
|
||||
try {
|
||||
// 删除原有角色资源关联
|
||||
Db::table('role_resources')->where('role_id', $roleId)->delete();
|
||||
|
||||
// 批量插入新角色资源关联
|
||||
if (!empty($resources)) {
|
||||
$insertData = [];
|
||||
foreach ($resources as $resourceId) {
|
||||
$insertData[] = [
|
||||
'role_id' => $roleId,
|
||||
'resource_id' => $resourceId
|
||||
];
|
||||
}
|
||||
Db::table('role_resources')->insert($insertData);
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (\Throwable $exception) {
|
||||
Db::rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色资源
|
||||
*
|
||||
* @param int $roleId 角色ID
|
||||
* @return array 资源ID列表
|
||||
*/
|
||||
public function getRoleResources(int $roleId): array
|
||||
{
|
||||
if (empty($roleId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Db::table('role_resources')
|
||||
->where('role_id', $roleId)
|
||||
->pluck('resource_id')
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户资源
|
||||
*
|
||||
* @param int $userId 用户ID
|
||||
* @return array 资源ID列表
|
||||
*/
|
||||
public function getUserResources(int $userId): array
|
||||
{
|
||||
if (empty($userId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Db::table('user_resources')
|
||||
->where('user_id', $userId)
|
||||
->pluck('resource_id')
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,18 @@
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\model\User;
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
class UserLogic
|
||||
{
|
||||
use CrudLogicTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = User::class;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
|
||||
@@ -4,24 +4,6 @@ namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
/**
|
||||
* corp_feishu_app 企业-飞书应用
|
||||
* @property integer $id ID(主键)
|
||||
* @property integer $corp_id 公司ID
|
||||
* @property string $name 名称
|
||||
* @property string $tenant_key 企业标识
|
||||
* @property string $app_id 应用ID
|
||||
* @property string $app_secret 应用秘钥
|
||||
* @property string $base_uri 基础域
|
||||
* @property string $r_url 授权地址
|
||||
* @property string $scopes 授权范围
|
||||
* @property string $state 携带参数
|
||||
* @property string $system_code 绑定系统码
|
||||
* @property integer $sort 排序
|
||||
* @property integer $status 状态
|
||||
* @property integer $created_at 创建时间
|
||||
* @property integer $updated_at 更新时间
|
||||
*/
|
||||
class CorpFeishuApp extends Model
|
||||
{
|
||||
/**
|
||||
@@ -53,4 +35,26 @@ class CorpFeishuApp extends Model
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'corp_id', 'system_id', 'name', 'tenant_key', 'app_id', 'app_secret', 'base_uri', 'r_url', 'scopes', 'state', 'sort', 'status', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
|
||||
public function corpInfo()
|
||||
{
|
||||
return $this->hasOne(Corp::class, 'id', 'corp_id');
|
||||
}
|
||||
|
||||
public function systemInfo()
|
||||
{
|
||||
return $this->hasOne(Systems::class, 'id', 'system_id');
|
||||
}
|
||||
}
|
||||
@@ -46,4 +46,31 @@ class CrmCustomer extends Model
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::saved(function ($customer) {
|
||||
if (empty($customer->code)) {
|
||||
$customer->code = self::generateCustomerCode($customer);
|
||||
// 使用saveQuietly避免递归调用
|
||||
$customer->saveQuietly();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function generateCustomerCode($customer)
|
||||
{
|
||||
// 生成唯一16位code,CM+14位
|
||||
$unique = strtoupper(substr(md5($customer->id . microtime(true) . mt_rand(1000, 9999)), 8, 6));
|
||||
$code = 'CM' . date('Ymd') .$unique;
|
||||
return $code;
|
||||
}
|
||||
|
||||
// 静默保存方法,不触发事件
|
||||
public function saveQuietly(array $options = [])
|
||||
{
|
||||
return static::withoutEvents(function () use ($options) {
|
||||
return $this->save($options);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class InquiryLog extends Model
|
||||
|
||||
public function recipientInfo()
|
||||
{
|
||||
return $this->hasOne(User::class, 'id', 'recipient');
|
||||
return $this->hasOne(User::class, 'id', 'recipient')->where('status', 1);
|
||||
}
|
||||
|
||||
public function channelInfo()
|
||||
|
||||
@@ -4,20 +4,6 @@ namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
/**
|
||||
* resources 资源表:目录/菜单/权限
|
||||
* @property integer $id 资源ID(主键)
|
||||
* @property string $name 资源名称
|
||||
* @property string $type 资源类型
|
||||
* @property string $code 资源编码(权限标识)
|
||||
* @property integer $parent_id 父资源ID
|
||||
* @property string $url 路由 path 或 外链 URL
|
||||
* @property string $icon 图标,仅目录/菜单有效
|
||||
* @property string $open_type 菜单打开方式
|
||||
* @property integer $sort 排序
|
||||
* @property string $created_at
|
||||
* @property string $updated_at
|
||||
*/
|
||||
class Resource extends Model
|
||||
{
|
||||
/**
|
||||
@@ -49,32 +35,15 @@ class Resource extends Model
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
// 所属系统
|
||||
public function system()
|
||||
{
|
||||
return $this->belongsTo(Systems::class, 'system_id', 'id');
|
||||
}
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
// 拥有该资源的角色
|
||||
public function roles()
|
||||
{
|
||||
return $this->belongsToMany(Role::class, 'role_resources', 'resource_id', 'role_id');
|
||||
}
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'system_id', 'name', 'desc', 'type', 'code', 'parent_id', 'url', 'icon', 'open_type', 'is_hide', 'is_hide_tab', 'no_auth', 'is_home', 'instance', 'sort', 'status', 'created_at', 'updated_at'];
|
||||
|
||||
// 拥有该资源的用户(特殊补权)
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'user_resources', 'resource_id', 'user_id');
|
||||
}
|
||||
|
||||
// 递归
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(self::class, 'parent_id');
|
||||
}
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use support\Model;
|
||||
* @property string $email 邮箱
|
||||
* @property integer $status 状态
|
||||
* @property string $system_code 系统码
|
||||
* @property string $report_to 上级用户ID
|
||||
* @property string $created_at
|
||||
* @property string $updated_at
|
||||
*/
|
||||
@@ -69,6 +70,7 @@ class User extends Model
|
||||
'position',
|
||||
'socialize',
|
||||
'socialize_pic',
|
||||
'report_to',
|
||||
];
|
||||
|
||||
// 用户所有角色
|
||||
|
||||
@@ -2,82 +2,128 @@
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\model\User;
|
||||
use app\model\Role;
|
||||
use app\model\Resource;
|
||||
use app\common\logic\ResourceLogic;
|
||||
use app\common\validate\ResourceValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\Resource;
|
||||
use app\common\utils\Tree;
|
||||
use support\Request;
|
||||
|
||||
class ResourceService
|
||||
{
|
||||
/**
|
||||
* 获取用户可见菜单树
|
||||
*/
|
||||
public static function getMenuTreeForUser($userId)
|
||||
{
|
||||
$menuList = self::getUserMenus($userId);
|
||||
// 转树
|
||||
return self::buildTree($menuList);
|
||||
}
|
||||
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 获取用户所有有权限的菜单资源(type=menu)
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
public static function getUserMenus($userId)
|
||||
{
|
||||
$user = User::with('roles.resources')->find($userId);
|
||||
if (!$user) return [];
|
||||
// 合并所有角色下的菜单资源
|
||||
$allMenus = [];
|
||||
foreach ($user->roles as $role) {
|
||||
foreach ($role->resources as $res) {
|
||||
if ($res->type === 'menu') {
|
||||
$allMenus[$res->id] = $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_values($allMenus); // 去重后返回
|
||||
}
|
||||
protected string $modelClass = Resource::class;
|
||||
|
||||
/**
|
||||
* 获取用户所有有权限的按钮/功能权限 code
|
||||
* 验证器
|
||||
*/
|
||||
public static function getButtonPermissionCodesForUser($userId)
|
||||
{
|
||||
$user = User::with('roles.resources')->find($userId);
|
||||
if (!$user) return [];
|
||||
$codes = [];
|
||||
foreach ($user->roles as $role) {
|
||||
foreach ($role->resources as $res) {
|
||||
if ($res->type === 'button' && $res->code) {
|
||||
$codes[$res->code] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_keys($codes); // 去重后返回权限code数组
|
||||
}
|
||||
protected $validator = ResourceValidate::class;
|
||||
|
||||
/**
|
||||
* 递归构建菜单树
|
||||
* @param Resource[] $list
|
||||
* @param int $parentId
|
||||
* @return array
|
||||
* 获取验证器
|
||||
*/
|
||||
protected static function buildTree($list, $parentId = 0)
|
||||
public function getValidator()
|
||||
{
|
||||
$tree = [];
|
||||
foreach ($list as $item) {
|
||||
if ($item->parent_id == $parentId) {
|
||||
$children = self::buildTree($list, $item->id);
|
||||
$arr = [
|
||||
'id' => $item->id,
|
||||
'name' => $item->name,
|
||||
'path' => $item->url,
|
||||
'icon' => $item->icon ?? null,
|
||||
'code' => $item->code,
|
||||
'children' => $children,
|
||||
];
|
||||
$tree[] = $arr;
|
||||
}
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
||||
{
|
||||
$p = $request->all();
|
||||
|
||||
$config = [];
|
||||
$config['model'] = $this->modelClass;
|
||||
switch ($scene) {
|
||||
case 'default':
|
||||
$config['where']['system_id'] = ['in', [0, $p['system_id']]];
|
||||
$config['where']['status'] = 1;
|
||||
$config['order']['sort'] = 'asc';
|
||||
$config['order']['id'] = 'asc';
|
||||
break;
|
||||
case 'menuList':
|
||||
$config['where']['status'] = 1;
|
||||
$config['where']['type'] = ['!=', 'permission'];
|
||||
$config['order']['sort'] = 'asc';
|
||||
$config['order']['id'] = 'asc';
|
||||
break;
|
||||
case 'menuTreeList':
|
||||
$config['where']['status'] = 1;
|
||||
$config['order']['sort'] = 'asc';
|
||||
$config['order']['id'] = 'asc';
|
||||
break;
|
||||
case 'index':
|
||||
$config['where']['status'] = 1;
|
||||
$config['order']['sort'] = 'asc';
|
||||
$config['order']['id'] = 'asc';
|
||||
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 $tree;
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function serviceMenuList(Request $request)
|
||||
{
|
||||
$config = $this->buildQueryConfig($request, 'menuList');
|
||||
$result = $this->logicListAll($config);
|
||||
return $this->postProcess('MenuList', $result);
|
||||
}
|
||||
|
||||
public function serviceMenuTreeList(Request $request)
|
||||
{
|
||||
$config = $this->buildQueryConfig($request, 'menuTreeList');
|
||||
$result = (new ResourceLogic())->logicListAllResources($request, $config);
|
||||
return $this->postProcess('MenuTreeList', $result);
|
||||
}
|
||||
|
||||
|
||||
protected function afterServiceListAll($data)
|
||||
{
|
||||
$data = Tree::buildMenuTreeWithReference($data->toArray());
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function afterServiceMenuList($data)
|
||||
{
|
||||
$data = Tree::buildMenuTree($data->toArray());
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function afterServiceMenuTreeList($data)
|
||||
{
|
||||
$data = Tree::buildMenuTree($data->toArray());
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function beforeServiceStore($data, Request $request)
|
||||
{
|
||||
$data['parent_id'] = $data['parent_id'] != '' ? $data['parent_id'] : 0;
|
||||
$data['system_id'] = $data['system_id'] != '' ? $data['system_id'] : 0;
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function beforeServiceUpdate($data, Request $request)
|
||||
{
|
||||
$data['parent_id'] = $data['parent_id'] != '' ? $data['parent_id'] : 0;
|
||||
$data['system_id'] = $data['system_id'] != '' ? $data['system_id'] : 0;
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,22 @@ namespace app\common\service;
|
||||
use app\common\logic\UserLogic;
|
||||
use app\common\model\Corp;
|
||||
use app\common\model\User;
|
||||
use app\common\traits\crud\CrudLogicTrait;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\utils\CrudUtil;
|
||||
use app\crm\model\Country;
|
||||
use app\crm\model\Customer;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
|
||||
class UserService
|
||||
{
|
||||
use CrudServiceTrait;
|
||||
|
||||
/**
|
||||
* 指定当前要操作的模型
|
||||
*/
|
||||
protected string $modelClass = User::class;
|
||||
|
||||
protected $logic;
|
||||
|
||||
@@ -25,9 +35,10 @@ class UserService
|
||||
public function getUserInfo(int $uid, string $systemCode)
|
||||
{
|
||||
$user = $this->logic->userInfo($uid);
|
||||
$permService = new PermService();
|
||||
$menuTree = $permService->getMenuTree($uid, $systemCode);
|
||||
$permissionCodes = $permService->getPermissionCodes($uid, $systemCode);
|
||||
// $permService = new PermService();
|
||||
// $menuTree = $permService->getMenuTree($uid, $systemCode);
|
||||
// $permissionCodes = $permService->getPermissionCodes($uid, $systemCode);
|
||||
$corp_name = Corp::where('abbr', $user->corp_id)->value('name');
|
||||
return [
|
||||
'user' => [
|
||||
'id' => $user->id,
|
||||
@@ -36,10 +47,14 @@ class UserService
|
||||
'phone' => $user->phone,
|
||||
'email' => $user->email,
|
||||
'status' => $user->status,
|
||||
'roles' => $user->roles->pluck('name')
|
||||
'roles' => $user->roles->pluck('name'),
|
||||
'sex' => $user->sex,
|
||||
'sn' => $user->sn,
|
||||
'corp_id' => $user->corp_id,
|
||||
'corp_name' => $corp_name,
|
||||
],
|
||||
'menu' => $menuTree,
|
||||
'permissions' => $permissionCodes
|
||||
// 'menu' => $menuTree,
|
||||
// 'permissions' => $permissionCodes
|
||||
];
|
||||
}
|
||||
|
||||
@@ -110,4 +125,76 @@ class UserService
|
||||
{
|
||||
return $this->logic->getList();
|
||||
}
|
||||
|
||||
/** 分页列表 */
|
||||
public function serviceTeam(Request $request)
|
||||
{
|
||||
if (method_exists($this, 'complexQuery')) {
|
||||
$result = $this->complexQuery($request->get());
|
||||
} else {
|
||||
$config = $this->buildQueryConfig($request, 'team');
|
||||
$limit = (int)$request->get('size', 15);
|
||||
$page = (int)$request->get('current', 1);
|
||||
$result = $this->logicList($config, $limit, $page);
|
||||
}
|
||||
|
||||
foreach ($result as &$data){
|
||||
$data['customer_count'] = Customer::where('user_id', $data['id'])->count();
|
||||
unset($data['password']);
|
||||
unset($data['open_id']);
|
||||
unset($data['tenant_key']);
|
||||
unset($data['union_id']);
|
||||
}
|
||||
|
||||
return $this->postProcess('List', $result);
|
||||
}
|
||||
|
||||
/** 分页列表 */
|
||||
public function resignMember(Request $request)
|
||||
{
|
||||
$uid = $request->user->uid;
|
||||
$userId = $request->get('user_id');
|
||||
$user = User::find($userId);
|
||||
if ($user->report_to != $uid) {
|
||||
throw new BusinessException('禁止操作非组员');
|
||||
}
|
||||
|
||||
$data = [
|
||||
'status' => 2,
|
||||
];
|
||||
$user = $this->logic->edit($userId,$data);
|
||||
$user = $user->toArray();
|
||||
unset($user['password']);
|
||||
unset($user['open_id']);
|
||||
unset($user['tenant_key']);
|
||||
unset($user['union_id']);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造 CrudUtil 查询配置
|
||||
*/
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
||||
{
|
||||
$p = $request->all();
|
||||
|
||||
$config = [];
|
||||
$config['model'] = $this->modelClass;
|
||||
switch ($scene) {
|
||||
case 'team':
|
||||
// $config['where']['status'] = 1; // 关键字
|
||||
$config['order']['id'] = 'desc';
|
||||
|
||||
if (isset($p['status']) && $p['status']) {
|
||||
$config['where']['status'] = $p['status'];
|
||||
}
|
||||
|
||||
$config['dataLimit']['type'] = 'relation';
|
||||
$config['dataLimit']['userId'] = $request->user->uid;
|
||||
$config['dataLimit']['userField'] = 'report_to';
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace app\common\traits\crud;
|
||||
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
|
||||
/**
|
||||
@@ -48,7 +49,7 @@ trait CrudServiceTrait
|
||||
$config = $this->buildQueryConfig($request, 'default');
|
||||
$result = $this->logicListAll($config);
|
||||
}
|
||||
return $this->postProcess('List', $result);
|
||||
return $this->postProcess('ListAll', $result);
|
||||
}
|
||||
|
||||
/** 查看单条 */
|
||||
@@ -188,6 +189,6 @@ trait CrudServiceTrait
|
||||
*/
|
||||
// protected function complexQuery(array $params): array
|
||||
// {
|
||||
// throw new \LogicException('请在子类实现 complexQuery');
|
||||
// throw new BusinessException('请在子类实现 complexQuery');
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,505 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\utils;
|
||||
|
||||
class Tree
|
||||
{
|
||||
// /**
|
||||
// * 递归构建树形结构
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param int $parentId 父级ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @param int $level 当前层级
|
||||
// * @return array
|
||||
// */
|
||||
// public static function build(array $data, int $parentId = 0, string $pidField = 'parent_id', string $idField = 'id', int $level = 0): array
|
||||
// {
|
||||
// $tree = [];
|
||||
|
||||
// foreach ($data as $item) {
|
||||
// if ($item[$pidField] == $parentId) {
|
||||
// $item['level'] = $level;
|
||||
// $children = static::build($data, $item[$idField], $pidField, $idField, $level + 1);
|
||||
|
||||
// if (!empty($children)) {
|
||||
// $item['children'] = $children;
|
||||
// }
|
||||
|
||||
// $tree[] = $item;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $tree;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 使用引用方式构建树形结构(性能更好)
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @return array
|
||||
// */
|
||||
// public static function buildWithReference(array $data, string $pidField = 'parent_id', string $idField = 'id'): array
|
||||
// {
|
||||
// $items = [];
|
||||
// $tree = [];
|
||||
|
||||
// // 建立以id为索引的数组
|
||||
// foreach ($data as $item) {
|
||||
// $item['level'] = 0;
|
||||
// $items[$item[$idField]] = $item;
|
||||
// }
|
||||
|
||||
// // 构建树形结构
|
||||
// foreach ($items as $id => $item) {
|
||||
// if ($item[$pidField] == 0) {
|
||||
// $tree[] = &$items[$id];
|
||||
// } else {
|
||||
// if (isset($items[$item[$pidField]])) {
|
||||
// $items[$id]['level'] = $items[$item[$pidField]]['level'] + 1;
|
||||
|
||||
// if (!isset($items[$item[$pidField]]['children'])) {
|
||||
// $items[$item[$pidField]]['children'] = [];
|
||||
// }
|
||||
|
||||
// $items[$item[$pidField]]['children'][] = &$items[$id];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $tree;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 将树形结构扁平化为列表(带层级前缀)
|
||||
// *
|
||||
// * @param array $tree 树形结构数据
|
||||
// * @param string $prefix 前缀字符
|
||||
// * @param string $field 显示字段名
|
||||
// * @param int $level 层级
|
||||
// * @return array
|
||||
// */
|
||||
// public static function flattenWithPrefix(array $tree, string $prefix = '--', string $field = 'name', int $level = 0): array
|
||||
// {
|
||||
// $result = [];
|
||||
|
||||
// foreach ($tree as $item) {
|
||||
// $item[$field . '_with_prefix'] = str_repeat($prefix, $item['level']) . $item[$field];
|
||||
// $result[] = $item;
|
||||
|
||||
// if (isset($item['children']) && !empty($item['children'])) {
|
||||
// $children = static::flattenWithPrefix($item['children'], $prefix, $field, $item['level'] + 1);
|
||||
// $result = array_merge($result, $children);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $result;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 根据父ID查找所有子节点(包括子孙节点)
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param int $parentId 父级ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @return array
|
||||
// */
|
||||
// public static function findChildren(array $data, int $parentId, string $pidField = 'parent_id', string $idField = 'id'): array
|
||||
// {
|
||||
// $children = [];
|
||||
|
||||
// foreach ($data as $item) {
|
||||
// if ($item[$pidField] == $parentId) {
|
||||
// $children[] = $item;
|
||||
// $grandChildren = static::findChildren($data, $item[$idField], $pidField, $idField);
|
||||
// $children = array_merge($children, $grandChildren);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $children;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 获取指定节点的所有父级节点
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param int $id 当前节点ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @return array
|
||||
// */
|
||||
// public static function getParents(array $data, int $id, string $pidField = 'parent_id', string $idField = 'id'): array
|
||||
// {
|
||||
// $parents = [];
|
||||
|
||||
// foreach ($data as $item) {
|
||||
// if ($item[$idField] == $id) {
|
||||
// if ($item[$pidField] != 0) {
|
||||
// $parents[] = $item;
|
||||
// $parentParents = static::getParents($data, $item[$pidField], $pidField, $idField);
|
||||
// $parents = array_merge($parents, $parentParents);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $parents;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 获取指定节点的子孙节点ID列表
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param int $parentId 父级ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @return array
|
||||
// */
|
||||
// public static function getChildrenIds(array $data, int $parentId, string $pidField = 'parent_id', string $idField = 'id'): array
|
||||
// {
|
||||
// $ids = [];
|
||||
// $children = static::findChildren($data, $parentId, $pidField, $idField);
|
||||
|
||||
// foreach ($children as $child) {
|
||||
// $ids[] = $child[$idField];
|
||||
// }
|
||||
|
||||
// return $ids;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 检查是否有子节点
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param int $parentId 父级ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @return bool
|
||||
// */
|
||||
// public static function hasChildren(array $data, int $parentId, string $pidField = 'parent_id'): bool
|
||||
// {
|
||||
// foreach ($data as $item) {
|
||||
// if ($item[$pidField] == $parentId) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * 构建带有权限列表的资源树(权限不显示在树结构中)
|
||||
// *
|
||||
// * @param array $data 资源数据列表
|
||||
// * @param int $parentId 父级ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @param string $typeField 类型字段名
|
||||
// * @param string $permissionType 权限类型标识
|
||||
// * @param int $level 当前层级
|
||||
// * @return array
|
||||
// */
|
||||
// public static function buildWithAuthList(
|
||||
// array $data,
|
||||
// int $parentId = 0,
|
||||
// string $pidField = 'parent_id',
|
||||
// string $idField = 'id',
|
||||
// string $typeField = 'type',
|
||||
// string $permissionType = 'permission',
|
||||
// int $level = 0
|
||||
// ): array {
|
||||
// $tree = [];
|
||||
|
||||
// foreach ($data as $item) {
|
||||
// // 只处理指定父级的非权限节点
|
||||
// if ($item[$pidField] == $parentId && $item[$typeField] != $permissionType) {
|
||||
// $item['level'] = $level;
|
||||
|
||||
// // 递归处理子节点(非权限类型)
|
||||
// $children = static::buildWithAuthList($data, $item[$idField], $pidField, $idField, $typeField, $permissionType, $level + 1);
|
||||
|
||||
// if (!empty($children)) {
|
||||
// $item['children'] = $children;
|
||||
// }
|
||||
|
||||
// // 收集当前节点下的所有权限
|
||||
// $item['auth_list'] = static::collectDirectPermissions($data, $item[$idField], $pidField, $typeField, $permissionType);
|
||||
|
||||
// $tree[] = $item;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $tree;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 收集指定节点下的直接权限项(只收集直接子节点中的权限)
|
||||
// *
|
||||
// * @param array $data 数据列表
|
||||
// * @param int $parentId 父级ID
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $typeField 类型字段名
|
||||
// * @param string $permissionType 权限类型标识
|
||||
// * @return array
|
||||
// */
|
||||
// public static function collectDirectPermissions1(
|
||||
// array $data,
|
||||
// int $parentId,
|
||||
// string $pidField = 'parent_id',
|
||||
// string $typeField = 'type',
|
||||
// string $permissionType = 'permission'
|
||||
// ): array {
|
||||
// $permissions = [];
|
||||
|
||||
// foreach ($data as $item) {
|
||||
// // 收集直接子节点中的权限类型
|
||||
// if ($item[$pidField] == $parentId && $item[$typeField] == $permissionType) {
|
||||
// $permissions[] = $item;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $permissions;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 使用引用方式构建带有权限列表的资源树(权限不显示在树结构中)
|
||||
// *
|
||||
// * @param array $data 资源数据列表
|
||||
// * @param string $pidField 父级字段名
|
||||
// * @param string $idField ID字段名
|
||||
// * @param string $typeField 类型字段名
|
||||
// * @param string $permissionType 权限类型标识
|
||||
// * @return array
|
||||
// */
|
||||
// public static function buildWithAuthListAndReference(
|
||||
// array $data,
|
||||
// string $pidField = 'parent_id',
|
||||
// string $idField = 'id',
|
||||
// string $typeField = 'type',
|
||||
// string $permissionType = 'permission'
|
||||
// ): array {
|
||||
// $items = [];
|
||||
// $tree = [];
|
||||
|
||||
// // 建立以id为索引的数组(只包含非权限节点)
|
||||
// foreach ($data as $item) {
|
||||
// if ($item[$typeField] != $permissionType) {
|
||||
// $item['level'] = 0;
|
||||
// $items[$item[$idField]] = $item;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 构建树形结构
|
||||
// foreach ($items as $id => $item) {
|
||||
// if ($item[$pidField] == 0) {
|
||||
// $tree[] = &$items[$id];
|
||||
// } else {
|
||||
// if (isset($items[$item[$pidField]])) {
|
||||
// $items[$id]['level'] = $items[$item[$pidField]]['level'] + 1;
|
||||
|
||||
// if (!isset($items[$item[$pidField]]['children'])) {
|
||||
// $items[$item[$pidField]]['children'] = [];
|
||||
// }
|
||||
|
||||
// $items[$item[$pidField]]['children'][] = &$items[$id];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 为每个节点添加权限列表
|
||||
// foreach ($items as &$item) {
|
||||
// $item['auth_list'] = static::collectDirectPermissions($data, $item[$idField], $pidField, $typeField, $permissionType);
|
||||
// }
|
||||
|
||||
// return $tree;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// 8.13 add
|
||||
/**
|
||||
* 构建前端需要的菜单树结构
|
||||
*
|
||||
* @param array $data 服务端菜单数据
|
||||
* @param int $parentId 父级ID
|
||||
* @return array
|
||||
*/
|
||||
public static function buildMenuTree(array $data, int $parentId = 0): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
foreach ($data as $item) {
|
||||
// 只处理非权限类型的节点
|
||||
if ($item['parent_id'] == $parentId && $item['type'] != 'permission') {
|
||||
// 转换数据结构以匹配前端需要的格式
|
||||
$menuItem = [
|
||||
'id' => $item['id'],
|
||||
'path' => $item['url'] ?? '',
|
||||
'name' => $item['name'],
|
||||
'component' => $item['url'] ?? '',
|
||||
'meta' => [
|
||||
'title' => $item['name'],
|
||||
'icon' => $item['icon'] ?? '',
|
||||
'isHide' => !empty($item['is_hide']),
|
||||
'isHideTab' => !empty($item['is_hide_tab']),
|
||||
'keepAlive' => !empty($item['keep_alive']),
|
||||
]
|
||||
];
|
||||
|
||||
// 收集当前节点下的所有权限
|
||||
$permissions = static::collectDirectPermissions($data, $item['id']);
|
||||
if (!empty($permissions)) {
|
||||
$authList = [];
|
||||
foreach ($permissions as $permission) {
|
||||
$authList[] = [
|
||||
'id' => $permission['id'],
|
||||
'title' => $permission['name'] ?? '',
|
||||
'authMark' => $permission['code'] ?? '',
|
||||
'selected' => isset($permission['selected']) && $permission['selected'] ? true : false
|
||||
];
|
||||
}
|
||||
$menuItem['meta']['authList'] = $authList;
|
||||
}
|
||||
|
||||
// 将服务端额外字段放入meta中
|
||||
$extraFields = static::getExtraFields($item);
|
||||
if (!empty($extraFields)) {
|
||||
$menuItem['meta'] = array_merge($menuItem['meta'], $extraFields);
|
||||
}
|
||||
|
||||
// 递归处理子菜单
|
||||
$children = static::buildMenuTree($data, $item['id']);
|
||||
if (!empty($children)) {
|
||||
$menuItem['children'] = $children;
|
||||
}
|
||||
|
||||
$tree[] = $menuItem;
|
||||
}
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用引用方式构建前端需要的菜单树结构(性能更好)
|
||||
*
|
||||
* @param array $data 服务端菜单数据
|
||||
* @return array
|
||||
*/
|
||||
public static function buildMenuTreeWithReference(array $data): array
|
||||
{
|
||||
$items = [];
|
||||
$tree = [];
|
||||
|
||||
// 过滤出菜单类型的节点并转换数据结构
|
||||
$menuData = array_filter($data, function($item) {
|
||||
return ($item['type'] ?? '') != 'permission';
|
||||
});
|
||||
|
||||
// 建立以id为索引的数组并转换数据结构
|
||||
foreach ($menuData as $item) {
|
||||
$items[$item['id']] = [
|
||||
'id' => $item['id'],
|
||||
'path' => $item['url'] ?? '',
|
||||
'name' => $item['name'],
|
||||
'component' => $item['url'] ?? '',
|
||||
'meta' => [
|
||||
'title' => $item['name'],
|
||||
'icon' => $item['icon'] ?? '',
|
||||
'isHide' => !empty($item['is_hide']),
|
||||
'isHideTab' => !empty($item['is_hide_tab']),
|
||||
'keepAlive' => !empty($item['keep_alive']),
|
||||
]
|
||||
];
|
||||
|
||||
// 将服务端额外字段放入meta中
|
||||
$extraFields = static::getExtraFields($item);
|
||||
if (!empty($extraFields)) {
|
||||
$items[$item['id']]['meta'] = array_merge($items[$item['id']]['meta'], $extraFields);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建树形结构
|
||||
foreach ($menuData as $item) {
|
||||
if ($item['parent_id'] == 0) {
|
||||
$tree[] = &$items[$item['id']];
|
||||
} else {
|
||||
if (isset($items[$item['parent_id']])) {
|
||||
if (!isset($items[$item['parent_id']]['children'])) {
|
||||
$items[$item['parent_id']]['children'] = [];
|
||||
}
|
||||
$items[$item['parent_id']]['children'][] = &$items[$item['id']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 为每个节点添加权限列表
|
||||
foreach ($items as &$item) {
|
||||
$parentId = $item['id'];
|
||||
$permissions = static::collectDirectPermissions($data, $parentId);
|
||||
if (!empty($permissions)) {
|
||||
$authList = [];
|
||||
foreach ($permissions as $permission) {
|
||||
$authList[] = [
|
||||
'id' => $permission['id'],
|
||||
'title' => $permission['name'] ?? '',
|
||||
'authMark' => $permission['code'] ?? ''
|
||||
];
|
||||
}
|
||||
$item['meta']['authList'] = $authList;
|
||||
}
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集指定节点下的直接权限项(只收集直接子节点中的权限)
|
||||
*
|
||||
* @param array $data 数据列表
|
||||
* @param int $parentId 父级ID
|
||||
* @return array
|
||||
*/
|
||||
public static function collectDirectPermissions(array $data, int $parentId): array
|
||||
{
|
||||
$permissions = [];
|
||||
|
||||
foreach ($data as $item) {
|
||||
// 收集直接子节点中的权限类型
|
||||
if ($item['parent_id'] == $parentId && ($item['type'] ?? '') == 'permission') {
|
||||
$permissions[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要放入meta的额外字段
|
||||
*
|
||||
* @param array $item 菜单项
|
||||
* @return array
|
||||
*/
|
||||
public static function getExtraFields(array $item): array
|
||||
{
|
||||
$extraFields = [];
|
||||
$standardFields = [
|
||||
'id', 'name', 'url', 'icon', 'is_hide', 'is_hide_tab', 'keep_alive', 'level'
|
||||
];
|
||||
|
||||
foreach ($item as $key => $value) {
|
||||
// 如果不是标准字段且不是auth_list,则放入extraFields
|
||||
if (!in_array($key, $standardFields) && $key !== 'auth_list') {
|
||||
// 转换下划线命名到驼峰命名
|
||||
$camelKey = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key))));
|
||||
$extraFields[$camelKey] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $extraFields;
|
||||
}
|
||||
}
|
||||
@@ -156,8 +156,11 @@ class Generate
|
||||
protected function deleteFileIfExists($path)
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
unlink($path);
|
||||
echo "删除已存在文件: <comment>{$path}</comment> \n";
|
||||
"文件: <comment>{$path}</comment> 已存在,核对后手动删除。\n";
|
||||
return;
|
||||
|
||||
// unlink($path);
|
||||
// echo "删除已存在文件: <comment>{$path}</comment> \n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>邮箱提醒</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.header {
|
||||
padding: 20px;
|
||||
background-color: #0056b3;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
background-color: #0056b3;
|
||||
color: white !important;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.footer {
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #777777;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
@media only screen and (max-width: 480px) {
|
||||
.email-container {
|
||||
width: 100%;
|
||||
}
|
||||
.button {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!--[if mso]>
|
||||
<style type="text/css">
|
||||
.button {
|
||||
background-color: #0056b3 !important;
|
||||
color: white !important;
|
||||
}
|
||||
</style>
|
||||
<![endif]-->
|
||||
|
||||
<table class="email-container" width="100%" cellspacing="0" cellpadding="0" border="0" align="center">
|
||||
<tr>
|
||||
<td class="header">
|
||||
<h1>工单提醒</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content">
|
||||
<p>你好,</p>
|
||||
<p>你有新的工单待处理。请及时查看:</p>
|
||||
|
||||
<ul>
|
||||
<li>工单编号:{{code}}</li>
|
||||
<li>工单分类:{{category}}</li>
|
||||
<li>问题描述:{{content}}</li>
|
||||
</ul>
|
||||
|
||||
<p>请点击下方按钮立即查看详情:</p>
|
||||
|
||||
<div style="text-align: center;">
|
||||
<a href="https://x.hnxinyouhe.com" class="button" style="color: white; text-decoration: none;">立即查看</a>
|
||||
</div>
|
||||
|
||||
<!--<p>如果您未请求此操作,请忽略此邮件或联系我们的客服团队。</p>-->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="footer">
|
||||
<p>© 2025 河南新友合科技有限公司. 保留所有权利。</p>
|
||||
<p>这是系统自动发送的邮件,请勿直接回复。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class CorpFeishuAppValidate extends Validate
|
||||
{
|
||||
// 规则
|
||||
protected $rule = [
|
||||
|
||||
];
|
||||
|
||||
// 提示
|
||||
protected $message = [
|
||||
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'store' => [
|
||||
|
||||
],
|
||||
|
||||
'update' => [
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class CountryValidate extends Validate
|
||||
{
|
||||
// 规则
|
||||
protected $rule = [
|
||||
|
||||
];
|
||||
|
||||
// 提示
|
||||
protected $message = [
|
||||
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'store' => [
|
||||
|
||||
],
|
||||
|
||||
'update' => [
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class ResourceValidate extends Validate
|
||||
{
|
||||
// 规则
|
||||
protected $rule = [
|
||||
|
||||
];
|
||||
|
||||
// 提示
|
||||
protected $message = [
|
||||
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'store' => [
|
||||
|
||||
],
|
||||
|
||||
'update' => [
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class RoleValidate extends Validate
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'store' => ['system_id', 'name', 'desc', 'sort'],
|
||||
'update' => ['id', 'system_id', 'name', 'desc', 'sort', 'status'],
|
||||
'store' => ['name', 'desc', 'sort'],
|
||||
'update' => ['id', 'name', 'desc', 'sort', 'status'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class UserValidate extends Validate
|
||||
'feishu_register' => ['feishu_code'],
|
||||
'upwd_login' => ['account' => 'require|checkAccount', 'password'],
|
||||
'feishu_auth' => ['corp_abbr', 'system_code', 'login_type'],
|
||||
'feishu_login' => ['feishu_code']
|
||||
'feishu_login' => ['feishu_code'],
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,27 +75,27 @@ class IndexController
|
||||
public function createResource()
|
||||
{
|
||||
$options = [
|
||||
// 'controller' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
'controller' => [
|
||||
'module' => 'common',
|
||||
'name' => 'resources'
|
||||
],
|
||||
'model' => [
|
||||
'module' => 'common',
|
||||
'name' => 'email_parsed_result'
|
||||
'name' => 'resources'
|
||||
],
|
||||
// 'service' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
// 'logic' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
// 'validate' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
'table' => 'email_parsed_result'
|
||||
'service' => [
|
||||
'module' => 'common',
|
||||
'name' => 'resources'
|
||||
],
|
||||
'logic' => [
|
||||
'module' => 'common',
|
||||
'name' => 'resources'
|
||||
],
|
||||
'validate' => [
|
||||
'module' => 'common',
|
||||
'name' => 'resources'
|
||||
],
|
||||
'table' => 'resources'
|
||||
];
|
||||
|
||||
$result = (new Generate($options))->doGenerate();
|
||||
@@ -106,13 +106,21 @@ class IndexController
|
||||
public function test()
|
||||
{
|
||||
|
||||
$uidRotator = new \app\common\utils\RedisUidRotator('email_parsed_result_20250804');
|
||||
$uidRotator->setUids([64, 63, 83, 93, 108, 118, 131, 132, 145, 150, 143, 156, 157, 158]);
|
||||
// $data = [
|
||||
// 'code' => 'GD20250703-1DC80',
|
||||
// 'category' => '账号类问题',
|
||||
// 'content' => '这是一条测试工单内容。'
|
||||
// ];
|
||||
// \app\common\utils\email\MailSend::send('mzl@hnxinyouhe.com', '【XYH】新的工单提醒', replaceTpl($data, 'work_order'));
|
||||
|
||||
$assignedUid = $uidRotator->next();
|
||||
// $options = [
|
||||
// 'corp_id' => 3,
|
||||
// 'user_id' => 666
|
||||
// ];
|
||||
// \Webman\RedisQueue\Redis::send('perm-agt', $options);
|
||||
|
||||
flg($assignedUid, false);
|
||||
$res = Cache::delete("user_resources_74_fdesk");
|
||||
|
||||
return $assignedUid;
|
||||
return 22;
|
||||
}
|
||||
}
|
||||
@@ -325,6 +325,7 @@ class CustomerController extends BaseController
|
||||
'lng' => Util::getParam($request, 'lng', 0),
|
||||
'address' => Util::getParam($request, 'address', ''),
|
||||
'sex' => Util::getParam($request, 'sex', 0),
|
||||
'obtain' => time(),
|
||||
];
|
||||
|
||||
if (Util::isEmpty($id)) {
|
||||
@@ -393,13 +394,31 @@ class CustomerController extends BaseController
|
||||
if(empty($customer)){
|
||||
return $this->error( trans('fail'));
|
||||
}
|
||||
if($force == 'force'){
|
||||
//强制删除
|
||||
$res = $customer->forceDelete();
|
||||
}else{
|
||||
//软删除
|
||||
$res = $customer->delete();
|
||||
try {
|
||||
Db::beginTransaction();
|
||||
if ($force == 'force') {
|
||||
//强制删除
|
||||
$res = $customer->forceDelete();
|
||||
} else {
|
||||
$customer->user_id = 0;
|
||||
$customer->save();
|
||||
|
||||
//记录客户关系变化
|
||||
$his = CustomerHis::create([
|
||||
'customer_id' => $id,
|
||||
'user_his' => $userId,
|
||||
'user_id' => 0,
|
||||
]);
|
||||
|
||||
//软删除
|
||||
$res = $customer->delete();
|
||||
}
|
||||
Db::commit();
|
||||
} catch (\Throwable $e) {
|
||||
Db::rollback();
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
if ($res) {
|
||||
return $this->success($res, trans('success'));
|
||||
} else {
|
||||
@@ -485,10 +504,10 @@ class CustomerController extends BaseController
|
||||
return $this->error(trans('customer_id').trans('not_null'));
|
||||
}
|
||||
$data = [
|
||||
'user_id' => $request->user->uid
|
||||
'user_id' => $request->user->uid,
|
||||
'obtain' => time(),
|
||||
];
|
||||
|
||||
|
||||
try {
|
||||
Db::beginTransaction();
|
||||
$customer= Customer::withTrashed()->find($customerId);
|
||||
@@ -526,8 +545,6 @@ class CustomerController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 批量转让
|
||||
* @param Request $request
|
||||
@@ -543,10 +560,11 @@ class CustomerController extends BaseController
|
||||
return $this->error( trans('user_none'));
|
||||
}
|
||||
|
||||
$query= Customer::whereIn('id',explode(',',$customerId));
|
||||
$query= Customer::withTrashed()->whereIn('id',explode(',',$customerId));
|
||||
try {
|
||||
$customer = $query->get();
|
||||
|
||||
Db::beginTransaction();
|
||||
foreach ($customer as $item) {
|
||||
//记录客户关系变化
|
||||
$his = CustomerHis::create([
|
||||
@@ -561,8 +579,15 @@ class CustomerController extends BaseController
|
||||
$inquiryLog->save();
|
||||
}
|
||||
}
|
||||
|
||||
$item->restore();
|
||||
}
|
||||
$res = $query->update(['user_id' => $user->id]);
|
||||
|
||||
$data = [
|
||||
'user_id' => $user->id,
|
||||
'obtain' => time(),
|
||||
];
|
||||
$res = $query->update($data);
|
||||
|
||||
Db::commit();
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -79,4 +79,31 @@ class Customer extends Model
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::saved(function ($customer) {
|
||||
if (empty($customer->code)) {
|
||||
$customer->code = self::generateCustomerCode($customer);
|
||||
// 使用saveQuietly避免递归调用
|
||||
$customer->saveQuietly();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function generateCustomerCode($customer)
|
||||
{
|
||||
// 生成唯一16位code,CM+14位
|
||||
$unique = strtoupper(substr(md5($customer->id . microtime(true) . mt_rand(1000, 9999)), 8, 6));
|
||||
$code = 'CM' . date('Ymd') .$unique;
|
||||
return $code;
|
||||
}
|
||||
|
||||
// 静默保存方法,不触发事件
|
||||
public function saveQuietly(array $options = [])
|
||||
{
|
||||
return static::withoutEvents(function () use ($options) {
|
||||
return $this->save($options);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ class CustomerService
|
||||
$follow = $params['follow'] ?? '';
|
||||
$follow_last = $params['follow_last'] ?? '';
|
||||
$tagId = $params['tag_id'] ?? [];
|
||||
$countryId = $params['country_id'] ?? '';
|
||||
$where = [];
|
||||
$user_id =$params['user_id'];
|
||||
|
||||
@@ -49,6 +50,9 @@ class CustomerService
|
||||
}
|
||||
$where[] = ['status', 1];
|
||||
|
||||
if (!empty($countryId)){
|
||||
$where[] = ['country_id', $countryId];
|
||||
}
|
||||
|
||||
$grade = [];
|
||||
if (!Util::isEmpty($follow) && $follow == 0) {
|
||||
@@ -84,7 +88,10 @@ class CustomerService
|
||||
if (!Util::isEmpty($keyword)) {
|
||||
$query->where(function ($query) use ($keyword) {
|
||||
$query->where('contacts', 'like', "%{$keyword}%")
|
||||
->orWhere('phone', 'like', "%{$keyword}%");
|
||||
->orWhere('phone', 'like', "%{$keyword}%")
|
||||
->orWhere('email', 'like', "%{$keyword}%")
|
||||
->orWhere('WhatsApp', 'like', "%{$keyword}%")
|
||||
->orWhere('code', 'like', "%{$keyword}%");
|
||||
});
|
||||
}
|
||||
if (!Util::isEmpty($grade)) {
|
||||
@@ -148,9 +155,16 @@ class CustomerService
|
||||
switch ($scene) {
|
||||
case 'index':
|
||||
$config['where']['status'] = 1; // 关键字
|
||||
if (isset($p['user_id']) && $p['user_id']) {
|
||||
$config['where']['user_id'] = $p['user_id'];
|
||||
} // 关键字
|
||||
if (isset($p['keyword']) && $p['keyword']) {
|
||||
$k = '%' . $p['keyword'] . '%';
|
||||
$config['where']['contacts'] = ['like', $k];
|
||||
$config['orWhere'][] = ['contacts','like', $k];
|
||||
$config['orWhere'][] = ['phone','like', $k];
|
||||
$config['orWhere'][] = ['email','like', $k];
|
||||
$config['orWhere'][] = ['WhatsApp','like', $k];
|
||||
$config['orWhere'][] = ['code','like', $k];
|
||||
}
|
||||
$config['order']['id'] = 'desc';
|
||||
$config['dataLimit']['type'] = 'relation';
|
||||
@@ -162,6 +176,11 @@ class CustomerService
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无用线索举报
|
||||
* @param $params
|
||||
* @return false
|
||||
*/
|
||||
public function report($params)
|
||||
{
|
||||
$id = $params['id'];
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace app\crmAdmin\controller;
|
||||
|
||||
use app\common\model\Corp;
|
||||
use app\crm\model\Customer;
|
||||
use app\crmAdmin\service\CustomerService;
|
||||
use support\Request;
|
||||
|
||||
@@ -133,6 +134,37 @@ class CustomerController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function delete(Request $request)
|
||||
{
|
||||
try {
|
||||
$param = $request->all();
|
||||
if (empty($param['customer_id'])) {
|
||||
return $this->error('customer_id'.trans('not_null'));
|
||||
}
|
||||
|
||||
$where = [
|
||||
'id' => $param['customer_id'],
|
||||
];
|
||||
$customer = Customer::where($where)->withTrashed()->first();
|
||||
if(empty($customer)){
|
||||
return $this->error( trans('fail'));
|
||||
}
|
||||
//软删除
|
||||
$customer->status = 3;
|
||||
$res = $customer->save();
|
||||
$customer->delete();
|
||||
|
||||
return $this->success($res);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户详情
|
||||
* @param Request $request
|
||||
@@ -154,4 +186,25 @@ class CustomerController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户详情
|
||||
* @param Request $request
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function follow(Request $request)
|
||||
{
|
||||
try {
|
||||
$param = $request->all();
|
||||
if (empty($param['id'])) {
|
||||
return $this->error('id'.trans('not_null'));
|
||||
}
|
||||
|
||||
$result = (new CustomerService())->follow($param);
|
||||
|
||||
return $this->success($result);
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,10 @@ class CustomerLogic
|
||||
$customer->status = $status;
|
||||
$res = $customer->save();
|
||||
|
||||
if($status == 1){
|
||||
$customer->restore();
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
@@ -20,7 +24,9 @@ class CustomerLogic
|
||||
{
|
||||
$customer = Customer::withTrashed()->find($id);
|
||||
//强制删除
|
||||
$res = $customer->forceDelete();
|
||||
// $res = $customer->forceDelete();
|
||||
$customer->status = 3;
|
||||
$res = $customer->save();
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace app\crmAdmin\service;
|
||||
|
||||
use app\common\model\InquiryLog;
|
||||
use app\common\model\User;
|
||||
use app\common\service\OssService;
|
||||
use app\crm\model\CustomerHis;
|
||||
use app\crmAdmin\logic\CustomerLogic;
|
||||
use app\crm\model\CarType;
|
||||
@@ -104,16 +105,22 @@ class CustomerService
|
||||
if (!Util::isEmpty($keyword)) {
|
||||
$query->where(function ($query) use ($keyword) {
|
||||
$query->where('contacts', 'like', "%{$keyword}%")
|
||||
->orWhere('phone', 'like', "%{$keyword}%");
|
||||
->orWhere('phone', 'like', "%{$keyword}%")
|
||||
->orWhere('email', 'like', "%{$keyword}%")
|
||||
->orWhere('WhatsApp', 'like', "%{$keyword}%")
|
||||
->orWhere('code', 'like', "%{$keyword}%");
|
||||
});
|
||||
}
|
||||
if (!Util::isEmpty($grade)) {
|
||||
$query->whereIn('grade', $grade);
|
||||
}
|
||||
|
||||
if ($recycle == 'recycle' || $scene == 'recycle' || $seas == 'seas' || $scene == 'seas' || $scene == 'audit') {
|
||||
if ($recycle == 'recycle' || $scene == 'recycle' || $scene == 'audit') {
|
||||
$query->onlyTrashed();
|
||||
}
|
||||
if ($seas == 'seas' || $scene == 'seas') {
|
||||
$query->withTrashed();
|
||||
}
|
||||
|
||||
if (!$export) {
|
||||
$customer = $query->orderBy('id', 'desc')->paginate($perPage, ['*'], 'page', $page);
|
||||
@@ -124,9 +131,10 @@ class CustomerService
|
||||
if (!$export) {
|
||||
foreach ($customer as &$item) {
|
||||
$item = $this->getCustomer($item);
|
||||
$item['desc_collect'] = $item['desc_collect'] ?? '';
|
||||
$item['follow_next'] = empty($item['follow_next'])?'':date('Y-m-d H:i:s', $item['follow_next']);
|
||||
if ($seas == 'seas' || $scene == 'seas') {
|
||||
$item['seas_time'] = time() - strtotime($item['deleted_at']);
|
||||
$item['seas_time'] = time() - (empty($item['deleted_at'])?strtotime($item['updated_at']):strtotime($item['deleted_at']));
|
||||
}
|
||||
if ($scene == 'audit') { //审核时查询举报人姓名
|
||||
$customerHis = CustomerHis::where('customer_id', $item->id)->orderBy('id', 'desc')->first(['user_his']);
|
||||
@@ -315,7 +323,42 @@ class CustomerService
|
||||
}
|
||||
}
|
||||
}
|
||||
$res = $query->update(['user_id' => $userId]);
|
||||
$data = [
|
||||
'user_id' => $userId,
|
||||
'obtain' => time(),
|
||||
];
|
||||
$res = $query->update($data);
|
||||
|
||||
Db::commit();
|
||||
return $res;
|
||||
} catch (\Throwable $e) {
|
||||
Db::rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($params)
|
||||
{
|
||||
try {
|
||||
Db::beginTransaction();
|
||||
$customerId = $params['customer_id'];
|
||||
|
||||
$query= Customer::whereIn('id',explode(',',$customerId));
|
||||
$customer = $query->get();
|
||||
|
||||
foreach ($customer as $item) {
|
||||
//记录客户关系变化
|
||||
$his = CustomerHis::create([
|
||||
'customer_id' => $item->id,
|
||||
'user_his' => $item->user_id,
|
||||
'user_id' => 0,
|
||||
]);
|
||||
}
|
||||
$res = $query->update(['user_id' => 0]);
|
||||
|
||||
Db::commit();
|
||||
return $res;
|
||||
@@ -394,4 +437,19 @@ class CustomerService
|
||||
|
||||
return $customer;
|
||||
}
|
||||
|
||||
public function follow($params)
|
||||
{
|
||||
$id = $params['id'];
|
||||
$follow = Follow::
|
||||
where('customer_id', $id)
|
||||
->get();
|
||||
|
||||
$ossservice = new OssService();
|
||||
foreach ($follow as $item) {
|
||||
$item['picture_full'] = empty($item->picture)?'':$ossservice->generatePrivateUrl($item->picture);
|
||||
}
|
||||
|
||||
return $follow;
|
||||
}
|
||||
}
|
||||
+17
-2
@@ -158,9 +158,10 @@ if (!function_exists('sendFeishuTextMessage')) {
|
||||
* 替换模板
|
||||
*/
|
||||
if (!function_exists('replaceTpl')) {
|
||||
function replaceTpl(array $data = [], string $templatePath = 'common/utils/scaffold/templates/Email.stub')
|
||||
function replaceTpl(array $data = [], string $tplKey = 'email')
|
||||
{
|
||||
if (!$data || !$templatePath) return '';
|
||||
if (!$data || !$tplKey) return '';
|
||||
$templatePath = tplUrl($tplKey);
|
||||
$templatePath = app_path($templatePath);
|
||||
$content = file_get_contents($templatePath);
|
||||
foreach ($data as $key => $value) {
|
||||
@@ -170,6 +171,20 @@ if (!function_exists('replaceTpl')) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板路径
|
||||
*/
|
||||
if (!function_exists('tplUrl')) {
|
||||
function tplUrl(string $tplKey = '')
|
||||
{
|
||||
$urlArray = [
|
||||
'email' => 'common/utils/scaffold/templates/Email.stub',
|
||||
'work_order' => 'common/utils/scaffold/templates/workOrder.stub'
|
||||
];
|
||||
return $urlArray[$tplKey];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换模板
|
||||
*/
|
||||
|
||||
@@ -101,7 +101,7 @@ class StatisticsController extends BaseController
|
||||
{
|
||||
$list = InquiryLog::with(["recipientInfo"])
|
||||
->where("recipient", ">", 0)
|
||||
->whereNotIn('recipient', [1,5,10,11,13,15,16,17,19,74,75,78,141,147])
|
||||
->whereNotIn('recipient', [1,5,10,11,13,155,16,17,19,74,75,78,141,147])
|
||||
->select('recipient', Db::raw('COUNT(*) as totals'))
|
||||
->groupBy('recipient')
|
||||
->get();
|
||||
|
||||
@@ -60,6 +60,7 @@ class InquiryToCrm implements Consumer
|
||||
$crmCustomer->contacts = $info->contacts;
|
||||
$crmCustomer->desc_collect = $info->content;
|
||||
$crmCustomer->enter_user_id = $info->enter_user_id;
|
||||
$crmCustomer->obtain = time();
|
||||
// 修改同步CRM状态
|
||||
$info->sync_crm = 1;
|
||||
// 保存
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace app\queue\redis;
|
||||
|
||||
use support\Db;
|
||||
use support\exception\BusinessException;
|
||||
use Webman\RedisQueue\Consumer;
|
||||
|
||||
class PermAgt implements Consumer
|
||||
{
|
||||
// 要消费的队列名
|
||||
public $queue = 'perm-agt';
|
||||
|
||||
// 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
|
||||
public $connection = 'default';
|
||||
|
||||
// 消费
|
||||
public function consume($data)
|
||||
{
|
||||
try {
|
||||
|
||||
$corpId = $data['corp_id'];
|
||||
$userId = $data['user_id'];
|
||||
|
||||
if ($corpId == 2) {
|
||||
$roles = [
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'role_id' => 1
|
||||
],
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'role_id' => 2
|
||||
],
|
||||
];
|
||||
$systems = [
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'system_id' => 1
|
||||
],
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'system_id' => 2
|
||||
],
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'system_id' => 3
|
||||
],
|
||||
];
|
||||
} else {
|
||||
$roles = [
|
||||
'user_id' => $userId,
|
||||
'role_id' => 2
|
||||
];
|
||||
$systems = [
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'system_id' => 2
|
||||
],
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'system_id' => 3
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
Db::table('user_roles')->insert($roles);
|
||||
Db::table('user_systems')->insert($systems);
|
||||
return true;
|
||||
} catch (\Throwable $th) {
|
||||
throw new BusinessException($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 消费失败回调
|
||||
/*
|
||||
$package = [
|
||||
'id' => 1357277951, // 消息ID
|
||||
'time' => 1709170510, // 消息时间
|
||||
'delay' => 0, // 延迟时间
|
||||
'attempts' => 2, // 消费次数
|
||||
'queue' => 'send-mail', // 队列名
|
||||
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
|
||||
'max_attempts' => 5, // 最大重试次数
|
||||
'error' => '错误信息' // 错误信息
|
||||
]
|
||||
*/
|
||||
public function onConsumeFailure(\Throwable $e, $package)
|
||||
{
|
||||
echo "consume failure\n";
|
||||
echo $e->getMessage() . "\n";
|
||||
// 无需反序列化
|
||||
var_export($package);
|
||||
}
|
||||
}
|
||||
+51
-9
@@ -52,12 +52,17 @@ Route::group('/common', function () {
|
||||
Route::group('/user', function () {
|
||||
Route::any('/info', [app\common\controller\UserController::class, 'info']);
|
||||
Route::any('/get', [app\common\controller\UserController::class, 'getUser']);
|
||||
Route::any('/team', [app\common\controller\UserController::class, 'team']);
|
||||
Route::any('/resign', [app\common\controller\UserController::class, 'resignMember']);
|
||||
});
|
||||
|
||||
Route::group('/preset', function () {
|
||||
Route::any('/corps', [app\common\controller\PresetController::class, 'corps']);
|
||||
Route::any('/feishu/app', [app\common\controller\PresetController::class, 'feishuApp']);
|
||||
Route::any('/systems', [app\common\controller\PresetController::class, 'systems']);
|
||||
Route::any('/roles', [app\common\controller\PresetController::class, 'roles']);
|
||||
Route::any('/cache/clear', [app\common\controller\PresetController::class, 'cacheClear']);
|
||||
Route::any('/menus', [app\common\controller\PresetController::class, 'menus']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -70,13 +75,7 @@ Route::group('/admin', function () {
|
||||
Route::any('/store', [app\admin\controller\RoleController::class, 'store']);
|
||||
Route::any('/update', [app\admin\controller\RoleController::class, 'update']);
|
||||
Route::any('/destroy', [app\admin\controller\RoleController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// 用户
|
||||
Route::group('/user', function () {
|
||||
Route::any('/list', [app\admin\controller\UserController::class, 'index']);
|
||||
Route::any('/show', [app\admin\controller\UserController::class, 'show']);
|
||||
Route::any('/update', [app\admin\controller\UserController::class, 'update']);
|
||||
Route::any('/menu/resource', [app\admin\controller\RoleController::class, 'menuResource']);
|
||||
});
|
||||
|
||||
// 公司
|
||||
@@ -88,6 +87,46 @@ Route::group('/admin', function () {
|
||||
Route::any('/destroy', [app\admin\controller\CorpController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// 系统
|
||||
Route::group('/systems', function () {
|
||||
Route::any('/list', [app\admin\controller\SystemsController::class, 'index']);
|
||||
Route::any('/show', [app\admin\controller\SystemsController::class, 'show']);
|
||||
Route::any('/store', [app\admin\controller\SystemsController::class, 'store']);
|
||||
Route::any('/update', [app\admin\controller\SystemsController::class, 'update']);
|
||||
Route::any('/destroy', [app\admin\controller\SystemsController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// 飞书应用
|
||||
Route::group('/corp/feishu', function () {
|
||||
Route::any('/list', [app\admin\controller\CorpFeishuAppController::class, 'index']);
|
||||
Route::any('/show', [app\admin\controller\CorpFeishuAppController::class, 'show']);
|
||||
Route::any('/store', [app\admin\controller\CorpFeishuAppController::class, 'store']);
|
||||
Route::any('/update', [app\admin\controller\CorpFeishuAppController::class, 'update']);
|
||||
Route::any('/destroy', [app\admin\controller\CorpFeishuAppController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// 资源
|
||||
Route::group('/resources', function () {
|
||||
Route::any('/list/tree', [app\common\controller\ResourceController::class, 'listTree']);
|
||||
Route::any('/show', [app\common\controller\ResourceController::class, 'show']);
|
||||
Route::any('/store', [app\common\controller\ResourceController::class, 'store']);
|
||||
Route::any('/update', [app\common\controller\ResourceController::class, 'update']);
|
||||
Route::any('/destroy', [app\common\controller\ResourceController::class, 'destroy']);
|
||||
Route::any('/list/menu', [app\common\controller\ResourceController::class, 'menuList']);
|
||||
Route::any('/list/menu/tree', [app\common\controller\ResourceController::class, 'menuTreeList']);
|
||||
});
|
||||
|
||||
// 用户
|
||||
Route::group('/user', function () {
|
||||
Route::any('/list', [app\admin\controller\UserController::class, 'index']);
|
||||
Route::any('/show', [app\admin\controller\UserController::class, 'show']);
|
||||
Route::any('/update', [app\admin\controller\UserController::class, 'update']);
|
||||
Route::any('/edit', [app\admin\controller\UserController::class, 'edit']);
|
||||
Route::any('/authorize', [app\admin\controller\UserController::class, 'authorize']);
|
||||
Route::any('/set/resources', [app\admin\controller\UserController::class, 'updateResources']);
|
||||
Route::any('/update/password', [app\admin\controller\UserController::class, 'savePassword']);
|
||||
});
|
||||
|
||||
// 询单
|
||||
Route::group('/inquiry', function () {
|
||||
Route::any('/list', [app\inquiry\controller\InquiryLogController::class, 'index']);
|
||||
@@ -117,6 +156,9 @@ Route::group('/admin', function () {
|
||||
Route::any('/audit', [app\crmAdmin\controller\CustomerController::class, 'audit']);
|
||||
Route::any('/transfer', [app\crmAdmin\controller\CustomerController::class, 'transfer']);
|
||||
Route::any('/detail', [app\crmAdmin\controller\CustomerController::class, 'detail']);
|
||||
Route::any('/delete', [app\crmAdmin\controller\CustomerController::class, 'delete']);
|
||||
Route::any('/cede', [app\crm\controller\CustomerController::class, 'cede']);
|
||||
Route::any('/follow', [app\crmAdmin\controller\CustomerController::class, 'follow']);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -177,7 +219,7 @@ Route::group('/crm', function () {
|
||||
Route::any('/upload/image', [app\common\controller\UploadController::class, 'uploadImage']);
|
||||
|
||||
|
||||
Route::any('/user/edit', [app\common\controller\UserController::class, 'edit']);
|
||||
Route::any('/user/savePassword', [app\common\controller\UserController::class, 'savePassword']);
|
||||
Route::any('/user/edit', [app\common\controller\UserController::class, 'edit']);
|
||||
Route::any('/user/savePassword', [app\common\controller\UserController::class, 'savePassword']);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user