whitefang 1 год назад
Родитель
Сommit
0ece26d6df

+ 105 - 0
app/adminapi/controller/tenant/TenantAdminController.php

@@ -0,0 +1,105 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\tenant;
+
+use app\api\validate\PasswordValidate;
+use app\adminapi\controller\BaseAdminController;
+use app\adminapi\lists\tenant\TenantAdminLists;
+use app\adminapi\logic\tenant\TenantAdminLogic;
+use app\adminapi\validate\tenant\TenantAdminValidate;
+
+/**
+ * 租户账号用户控制器
+ * Class TenantController
+ * @package app\adminapi\controller\user
+ */
+class TenantAdminController extends BaseAdminController
+{
+
+    /**
+     * @notes 获取租户管理员账号 租户查询参数必传防止越权查看
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 22:11
+     */
+    public function lists()
+    {
+        return $this->dataLists(new TenantAdminLists());
+    }
+
+
+    /**
+     * @notes 获取租户管理员账号 租户id以及主键id查询参数必传 防止越权查看
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 22:14
+     */
+    public function detail()
+    {
+        $params = (new TenantAdminValidate())->goCheck('detail');
+        $result = TenantAdminLogic::detail($params['id']);
+        if (false === $result) {
+            return $this->fail(TenantAdminLogic::getError());
+        }
+        return $this->success('获取成功', $result);
+    }
+
+    /**
+     * @notes 创建租户管理员账号
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 22:58
+     */
+    public function add()
+    {
+        $params = (new TenantAdminValidate())->post()->goCheck('add');
+        $result = TenantAdminLogic::add($params);
+        if (true === $result) {
+            return $this->success('操作成功', [], 1, 1);
+        }
+        return $this->fail(TenantAdminLogic::getError());
+    }
+
+    /**
+     * @notes 编辑租户管理员账号
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 22:58
+     */
+    public function edit()
+    {
+        $params = (new TenantAdminValidate())->post()->goCheck('edit');
+        $result = TenantAdminLogic::edit($params);
+        if (true === $result) {
+            return $this->success('操作成功', [], 1, 1);
+        }
+        return $this->fail(TenantAdminLogic::getError());
+    }
+
+    /**
+     * @notes 删除租户管理员账号
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 22:59
+     */
+    public function delete()
+    {
+        $params = (new TenantAdminValidate())->post()->goCheck('delete');
+        $result = TenantAdminLogic::delete($params);
+        if (true === $result) {
+            return $this->success('删除成功', [], 1, 1);
+        }
+        return $this->fail(TenantAdminLogic::getError());
+    }
+}

+ 141 - 0
app/adminapi/controller/tenant/TenantController.php

