diff --git a/app/admin/controller/CorpFeishuAppController.php b/app/admin/controller/CorpFeishuAppController.php
new file mode 100644
index 0000000..59e685d
--- /dev/null
+++ b/app/admin/controller/CorpFeishuAppController.php
@@ -0,0 +1,33 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/CountryController.php b/app/admin/controller/CountryController.php
new file mode 100644
index 0000000..8cc8458
--- /dev/null
+++ b/app/admin/controller/CountryController.php
@@ -0,0 +1,33 @@
+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;
+ // }
+}
\ No newline at end of file
diff --git a/app/admin/controller/RoleController.php b/app/admin/controller/RoleController.php
index 691e070..a08ff7e 100644
--- a/app/admin/controller/RoleController.php
+++ b/app/admin/controller/RoleController.php
@@ -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());
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/SystemsController.php b/app/admin/controller/SystemsController.php
index 9c300ac..3c062c5 100644
--- a/app/admin/controller/SystemsController.php
+++ b/app/admin/controller/SystemsController.php
@@ -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;
+ }
}
\ No newline at end of file
diff --git a/app/admin/controller/UserController.php b/app/admin/controller/UserController.php
index dfcebd7..25f2385 100644
--- a/app/admin/controller/UserController.php
+++ b/app/admin/controller/UserController.php
@@ -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());
+ }
+ }
}
\ No newline at end of file
diff --git a/app/admin/logic/UserLogic.php b/app/admin/logic/UserLogic.php
index de0d15d..d70b6de 100644
--- a/app/admin/logic/UserLogic.php
+++ b/app/admin/logic/UserLogic.php
@@ -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;
+ }
+ }
}
\ No newline at end of file
diff --git a/app/admin/service/CorpFeishuAppService.php b/app/admin/service/CorpFeishuAppService.php
new file mode 100644
index 0000000..e64631b
--- /dev/null
+++ b/app/admin/service/CorpFeishuAppService.php
@@ -0,0 +1,70 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/CountryService.php b/app/admin/service/CountryService.php
new file mode 100644
index 0000000..4139d97
--- /dev/null
+++ b/app/admin/service/CountryService.php
@@ -0,0 +1,31 @@
+validator;
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/RoleService.php b/app/admin/service/RoleService.php
index 248bc3d..f2ee190 100644
--- a/app/admin/service/RoleService.php
+++ b/app/admin/service/RoleService.php
@@ -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);
+ }
}
\ No newline at end of file
diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php
index f2e07fd..4d23710 100644
--- a/app/admin/service/UserService.php
+++ b/app/admin/service/UserService.php
@@ -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;
+ }
}
\ No newline at end of file
diff --git a/app/command/CustomerCodeCommand.php b/app/command/CustomerCodeCommand.php
index 2d3e447..a82ec0f 100644
--- a/app/command/CustomerCodeCommand.php
+++ b/app/command/CustomerCodeCommand.php
@@ -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;
diff --git a/app/common/controller/PresetController.php b/app/common/controller/PresetController.php
index ad88a8f..37073c4 100644
--- a/app/common/controller/PresetController.php
+++ b/app/common/controller/PresetController.php
@@ -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());
+ }
+ }
}
\ No newline at end of file
diff --git a/app/common/controller/ResourceController.php b/app/common/controller/ResourceController.php
new file mode 100644
index 0000000..5fd35b9
--- /dev/null
+++ b/app/common/controller/ResourceController.php
@@ -0,0 +1,82 @@
+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());
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/common/controller/UserController.php b/app/common/controller/UserController.php
index d725166..f49fba0 100644
--- a/app/common/controller/UserController.php
+++ b/app/common/controller/UserController.php
@@ -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());
+ }
+ }
}
\ No newline at end of file
diff --git a/app/common/logic/AuthLogic.php b/app/common/logic/AuthLogic.php
index b2a74fc..9857df8 100644
--- a/app/common/logic/AuthLogic.php
+++ b/app/common/logic/AuthLogic.php
@@ -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'],
diff --git a/app/common/logic/CorpFeishuAppLogic.php b/app/common/logic/CorpFeishuAppLogic.php
index e246316..2613c6a 100644
--- a/app/common/logic/CorpFeishuAppLogic.php
+++ b/app/common/logic/CorpFeishuAppLogic.php
@@ -2,11 +2,18 @@
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)
{
diff --git a/app/common/logic/CountryLogic.php b/app/common/logic/CountryLogic.php
new file mode 100644
index 0000000..0a753ee
--- /dev/null
+++ b/app/common/logic/CountryLogic.php
@@ -0,0 +1,17 @@
+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,
diff --git a/app/common/logic/ResourceLogic.php b/app/common/logic/ResourceLogic.php
new file mode 100644
index 0000000..ddf6423
--- /dev/null
+++ b/app/common/logic/ResourceLogic.php
@@ -0,0 +1,37 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/common/logic/RoleLogic.php b/app/common/logic/RoleLogic.php
index bd8f121..0898b10 100644
--- a/app/common/logic/RoleLogic.php
+++ b/app/common/logic/RoleLogic.php
@@ -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();
+ }
}
diff --git a/app/common/logic/UserLogic.php b/app/common/logic/UserLogic.php
index 9f5ae44..c7d5343 100644
--- a/app/common/logic/UserLogic.php
+++ b/app/common/logic/UserLogic.php
@@ -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;
+
/**
* 用户信息
*/
diff --git a/app/common/model/CorpFeishuApp.php b/app/common/model/CorpFeishuApp.php
index 44a83ea..8019a0b 100644
--- a/app/common/model/CorpFeishuApp.php
+++ b/app/common/model/CorpFeishuApp.php
@@ -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');
+ }
+}
\ No newline at end of file
diff --git a/app/common/model/CrmCustomer.php b/app/common/model/CrmCustomer.php
index 49446e6..bc439db 100644
--- a/app/common/model/CrmCustomer.php
+++ b/app/common/model/CrmCustomer.php
@@ -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);
+ });
+ }
}
\ No newline at end of file
diff --git a/app/common/model/InquiryLog.php b/app/common/model/InquiryLog.php
index 68926aa..798b267 100644
--- a/app/common/model/InquiryLog.php
+++ b/app/common/model/InquiryLog.php
@@ -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()
diff --git a/app/common/model/Resource.php b/app/common/model/Resource.php
index 6fc54d9..bff7b0a 100644
--- a/app/common/model/Resource.php
+++ b/app/common/model/Resource.php
@@ -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 = [];
+}
\ No newline at end of file
diff --git a/app/common/model/User.php b/app/common/model/User.php
index 446ed46..88c670d 100644
--- a/app/common/model/User.php
+++ b/app/common/model/User.php
@@ -15,7 +15,8 @@ use support\Model;
* @property string $email 邮箱
* @property integer $status 状态
* @property string $system_code 系统码
- * @property string $created_at
+ * @property string $report_to 上级用户ID
+ * @property string $created_at
* @property string $updated_at
*/
class User extends Model
@@ -69,6 +70,7 @@ class User extends Model
'position',
'socialize',
'socialize_pic',
+ 'report_to',
];
// 用户所有角色
diff --git a/app/common/service/ResourceService.php b/app/common/service/ResourceService.php
index dce3bb1..ad3f85b 100644
--- a/app/common/service/ResourceService.php
+++ b/app/common/service/ResourceService.php
@@ -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;
}
}
\ No newline at end of file
diff --git a/app/common/service/UserService.php b/app/common/service/UserService.php
index 1d5dab4..53507b2 100644
--- a/app/common/service/UserService.php
+++ b/app/common/service/UserService.php
@@ -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;
+ }
}
\ No newline at end of file
diff --git a/app/common/traits/crud/CrudServiceTrait.php b/app/common/traits/crud/CrudServiceTrait.php
index 344756d..dd4536f 100644
--- a/app/common/traits/crud/CrudServiceTrait.php
+++ b/app/common/traits/crud/CrudServiceTrait.php
@@ -1,6 +1,7 @@
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');
// }
}
\ No newline at end of file
diff --git a/app/common/utils/Tree.php b/app/common/utils/Tree.php
new file mode 100644
index 0000000..b831185
--- /dev/null
+++ b/app/common/utils/Tree.php
@@ -0,0 +1,505 @@
+ $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;
+ }
+}
\ No newline at end of file
diff --git a/app/common/utils/scaffold/Generate.php b/app/common/utils/scaffold/Generate.php
index 753a9cf..eb82025 100644
--- a/app/common/utils/scaffold/Generate.php
+++ b/app/common/utils/scaffold/Generate.php
@@ -156,8 +156,11 @@ class Generate
protected function deleteFileIfExists($path)
{
if (file_exists($path)) {
- unlink($path);
- echo "删除已存在文件:
+ 工单提醒+ |
+
|
+ 你好, +你有新的工单待处理。请及时查看: + +
请点击下方按钮立即查看详情: + +
+ 立即查看
+
+
+
+ |
+
|
+ © 2025 河南新友合科技有限公司. 保留所有权利。 +这是系统自动发送的邮件,请勿直接回复。 + |
+