@@ -0,0 +1,141 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\tenant;
+
+use app\common\model\dept\TenantDept;
+use app\adminapi\controller\BaseAdminController;
+use app\adminapi\lists\tenant\TenantLists;
+use app\adminapi\logic\setting\pay\PayConfigLogic;
+use app\adminapi\logic\setting\pay\PayWayLogic;
+use app\adminapi\logic\tenant\TenantAdminLogic;
+use app\adminapi\logic\tenant\TenantLogic;
+use app\adminapi\logic\tenant\TenantSystemMenuLogic;
+use app\adminapi\service\TenantCreatService;
+use app\adminapi\validate\tenant\TenantValidate;
+use app\tenantapi\logic\article\ArticleLogic;
+use app\tenantapi\logic\decorate\DecorateDataLogic;
+use app\tenantapi\logic\notice\NoticeLogic;
+use think\facade\Db;
+
+/**
+ * 用户控制器
+ * Class TenantController
+ * @package app\adminapi\controller\user
+ */
+class TenantController extends BaseAdminController
+{
+
+    /**
+     * @notes 用户列表
+     * @return \think\response\Json
+     * @author 段誉
+     * @date 2022/9/22 16:16
+     */
+    public function lists()
+    {
+        return $this->dataLists(new TenantLists());
+    }
+
+
+    /**
+     * @notes 获取用户详情
+     * @return \think\response\Json
+     * @author 段誉
+     * @date 2022/9/22 16:34
+     */
+    public function detail()
+    {
+        $params = (new TenantValidate())->goCheck('detail');
+        $result = TenantLogic::detail($params['id']);
+        if (false === $result) {
+            return $this->fail(TenantLogic::getError());
+        }
+        return $this->success('获取成功', $result);
+    }
+
+    /**
+     * @notes 新增租户信息 同步初始化对应租户信息
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/07 12:23
+     */
+    public function add()
+    {
+        $params = (new TenantValidate())->post()->goCheck('add');
+        try {
+            // 开始事务
+            DB::startTrans();
+            // 验证参数
+            // 创建租户基本信息
+            $tenant = TenantLogic::add($params);
+            // 判断用户是否采用分表模式
+            // todo 测试模式,全部采用分表模式
+            // $params['suitable'] = '1';
+            if (isset($params['tactics']) && $params['tactics'] == '1') {
+                (new TenantCreatService)->createTenantTable($tenant['sn']);
+                (new TenantCreatService)->initializationTenantData($tenant['id'],$tenant['sn'],$params);
+            }else{
+                // 初始化租户管理员账号
+                $managerInfo = TenantAdminLogic::initialization($tenant['id'], $tenant['sn'], $params);
+                // 初始化管理员部门信息
+                TenantDept::initialization($tenant['id'], $managerInfo['id']);
+                // 创建租户菜单权限
+                TenantSystemMenuLogic::initialization($tenant['id']);
+                // 创建默认装修数据
+                DecorateDataLogic::initialization($tenant['id']);
+            }
+            // 提交事务
+            DB::commit();
+            // 返回成功
+            return $this->success('新增成功', [], 1, 1);
+        } catch (\Exception $e) {
+            // 回滚事务
+            DB::rollBack();
+            // 处理异常并返回错误信息
+            return $this->fail('新增失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * @notes 编辑用户信息
+     * @return \think\response\Json
+     * @author 段誉
+     * @date 2022/9/22 16:34
+     */
+    public function edit()
+    {
+        $params = (new TenantValidate())->post()->goCheck('edit');
+        $result = TenantLogic::edit($params);
+        if (true === $result) {
+            return $this->success('操作成功', [], 1, 1);
+        }
+        return $this->fail(TenantLogic::getError());
+    }
+
+    /**
+     * @notes 删除租户
+     * @return \think\response\Json
+     * @author JXDN
+     * @date 2024/09/03 17:02
+     */
+    public function delete()
+    {
+        $params = (new TenantValidate())->post()->goCheck('delete');
+        $result = TenantLogic::delete($params);
+        if (true === $result) {
+            return $this->success('删除成功', [], 1, 1);
+        }
+        return $this->fail(TenantLogic::getError());
+    }
+}

+ 55 - 0
app/adminapi/controller/tenant/TenantUserController.php

@@ -0,0 +1,55 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\tenant;
+
+use app\adminapi\controller\BaseAdminController;
+use app\tenantapi\lists\user\UserLists;
+use app\tenantapi\logic\user\UserLogic;
+use app\tenantapi\validate\user\UserValidate;
+
+/**
+ * 租户用户控制器
+ * Class TenantUserController
+ * @package app\adminapi\controller\user
+ */
+class TenantUserController extends BaseAdminController
+{
+
+    /**
+     * @notes 获取租户用户列表
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 23:36
+     */
+    public function lists()
+    {
+        //进行租户信息校验
+        (new UserValidate())->goCheck('manager');
+        return $this->dataLists(new UserLists());
+    }
+
+
+    /**
+     * @notes 获取租户用户详情
+     * @return \think\response\Json
+     * @author yfdong
+     * @date 2024/09/04 23:36
+     */
+    public function detail()
+    {
+        $params = (new UserValidate())->goCheck('detail');
+        $detail = UserLogic::detail($params['id']);
+        return $this->success('获取租户用户详情成功', $detail);
+    }
+}

+ 116 - 0
app/adminapi/lists/tenant/TenantAdminLists.php

@@ -0,0 +1,116 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\lists\tenant;
+
+use app\common\model\auth\TenantAdmin;
+use app\tenantapi\lists\BaseAdminDataLists;
+use app\common\enum\user\UserTerminalEnum;
+use app\common\lists\ListsExcelInterface;
+use app\common\model\tenant\Tenant;
+
+
+/**
+ * 用户列表
+ * Class TenantLists
+ * @package app\tenantapi\lists\user
+ */
+class TenantAdminLists extends BaseAdminDataLists implements ListsExcelInterface
+{
+
+    /**
+     * @notes 搜索条件
+     * @return array
+     * @author 段誉
+     * @date 2022/9/22 15:50
+     */
+    public function setSearch(): array
+    {
+        $allowSearch = ['keyword', 'create_time_start', 'create_time_end','tenant_id'];
+        return array_intersect(array_keys($this->params), $allowSearch);
+    }
+
+
+    /**
+     * @notes 获取用户列表
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 段誉
+     * @date 2022/9/22 15:50
+     */
+    public function lists(): array
+    {
+        //进行参数校验 租户标识必填
+        if(!isset($this->params['tenant_id'])){
+            return [];
+        }
+
+        $field = "id,root,name,avatar,account,multipoint_login,disable,create_time";
+
+        $lists = TenantAdmin::withSearch($this->setSearch(), $this->params)
+            ->limit($this->limitOffset, $this->limitLength)
+            ->field($field)
+            ->order('create_time desc')
+            ->select()->toArray();
+
+
+        return $lists;
+    }
+
+
+    /**
+     * @notes 获取数量
+     * @return int
+     * @author 段誉
+     * @date 2022/9/22 15:51
+     */
+    public function count(): int
+    {
+        return TenantAdmin::withSearch($this->setSearch(), $this->params)->count();
+    }
+
+
+    /**
+     * @notes 导出文件名
+     * @return string
+     * @author 段誉
+     * @date 2022/11/24 16:17
+     */
+    public function setFileName(): string
+    {
+        return '租户用户列表';
+    }
+
+
+    /**
+     * @notes 导出字段
+     * @return string[]
+     * @author 段誉
+     * @date 2022/11/24 16:17
+     */
+    public function setExcelFields(): array
+    {
+        return [
+            'root' => '是否超级管理员',
+            'name' => '租户账户昵称',
+            'avatar' => '头像',
+            'account' => '账号',
+            'multipoint_login' => '是否允许多处登录',
+            'disable' => '是否禁用',
+            'create_time' => '注册时间',
+        ];
+    }
+
+}

+ 168 - 0
app/adminapi/lists/tenant/TenantLists.php

@@ -0,0 +1,168 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\lists\tenant;
+
+use app\tenantapi\lists\BaseAdminDataLists;
+use app\common\enum\user\UserTerminalEnum;
+use app\common\lists\ListsExcelInterface;
+use app\common\model\tenant\Tenant;
+
+
+/**
+ * 用户列表
+ * Class TenantLists
+ * @package app\tenantapi\lists\user
+ */
+class TenantLists extends BaseAdminDataLists implements ListsExcelInterface
+{
+
+    /**
+     * @notes 搜索条件
+     * @return array
+     * @author 段誉
+     * @date 2022/9/22 15:50
+     */
+    public function setSearch(): array
+    {
+        $allowSearch = ['keyword', 'create_time_start', 'create_time_end'];
+        return array_intersect(array_keys($this->params), $allowSearch);
+    }
+
+
+    /**
+     * @notes 获取用户列表
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 段誉
+     * @date 2022/9/22 15:50
+     */
+    public function lists(): array
+    {
+        $field = "id,sn,name,avatar,disable,create_time,domain_alias,domain_alias_enable,notes,tel";
+
+        $lists = Tenant::withCount(['users'])
+            ->withSearch($this->setSearch(), $this->params)
+            ->limit($this->limitOffset, $this->limitLength)
+            ->field($field)
+            ->order('id desc')
+            ->select()->toArray();
+
+        $domain = self::getRootDmain(request()->domain());
+
+        // 遍历结果,添加 link 字段
+        return array_map(function ($item) use ($domain) {
+            // 拼接租户的链接 http://[sn].likeadmin-saas.localhost/admin/
+            $http_prefix = self::checkHttp() ? 'https://' : 'http://';
+            $item['default_domain'] = $http_prefix . $item['sn'] . '.' . $domain . '/tenant/';
+
+            if ($item['domain_alias_enable'] === 0) {
+                $item['domain'] = $http_prefix . $item['domain_alias'] . '/tenant/';
+            } else {
+                $item['domain'] = $item['default_domain'];
+            }
+            return $item;
+        }, $lists);
+    }
+
+
+    /**
+     * @notes 获取数量
+     * @return int
+     * @author 段誉
+     * @date 2022/9/22 15:51
+     */
+    public function count(): int
+    {
+        return Tenant::withSearch($this->setSearch(), $this->params)->count();
+    }
+
+
+    /**
+     * @notes 导出文件名
+     * @return string
+     * @author 段誉
+     * @date 2022/11/24 16:17
+     */
+    public function setFileName(): string
+    {
+        return '租户列表';
+    }
+
+
+    /**
+     * @notes 导出字段
+     * @return string[]
+     * @author 段誉
+     * @date 2022/11/24 16:17
+     */
+    public function setExcelFields(): array
+    {
+        return [
+            'sn' => '租户编号',
+            'name' => '租户昵称',
+            'disable' => '租户状态',
+            'create_time' => '注册时间',
+        ];
+    }
+
+    /**
+     * @notes 检查是否为https
+     * @return bool
+     * @author JXDN
+     * @date 2024/09/11 14:39
+     */
+    public static function checkHttp()
+    {
+        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * @notes 获取根域名
+     * @param $url
+     * @return array|int|string|null
+     * @author JXDN
+     * @date 2024/09/11 14:49
+     */
+    public static function getRootDmain($url)
+    {
+        // 解析 URL 获取主机名
+        $host = parse_url($url, PHP_URL_HOST);
+
+        // 如果主机名为空,返回 null
+        if (!$host) {
+            return null;
+        }
+
+        // 拆分域名
+        $parts = explode('.', $host);
+
+        // 检查域名的级数
+        $numParts = count($parts);
+
+        // 针对常见的两级或三级域名进行处理
+        if ($numParts >= 2) {
+            // 获取最后两部分,例如 qq.com 或 co.uk
+            $rootDomain = $parts[$numParts - 2] . '.' . $parts[$numParts - 1];
+            return $rootDomain;
+        }
+
+        return $host; // 当域名本身就是根域名时,直接返回
+    }
+}

+ 341 - 0
app/adminapi/logic/tenant/TenantAdminLogic.php

@@ -0,0 +1,341 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\logic\tenant;
+
+use app\common\cache\TenantAdminAuthCache;
+use app\common\cache\TenantAdminTokenCache;
+use app\common\enum\YesNoEnum;
+use app\common\logic\BaseLogic;
+use app\common\model\auth\TenantAdmin;
+use app\common\model\auth\TenantAdminDept;
+use app\common\model\auth\TenantAdminJobs;
+use app\common\model\auth\TenantAdminRole;
+use app\common\model\auth\TenantAdminSession;
+use app\common\service\FileService;
+use think\facade\Db;
+use think\facade\Config;
+
+/**
+ * 用户逻辑层
+ * Class TenantLogic
+ * @package app\adminapi\logic\user
+ */
+class TenantAdminLogic extends BaseLogic
+{
+    /**
+     * @notes 新增租户管理员
+     * @param array $params
+     * @return bool
+     * @author yfdong
+     * @date 2024/09/04 22:43
+     */
+    public static function add(array $params)
+    {
+        Db::startTrans();
+        try {
+            $passwordSalt = Config::get('project.unique_identification');
+            $password = create_password($params['password'], $passwordSalt);
+            $defaultAvatar = config('project.default_image.admin_avatar');
+            $avatar = !empty($params['avatar']) ? FileService::setFileUrl($params['avatar']) : $defaultAvatar;
+
+            $admin = TenantAdmin::create([
+                'name'             => $params['name'],
+                'tenant_id'        => $params['tenant_id'],
+                'account'          => $params['account'],
+                'avatar'           => $avatar,
+                'password'         => $password,
+                'create_time'      => time(),
+                'disable'          => $params['disable'],
+                'multipoint_login' => $params['multipoint_login'],
+            ]);
+
+            // 角色
+            self::insertRole($admin['id'], $params['role_id'] ?? []);
+            // 部门
+            self::insertDept($admin['id'], $params['dept_id'] ?? []);
+            // 岗位
+            self::insertJobs($admin['id'], $params['jobs_id'] ?? []);
+
+            Db::commit();
+            return true;
+        } catch (\Exception $e) {
+            Db::rollback();
+            self::setError($e->getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * @notes 租户管理员详情
+     * @param int $userId
+     * @return array | bool
+     * @author yfdong
+     * @date 2024/09/04 22:44
+     */
+    public static function detail(int $userId): array|bool
+    {
+        $field = "id,root,name,avatar,account,multipoint_login,disable,create_time";
+
+        try {
+            return TenantAdmin::where(['id' => $userId])->field($field)->findOrEmpty()->toArray();
+        } catch (\Exception $e) {
+            self::setError($e->getMessage());
+            return false;
+        }
+    }
+
+
+    /**
+     * @notes 修改租户管理员
+     * @param array $params
+     * @return bool
+     * @author yfdong
+     * @date 2024/09/04 22:44
+     */
+    public static function edit(array $params)
+    {
+        Db::startTrans();
+        try {
+            // 基础信息
+            $data = [
+                'name'             => $params['name'],
+                'account'          => $params['account'],
+                'disable'          => $params['disable'],
+                'multipoint_login' => $params['multipoint_login']
+            ];
+
+            // 头像
+            $data['avatar'] = !empty($params['avatar']) ? FileService::setFileUrl($params['avatar']) : '';
+
+            // 密码
+            if (!empty($params['password'])) {
+                $passwordSalt = Config::get('project.unique_identification');
+                $data['password'] = create_password($params['password'], $passwordSalt);
+            }
+
+            // 禁用或更换角色后.设置token过期
+            $roleId = TenantAdminRole::where('admin_id', $params['id'])->column('role_id');
+            $editRole = false;
+            if (!empty(array_diff_assoc($roleId, $params['role_id']))) {
+                $editRole = true;
+            }
+
+            if ($params['disable'] == 1 || $editRole) {
+                $tokenArr = TenantAdminSession::where('admin_id', $params['id'])->select()->toArray();
+                foreach ($tokenArr as $token) {
+                    self::expireToken($token['token']);
+                }
+            }
+            TenantAdmin::update($data, ['id' => $params['id']]);
+            (new TenantAdminAuthCache($params['id']))->clearAuthCache();
+
+            // 删除旧的关联信息
+            TenantAdminRole::delByUserId($params['id']);
+            TenantAdminDept::delByUserId($params['id']);
+            TenantAdminJobs::delByUserId($params['id']);
+            // 角色
+            self::insertRole($params['id'], $params['role_id']);
+            // 部门
+            self::insertDept($params['id'], $params['dept_id'] ?? []);
+            // 岗位
+            self::insertJobs($params['id'], $params['jobs_id'] ?? []);
+
+            Db::commit();
+
+            return true;
+        } catch (\Exception $e) {
+            Db::rollback();
+            self::setError($e->getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * @notes 详情场景
+     * @param array $params
+     * @return bool
+     * @author yfdong
+     * @date 2024/09/04 22:58
+     */
+    public static function delete(array $params)
+    {
+        Db::startTrans();
+        try {
+            $admin = TenantAdmin::findOrEmpty($params['id']);
+            if ($admin->root == YesNoEnum::YES) {
+                throw new \Exception("超级管理员不允许被删除");
+            }
+            TenantAdmin::destroy($params['id']);
+
+            //设置token过期
+            $tokenArr = TenantAdminSession::where('admin_id', $params['id'])->select()->toArray();
+            foreach ($tokenArr as $token) {
+                self::expireToken($token['token']);
+            }
+            (new TenantAdminAuthCache($params['id']))->clearAuthCache();
+
+            // 删除旧的关联信息
+            TenantAdminRole::delByUserId($params['id']);
+            TenantAdminDept::delByUserId($params['id']);
+            TenantAdminJobs::delByUserId($params['id']);
+
+            Db::commit();
+            return true;
+        } catch (\Exception $e) {
+            Db::rollback();
+            self::setError($e->getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * @notes 设置token过期
+     * @param $token
+     * @return bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author JXDN
+     * @date 2024/09/06 18:03
+     */
+    public static function expireToken($token): bool
+    {
+        $adminSession = TenantAdminSession::where('token', '=', $token)
+            ->with('admin')
+            ->find();
+
+        if (empty($adminSession)) {
+            return false;
+        }
+
+        $time = time();
+        $adminSession->expire_time = $time;
+        $adminSession->update_time = $time;
+        $adminSession->save();
+
+        return (new TenantAdminTokenCache())->deleteAdminInfo($token);
+    }
+
+    /**
+     * @notes 新增角色
+     * @param $adminId
+     * @param $roleIds
+     * @return void
+     * @throws \Exception
+     * @author JXDN
+     * @date 2024/09/06 18:05
+     */
+    public static function insertRole($adminId, $roleIds)
+    {
+        if (!empty($roleIds)) {
+            // 角色
+            $roleData = [];
+            foreach ($roleIds as $roleId) {
+                $roleData[] = [
+                    'admin_id' => $adminId,
+                    'role_id'  => $roleId,
+                ];
+            }
+            (new TenantAdminRole())->saveAll($roleData);
+        }
+    }
+
+
+    /**
+     * @notes 新增部门
+     * @param $adminId
+     * @param $deptIds
+     * @return void
+     * @throws \Exception
+     * @author JXDN
+     * @date 2024/09/06 18:05
+     */
+    public static function insertDept($adminId, $deptIds)
+    {
+        // 部门
+        if (!empty($deptIds)) {
+            $deptData = [];
+            foreach ($deptIds as $deptId) {
+                $deptData[] = [
+                    'admin_id' => $adminId,
+                    'dept_id'  => $deptId
+                ];
+            }
+            (new TenantAdminDept())->saveAll($deptData);
+        }
+    }
+
+
+    /**
+     * @notes 新增岗位
+     * @param $adminId
+     * @param $jobsIds
+     * @return void
+     * @throws \Exception
+     * @author JXDN
+     * @date 2024/09/06 18:05
+     */
+    public static function insertJobs($adminId, $jobsIds)
+    {
+        // 岗位
+        if (!empty($jobsIds)) {
+            $jobsData = [];
+            foreach ($jobsIds as $jobsId) {
+                $jobsData[] = [
+                    'admin_id' => $adminId,
+                    'jobs_id'  => $jobsId
+                ];
+            }
+            (new TenantAdminJobs())->saveAll($jobsData);
+        }
+    }
+
+    /**
+     * @notes 根据加密规则创建密码
+     * @param $password
+     * @return string
+     * @author yfdong
+     * @date 2024/09/04 22:53
+     */
+    public static function createPassword($password)
+    {
+        // 密码盐
+        $passwordSalt = Config::get('project.unique_identification');
+        return create_password($password, $passwordSalt);
+    }
+
+    /**
+     * @notes 初始化管理员账号
+     * @param mixed $id
+     * @param $name
+     * @return TenantAdmin|\think\Model
+     * @author yfdong
+     * @date 2024/09/05 22:52
+     */
+    public static function initialization(mixed $id, $sn, $params)
+    {
+        // 获取配置中的默认密码
+        $defaultPassword = Config::get('project.default_password');
+        // 初始化管理员账号
+        return TenantAdmin::create([
+            'tenant_id' => $id,
+            'account'   => $params['account'] ?: $sn,
+            'name'      => '超级管理员',
+            'password'  => self::createPassword($params['password'] ?: $defaultPassword),
+            'avatar'    => '',
+            'disable'   => 0,
+            'root'      => 1
+        ]);
+    }
+}

+ 173 - 0
app/adminapi/logic/tenant/TenantLogic.php

@@ -0,0 +1,173 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\logic\tenant;
+
+use app\common\enum\user\UserTerminalEnum;
+use app\common\logic\BaseLogic;
+use app\common\model\tenant\Tenant;
+use app\common\model\user\User;
+
+/**
+ * 用户逻辑层
+ * Class TenantLogic
+ * @package app\adminapi\logic\user
+ */
+class TenantLogic extends BaseLogic
+{
+    /**
+     * @notes 新增租户
+     * @param array $params
+     * @return Tenant|\think\Model
+     * @author JXDN
+     * @date 2024/09/03 14:42
+     */
+    public static function add(array $params)
+    {
+        $domain_alias = preg_replace('/^https?:\/\/|\/$/', '', $params['domain_alias']);
+        return Tenant::create([
+            'sn'                  => Tenant::createUserSn(),
+            'name'                => $params['name'],
+            'avatar'              => $params['avatar'],
+            'tel'                 => $params['tel'],
+            'domain_alias'        => $domain_alias,
+            'domain_alias_enable' => $params['domain_alias_enable'],
+            'disable'             => $params['disable'] ?? 0,
+            'notes'               => $params['notes'] ?? '',
+            'tactics'             => $params['tactics'] ?? 0,
+        ]);
+    }
+
+    /**
+     * @notes 用户详情
+     * @param int $userId
+     * @return array|false
+     * @author JXDN
+     * @date 2024/09/11 15:48
+     */
+    public static function detail(int $userId)
+    {
+        try {
+            $field = "id,sn,name,avatar,tel,domain_alias,domain_alias_enable,disable,create_time,notes";
+
+            $user = Tenant::where(['id' => $userId])->field($field)->findOrEmpty();
+            $user['user_total'] = User::where(['tenant_id' => $userId])->count();
+
+            $domain = self::getRootDmain(request()->domain());
+            $user['default_domain'] = (self::checkHttp() ? 'https://' : 'http://') . $user['sn'] . '.' . $domain . '/tenant/';
+            if ($user['domain_alias_enable'] === 0) {
+                $user['domain'] = (self::checkHttp() ? 'https://' : 'http://') . $user['domain_alias'] . '/tenant/';
+            } else {
+                $user['domain'] = $user['default_domain'];
+            }
+
+            return $user->toArray();
+        } catch (\Exception $e) {
+            self::setError($e->getMessage());
+            return false;
+        }
+
+    }
+
+    /**
+     * @notes 更新租户信息
+     * @param array $params
+     * @return bool
+     * @author JXDN
+     * @date 2024/09/03 14:28
+     */
+    public static function edit(array $params)
+    {
+        try {
+            $domain_alias = preg_replace('/^https?:\/\/|\/$/', '', $params['domain_alias']);
+            Tenant::update([
+                'name'                => $params['name'],
+                'avatar'              => $params['avatar'],
+                'disable'             => $params['disable'] ?? 0,
+                'tel'                 => $params['tel'],
+                'domain_alias'        => $domain_alias,
+                'domain_alias_enable' => $params['domain_alias_enable'],
+                'notes'               => $params['notes'] ?? '',
+            ], ['id' => $params['id']]);
+            return true;
+        } catch (\Exception $e) {
+            self::setError($e->getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * @notes 删除租户
+     * @param array $params
+     * @return bool
+     * @author JXDN
+     * @date 2024/09/03 17:04
+     */
+    public static function delete(array $params)
+    {
+        try {
+            Tenant::destroy($params['id']);
+            return true;
+        } catch (\Exception $e) {
+            self::setError($e->getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * @notes 检查是否为https
+     * @return bool
+     * @author JXDN
+     * @date 2024/09/11 14:39
+     */
+    public static function checkHttp()
+    {
+        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * @notes 获取根域名
+     * @param $url
+     * @return array|int|string|null
+     * @author JXDN
+     * @date 2024/09/11 14:49
+     */
+    public static function getRootDmain($url)
+    {
+        // 解析 URL 获取主机名
+        $host = parse_url($url, PHP_URL_HOST);
+
+        // 如果主机名为空,返回 null
+        if (!$host) {
+            return null;
+        }
+
+        // 拆分域名
+        $parts = explode('.', $host);
+
+        // 检查域名的级数
+        $numParts = count($parts);
+
+        // 针对常见的两级或三级域名进行处理
+        if ($numParts >= 2) {
+            // 获取最后两部分,例如 qq.com 或 co.uk
+            return $parts[$numParts - 2] . '.' . $parts[$numParts - 1];
+        }
+
+        return $host; // 当域名本身就是根域名时,直接返回
+    }
+}

+ 61 - 0
app/adminapi/logic/tenant/TenantSystemMenuLogic.php

@@ -0,0 +1,61 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\logic\tenant;
+
+use app\common\model\auth\TenantSystemMenu;
+
+/**
+ * 租户菜单逻辑
+ *  Class TenantSystemMenuLogic
+ * @package app\adminapi\logic\tenant
+ */
+class TenantSystemMenuLogic
+{
+
+    /**
+     * @notes 初始化租户菜单信息
+     * @param $tenant_id
+     * @author yfdong
+     * @date 2024/09/05 22:15
+     */
+    public static function initialization($tenant_id)
+    {
+        //初始化租户菜单字段
+        $field = "id,pid,type,name,icon,sort,perms,paths,component,selected,params,is_cache,is_show,is_disable,tenant_id";
+        //查询模板菜单配置文件 此处默认为租户号为0的模板数据
+        $tenantSystemMenuList = TenantSystemMenu::where(['tenant_id' => 0])->field($field)->order('pid')->select()->toArray();
+        //记录对应的关系
+        foreach ($tenantSystemMenuList as $item) {
+            $tenantSystemMenu[$item['id']] = $item;
+        }
+        //创建菜单数据
+        foreach ($tenantSystemMenuList as $item) {
+            $item['tenant_id'] = $tenant_id;
+            //创建新的菜单并保存原本id对应现在的哪个信息
+            $oldId = $item['id'];
+            unset($item['id']);
+            $newMenu = TenantSystemMenu::create($item);
+            $tenantSystemMenu[$oldId] = $newMenu;
+        }
+        //获取当前租户的初始化菜单关系
+        $tenantSystemMenuNewList = TenantSystemMenu::where(['tenant_id' => $tenant_id])->field($field)->order('pid')->select()->toArray();
+        //更新对应的主菜单关系
+        foreach ($tenantSystemMenuNewList as $item) {
+            if ($item['pid'] != 0)
+                $item['pid'] = $tenantSystemMenu[$item['pid']]['id'];
+            $where = array('id' => intval($item['id']));
+            TenantSystemMenu::update($item, $where);
+        }
+    }
+}

+ 278 - 0
app/adminapi/service/TenantCreatService.php

@@ -0,0 +1,278 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+
+
+namespace app\adminapi\service;
+
+
+use Exception;
+use PDO;
+use PDOException;
+use think\facade\Config;
+
+/**
+ * 创建租户service
+ * Class TenantCreatService
+ * @package app\adminapi\service
+ */
+class TenantCreatService
+{
+
+    /**
+     * 数据库连接
+     */
+    private $dbh = null;
+
+    /**
+     * @notes 创建租户模式分表
+     * @param $tenantSn
+     * @return bool
+     * @throws \Random\RandomException
+     * @author yfdong
+     * @date 2024/09/28 10:55
+     */
+    public function createTenantTable($tenantSn)
+    {
+        // 创建数据库链接
+        $this->dbh = self::connectDB();
+
+        // 获取数据库版本
+        $version = self::getMysqlVersion($this->dbh);
+
+        // 获取数据库SQL文件路径
+        $dbFile = dirname(__DIR__) . '/db/tenant.sql';
+
+        // 检查文件是否存在,若不存在,直接返回错误
+        if (!file_exists($dbFile)) {
+            throw new Exception("SQL file not found: $dbFile");
+        }
+
+        // 读取并规范化SQL文件内容
+        $content = str_replace(";\r\n", ";\n", file_get_contents($dbFile));
+
+        // 对数据库中的脚本进行租户唯一标识替换
+        $content = str_replace("{tenantSn}", $tenantSn, $content);
+
+        // 分割SQL语句
+        $tables = explode(";\n", $content);
+
+        // 初始化安装时间戳
+        $installTime = microtime(true) * 10000;
+
+        // 循环处理每个SQL语句
+        foreach ($tables as $table) {
+            // 去除前后空白字符
+            $table = trim($table);
+
+            // 跳过空的SQL语句
+            if (empty($table)) continue;
+
+            // 处理数据库版本兼容性问题(版本<=4.1时移除CHARSET)
+            if (strpos($table, 'CREATE') !== false && $version <= 4.1) {
+                $table = str_replace('DEFAULT CHARSET=utf8', '', $table);
+            }
+
+            // 跳过注释的SQL语句
+            if (strpos($table, '--') === 0) continue;
+
+            // 替换表前缀
+            $table = str_replace('`la_', env('database.database', 'likeadmin_saas') . '.`la_', $table);
+            $table = str_replace('`la_', '`' . env('database.prefix', 'la_'), $table);
+
+            // 如果是创建表的SQL,记录表名和时间戳
+//            if (strpos($table, 'CREATE') !== false) {
+//                $tableName = explode('`', $table)[1];
+//                $installTime += random_int(3000, 7000); // 随机递增安装时间
+//                $successTable[] = [$tableName, date('Y-m-d H:i:s', $installTime / 10000)];
+//            }
+
+            // 执行SQL语句
+            try {
+                if (!$this->dbh->query($table)) {
+                    throw new Exception("SQL execution failed: $table");
+                }
+            } catch (Exception $e) {
+                // 捕获异常并输出详细错误信息
+                echo 'Error executing SQL: ' . htmlspecialchars($table) . "<br>";
+                echo 'Error message: ' . $e->getMessage() . "<br>";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @notes 初始化租户数据
+     * @param $tenantSn
+     * @return bool
+     * @throws \Random\RandomException
+     * @author yfdong
+     * @date 2024/10/01 15:43
+     */
+    public function initializationTenantData($tenantId, $tenantSn, $param)
+    {
+        // 创建数据库链接
+        $this->dbh = self::connectDB();
+
+        // 获取数据库版本
+        $version = self::getMysqlVersion($this->dbh);
+
+        // 获取数据库SQL文件路径
+        $dbFile = dirname(__DIR__) . '/db/tenantData.sql';
+
+        // 检查文件是否存在,若不存在,直接返回错误
+        if (!file_exists($dbFile)) {
+            throw new Exception("SQL file not found: $dbFile");
+        }
+
+        // 读取并规范化SQL文件内容
+        $content = str_replace(";\r\n", ";\n", file_get_contents($dbFile));
+
+        // 对数据库中的脚本进行租户唯一标识替换
+        $content = str_replace("{tenantSn}", $tenantSn, $content);
+
+        // 对数据库中的脚本进行租户唯一标识替换
+        $content = str_replace("{tenantId}", $tenantId, $content);
+
+        // 分割SQL语句
+        $tables = explode(";\n", $content);
+
+        // 初始化安装时间戳
+        $installTime = microtime(true) * 10000;
+
+        // 创建管理员账号
+        $tables[] = $this->initAccount($tenantId, $tenantSn, $param);
+
+        // 循环处理每个SQL语句
+        foreach ($tables as $table) {
+            // 去除前后空白字符
+            $table = trim($table);
+
+            // 跳过空的SQL语句
+            if (empty($table)) continue;
+
+            // 处理数据库版本兼容性问题(版本<=4.1时移除CHARSET)
+            if (strpos($table, 'CREATE') !== false && $version <= 4.1) {
+                $table = str_replace('DEFAULT CHARSET=utf8', '', $table);
+            }
+
+            // 跳过注释的SQL语句
+            if (strpos($table, '--') === 0) continue;
+
+            // 替换表前缀
+            $table = str_replace('`la_', env('database.database', 'likeadmin_saas') . '.`la_', $table);
+            $table = str_replace('`la_', '`' . env('database.prefix', 'la_'), $table);
+
+            // 执行SQL语句
+            try {
+                if (!$this->dbh->query($table)) {
+                    throw new Exception("SQL execution failed: $table");
+                }
+            } catch (Exception $e) {
+                // 捕获异常并输出详细错误信息
+                echo "初始化租户初始数据失败";
+                echo 'Error executing SQL: ' . htmlspecialchars($table) . "<br>";
+                echo 'Error message: ' . $e->getMessage() . "<br>";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @notes 检查数据库版本
+     * @return string
+     * @author yfdong
+     * @date 2024/10/01 13:39
+     */
+    public function getMysqlVersion($dbh)
+    {
+        $sql = "SELECT VERSION() AS version";
+        $result = $dbh->query($sql)->fetch();
+        return substr($result->version, 0, 3);
+    }
+
+
+    /**
+     * @notes 创建数据库链接
+     * @return PDO|string
+     * @author yfdong
+     * @date 2024/10/01 13:39
+     */
+    public function connectDB()
+    {
+        // 获取数据库链接
+        $host = env('database.hostname', '');
+        $port = env('database.hostport', '');
+        $user = env('database.username', '');
+        $password = env('database.password', '');
+        $dsn = "mysql:host={$host}; port={$port}";
+        try {
+            $this->dbh = new PDO($dsn, $user, $password);
+            $this->dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
+            $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+            $this->dbh->exec("SET NAMES 'utf8mb4'");
+            $this->dbh->exec("SET NAMES 'utf8mb4'");
+            try {
+                $this->dbh->exec("SET GLOBAL sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';");
+            } catch (Exception $e) {
+
+            }
+            return $this->dbh;
+        } catch (PDOException $exception) {
+            return $exception->getMessage();
+        }
+    }
+
+
+    /**
+     * @notes 创建管理员账号
+     * @param $post
+     * @return string
+     * @author yfdong
+     * @date 2024/10/01 16:02
+     */
+    public function initAccount($tenantId, $tenantSn, $param)
+    {
+        $time = time();
+        $salt = Config::get('project.unique_identification');
+        $defaultPassword = Config::get('project.default_password');
+
+        global $uniqueSalt;
+        $uniqueSalt = $salt;
+
+        // 账号
+        if (isset($param['account'])) {
+            $account = $param['account'];
+        } else {
+            $account = 'admin';
+        }
+
+        //设置密码
+        if (isset($param['password'])) {
+            $password = md5($salt . md5($param['password'] . $salt));
+        } else {
+            $password = $defaultPassword;
+        }
+
+        // 超级管理员
+        $sql = "INSERT INTO `la_tenant_admin_{$tenantSn}`(`id`, `tenant_id`,`root`, `name`, `avatar`, `account`, `password`, `login_time`, `login_ip`, `multipoint_login`, `disable`, `create_time`, `update_time`, `delete_time`) VALUES (1, {$tenantId},1, '超级管理员', '', '{$account}', '{$password}','{$time}', '', 1, 0, '{$time}', '{$time}', NULL);";
+        // 超级管理员关联部门
+        $sql .= "INSERT INTO `la_tenant_admin_dept_{$tenantSn}` (`admin_id`, `dept_id`) VALUES (1, 1);";
+
+        return $sql;
+    }
+}

+ 172 - 0
app/adminapi/validate/tenant/TenantAdminValidate.php

@@ -0,0 +1,172 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\validate\tenant;
+
+
+use app\common\model\auth\TenantAdmin;
+use app\common\model\tenant\Tenant;
+use app\common\validate\BaseValidate;
+
+/**
+ * 用户验证
+ * Class TenantValidate
+ * @package app\adminapi\validate\user
+ */
+class TenantAdminValidate extends BaseValidate
+{
+
+    protected $rule = [
+        'id'               => 'require|checkUser',
+        'tenant_id'        => 'require|checkTenant',
+        'account'          => 'require|length:1,32|checkAccount',
+        'name'             => 'require',
+        'password'         => 'require|length:6,32|edit',
+        'password_confirm' => 'requireWith:password|confirm',
+    ];
+
+    protected $message = [
+        'id.require'                   => '请选择用户',
+        'name.require'                 => '请输入用户名',
+        'account.require'              => '请输入账户',
+        'account.checkAccount'         => '账号已存在',
+        'account.length'               => '账号长度须在1-32位字符',
+        'tenant_id.require'            => '请选择对应的租户',
+        'password.require'             => '密码不能为空',
+        'password.length'              => '密码长度须在6-32位字符',
+        'password_confirm.requireWith' => '确认密码不能为空',
+        'password_confirm.confirm'     => '两次输入的密码不一致',
+    ];
+
+
+    /**
+     * @notes 详情场景
+     * @return TenantAdminValidate
+     * @author yfdong
+     * @date 2024/09/04 22:58
+     */
+    public function sceneDetail()
+    {
+        return $this->only(['id', 'tenant_id']);
+    }
+
+
+    /**
+     * @notes 租户信息校验
+     * @param $value
+     * @param $rule
+     * @param $data
+     * @return string|true
+     * @author yfdong
+     * @date 2024/09/04 22:57
+     */
+    public function checkUser($value, $rule, $data)
+    {
+        $userIds = TenantAdmin::findOrEmpty($value);
+        if ($userIds->isEmpty()) {
+            return '租户管理员不存在';
+        }
+        return true;
+    }
+
+    public function checkAccount($value, $rule, $data)
+    {
+        $adminAccount = TenantAdmin::where(['account' => $value, 'tenant_id' => $data['tenant_id']])->findOrEmpty();
+        if (!$adminAccount->isEmpty()) {
+            return '账号已存在';
+        }
+        return true;
+    }
+
+    /**
+     * @notes 检查对应租户号是否存在
+     * @param $value
+     * @return string|true
+     * @author yfdong
+     * @date 2024/09/04 22:16
+     */
+    public function checkTenant($value)
+    {
+        $adminTenant = Tenant::where(['id' => $value])->findOrEmpty();
+        if ($adminTenant->isEmpty()) {
+            return '对应租户账号不存在';
+        }
+        return true;
+    }
+
+    /**
+     * @notes 添加场景
+     * @return TenantAdminValidate
+     * @author yfdong
+     * @date 2024/09/04 22:57
+     */
+    public function sceneAdd()
+    {
+        return $this->remove('id', true);
+    }
+
+    /**
+     * @notes 修改场景
+     * @return TenantAdminValidate
+     * @author yfdong
+     * @date 2024/09/04 22:57
+     */
+    public function sceneEdit()
+    {
+        return $this->remove('password', true)->remove('account', true);
+    }
+
+    /**
+     * @notes 删除场景
+     * @return TenantAdminValidate
+     * @author yfdong
+     * @date 2024/09/04 22:57
+     */
+    public function sceneDelete()
+    {
+        return $this->only(['id']);
+    }
+
+
+    /**
+     * @notes 重置密码情形
+     * @return TenantAdminValidate
+     * @author yfdong
+     * @date 2024/09/04 23:29
+     */
+    public function sceneResetPassword()
+    {
+        return $this->only(['id']);
+    }
+
+    /**
+     * @notes 编辑情况下,检查是否填密码
+     * @param $value
+     * @param $rule
+     * @param $data
+     * @return bool|string
+     * @author 段誉
+     * @date 2021/12/29 10:19
+     */
+    public function edit($value, $rule, $data)
+    {
+        if (empty($data['password']) && empty($data['password_confirm'])) {
+            return true;
+        }
+        $len = strlen($value);
+        if ($len < 6 || $len > 32) {
+            return '密码长度须在6-32位字符';
+        }
+        return true;
+    }
+}

+ 141 - 0
app/adminapi/validate/tenant/TenantValidate.php

@@ -0,0 +1,141 @@
+<?php
+// +----------------------------------------------------------------------
+// | likeadmin快速开发前后端分离管理后台(PHP版)
+// +----------------------------------------------------------------------
+// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
+// | 开源版本可自由商用,可去除界面版权logo
+// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
+// | github下载:https://github.com/likeshop-github/likeadmin
+// | 访问官网:https://www.likeadmin.cn
+// | likeadmin团队 版权所有 拥有最终解释权
+// +----------------------------------------------------------------------
+// | author: likeadminTeam
+// +----------------------------------------------------------------------
+namespace app\adminapi\validate\tenant;
+
+
+use app\common\model\tenant\Tenant;
+use app\common\validate\BaseValidate;
+
+/**
+ * 用户验证
+ * Class TenantValidate
+ * @package app\adminapi\validate\user
+ */
+class TenantValidate extends BaseValidate
+{
+
+    protected $rule = [
+        'id'   => 'require|checkUser',
+        'name' => 'require',
+        'domain_alias' => 'checkDomainAlias'
+    ];
+
+    protected $message = [
+        'id.require'   => '请选择用户',
+        'name.require' => '请输入用户名',
+    ];
+
+
+    /**
+     * @notes 详情场景
+     * @return TenantValidate
+     * @author 段誉
+     * @date 2022/9/22 16:35
+     */
+    public function sceneDetail()
+    {
+        return $this->only(['id']);
+    }
+
+
+    /**
+     * @notes 租户信息校验
+     * @param $value
+     * @param $rule
+     * @param $data
+     * @return bool|string
+     * @author 段誉
+     * @date 2022/9/22 17:03
+     */
+    public function checkUser($value, $rule, $data)
+    {
+        $userIds = Tenant::findOrEmpty($value);
+        if ($userIds->isEmpty()) {
+            return '租户不存在';
+        }
+        return true;
+    }
+
+    /**
+     * @notes 域名校验
+     * @param $value
+     * @param $rule
+     * @param $data
+     * @return string|true
+     * @author JXDN
+     * @date 2024/09/11 15:30
+     */
+    public function checkDomainAlias($value, $rule, $data)
+    {
+        $tenant = Tenant::where(['domain_alias' => $value])->findOrEmpty();
+        if (!$tenant->isEmpty()) {
+            return '租户别名已存在';
+        }
+        return true;
+    }
+
+    /**
+     * @notes 域名校验
+     * @param $value
+     * @param $rule
+     * @param $data
+     * @return string|true
+     * @author JXDN
+     * @date 2024/09/11 15:30
+     */
+    public function checkDomainAliasEdit($value, $rule, $data)
+    {
+        $tenant = Tenant::where('domain_alias', $value)
+            ->where('id', '<>', $data['id']) // 排除当前租户
+            ->findOrEmpty();
+        if (!$tenant->isEmpty()) {
+            return '租户别名已存在';
+        }
+        return true;
+    }
+
+
+    /**
+     * @notes 添加场景
+     * @return TenantValidate
+     * @author 段誉
+     * @date 2022/5/25 18:16
+     */
+    public function sceneAdd()
+    {
+        return $this->remove('id', true);
+    }
+
+    /**
+     * @notes 编辑场景
+     * @return TenantValidate
+     * @author JXDN
+     * @date 2024/09/11 15:31
+     */
+    public function sceneEdit()
+    {
+        return $this->only(['id', 'name'])->append('domain_alias', 'checkDomainAliasEdit');
+    }
+
+    /**
+     * @notes 删除场景
+     * @return TenantValidate
+     * @author 段誉
+     * @date 2022/5/25 18:16
+     */
+    public function sceneDelete()
+    {
+        return $this->only(['id']);
+    }
+}