From 9d1ff26442fe045daa1777ad4af73bed3102203f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 10:32:10 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E8=B6=85=E7=AE=A1=E5=90=8E=E5=8F=B0=20-=20?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/superadmin/config/route.php | 5 +- .../UpdateAdministratorController.php | 13 +- .../company/CreateCompanyController.php | 2 +- .../GetCompanyDetailForUpdateController.php | 2 +- .../company/UpdateCompanyController.php | 217 ++++++++++++++++++ .../app/dashboard/projects/[id]/edit/page.tsx | 3 +- 6 files changed, 233 insertions(+), 9 deletions(-) create mode 100644 Server/application/superadmin/controller/company/UpdateCompanyController.php diff --git a/Server/application/superadmin/config/route.php b/Server/application/superadmin/config/route.php index de28be4b..449b495b 100644 --- a/Server/application/superadmin/config/route.php +++ b/Server/application/superadmin/config/route.php @@ -28,13 +28,14 @@ Route::group('', function () { // 客户池管理路由 Route::group('trafficPool', function () { - Route::get('list', 'app\superadmin\controller\TrafficPoolController@getList'); // 获取客户池列表 - Route::get('detail', 'app\superadmin\controller\TrafficPoolController@getDetail'); // 获取客户详情 + Route::get('list', 'app\superadmin\controller\TrafficPoolController@getList'); + Route::get('detail', 'app\superadmin\controller\TrafficPoolController@getDetail'); }); // 公司路由 Route::group('company', function () { Route::post('create', 'app\superadmin\controller\company\CreateCompanyController@index'); + Route::post('update', 'app\superadmin\controller\company\UpdateCompanyController@index'); Route::get('list', 'app\superadmin\controller\company\GetCompanyListController@index'); Route::get('detail/:id', 'app\superadmin\controller\company\GetCompanyDetailForUpdateController@index'); }); diff --git a/Server/application/superadmin/controller/administrator/UpdateAdministratorController.php b/Server/application/superadmin/controller/administrator/UpdateAdministratorController.php index 0214ac7b..f8bc85d6 100644 --- a/Server/application/superadmin/controller/administrator/UpdateAdministratorController.php +++ b/Server/application/superadmin/controller/administrator/UpdateAdministratorController.php @@ -51,12 +51,12 @@ class UpdateAdministratorController extends BaseController 'account' => 'require|/\S+/', 'name' => 'require|/\S+/', 'password' => '/\S+/', - 'permissionIds' => 'require|array', + 'permissionIds' => 'array', ], [ 'id.require' => '缺少必要参数', 'account.require' => '账号不能为空', 'name.require' => '姓名不能为空', - 'permissionIds.require' => '请至少分配一种权限', + 'permissionIds.array' => '请至少分配一种权限', ]); if (!$validate->check($params)) { @@ -70,9 +70,10 @@ class UpdateAdministratorController extends BaseController * 判断是否有权限修改 * * @param int $adminId + * @param array $params * @return $this */ - protected function checkPermission(int $adminId): self + protected function checkPermission(int $adminId, array $params): self { $currentAdminId = $this->getAdminInfo('id'); @@ -80,6 +81,10 @@ class UpdateAdministratorController extends BaseController throw new \Exception('您没有权限修改其他管理员', 403); } + if ($params['id'] != 1 && empty($params['permissionIds'])) { + throw new \Exception('请至少分配一种权限', 403); + } + return $this; } @@ -123,7 +128,7 @@ class UpdateAdministratorController extends BaseController // 被修改的管理员id $adminId = $params['id'] ?? 0; - $this->dataValidate($params)->checkPermission($adminId); + $this->dataValidate($params)->checkPermission($adminId, $params); Db::startTrans(); diff --git a/Server/application/superadmin/controller/company/CreateCompanyController.php b/Server/application/superadmin/controller/company/CreateCompanyController.php index 2c2eee25..9ccc9d9e 100644 --- a/Server/application/superadmin/controller/company/CreateCompanyController.php +++ b/Server/application/superadmin/controller/company/CreateCompanyController.php @@ -106,7 +106,7 @@ class CreateCompanyController extends BaseController */ protected function ckbCreateCompany(array $params): void { - $params = ArrHelper::getValue('companyId,name,memo,status', $params); + $params = ArrHelper::getValue('companyId=id,companyId,name,memo,status', $params); $result = CompanyModel::create($params); if (!$result) { diff --git a/Server/application/superadmin/controller/company/GetCompanyDetailForUpdateController.php b/Server/application/superadmin/controller/company/GetCompanyDetailForUpdateController.php index 12dc5921..84235f52 100644 --- a/Server/application/superadmin/controller/company/GetCompanyDetailForUpdateController.php +++ b/Server/application/superadmin/controller/company/GetCompanyDetailForUpdateController.php @@ -29,7 +29,7 @@ class GetCompanyDetailForUpdateController extends BaseController } /** - * 获取下古墓详情 + * 获取项目详情 * * @param int $id * @return CompanyModel diff --git a/Server/application/superadmin/controller/company/UpdateCompanyController.php b/Server/application/superadmin/controller/company/UpdateCompanyController.php new file mode 100644 index 00000000..21b43f6e --- /dev/null +++ b/Server/application/superadmin/controller/company/UpdateCompanyController.php @@ -0,0 +1,217 @@ +request->post('id/d', 0) + ); + + if (!$company) { + throw new \Exception('项目不存在', 404); + } + + // 外部使用 + $this->companyId = $company->id; + + return $company; + } + + /** + * 通过账号获取用户信息 + * + * @return UsersModel + * @throws \Exception + */ + protected function getUserDetailByCompanyId(): ?UsersModel + { + $user = UsersModel::where(['companyId' => $this->companyId])->find(); + + if (!$user) { + throw new \Exception('用户不存在', 404); + } + + return $user; + } + + /** + * 更新项目信息 + * + * @param array $params + * @return void + * @throws \Exception + */ + protected function updateCompany(array $params): void + { + $params = ArrHelper::getValue('name,status,memo', $params); + $params = ArrHelper::rmValue($params); + + $company = $this->getCompanyDetailById(); + if (!$company->save($params)) { + throw new \Exception('项目更新失败', 403); + } + } + + /** + * 更新账号信息 + * + * @param array $params + * @return void + */ + protected function updateUserAccount(array $params): void + { + $params = ArrHelper::getValue('username,account,password=passwordLocal,realName,status', $params); + $params = ArrHelper::rmValue($params); + + if (isset($params['passwordLocal'])) { + $params['passwordMd5'] = md5($params['passwordLocal']); + } + + $user = $this->getUserDetailByCompanyId(); + if (!$user->save($params)) { + throw new \Exception('用户账号更新失败', 403); + } + } + + /** + * @param array $params + * @return self + * @throws \Exception + */ + protected function updateCkbAbout(array $params): self + { + // 1. 更新项目信息 + $this->updateCompany($params); + + // 2. 更新账号信息 + $this->updateUserAccount($params); + + return $this; + } + + /** + * @param array $params + * @return self + * @throws \Exception + */ + protected function updateS2About(array $params): self + { + // 1. 更新项目信息 + $this->updateCompany($params); + + // 2. 更新账号信息 + $this->updateUserAccount($params); + + return $this; + } + + /** + * 检查项目名称是否已存在(排除自身) + * + * @param array $where + * @return void + * @throws \Exception + */ + protected function checkCompanyNameAndAccountExists(array $where): void + { + extract($where); + + // 项目名称尽量不重名 + $exists = CompanyModel::where(compact('name'))->where('id', '<>', $id)->count() > 0; + if ($exists) { + throw new \Exception('项目名称已存在', 403); + } + + // 账号尽量不重名 + // TODO(数据迁移时,存客宝,主账号先查询出id,通过id查询出S2的最新信息,然后更新。) + $exists = UsersModel::where(compact('account'))->where('companyId', '<>', $id)->count() > 0; + if ($exists) { + throw new \Exception('用户账号已存在', 403); + } + } + + /** + * 数据验证 + * + * @param array $params + * @return $this + * @throws \Exception + */ + protected function dataValidate(array $params): self + { + $validate = Validate::make([ + 'id' => 'require', + 'name' => 'require|max:50|/\S+/', + 'username' => 'require|max:20|/\S+/', + 'account' => 'require|regex:/^1[3-9]\d{9}$/', + 'status' => 'require|in:0,1', + 'realName' => 'require|/\S+/', + ], [ + 'id.require' => '非法请求', + 'name.require' => '请输入项目名称', + 'username.require' => '请输入用户昵称', + 'account.require' => '请输入账号', + 'account.regex' => '账号为手机号', + 'status.require' => '缺少重要参数', + 'status.in' => '非法参数', + 'realName.require' => '请输入真实姓名', + ]); + + if (!$validate->check($params)) { + throw new \Exception($validate->getError(), 400); + } + + return $this; + } + + /** + * 更新项目信息 + * + * @return \think\response\Json + */ + public function index() + { + try { + $params = $this->request->only(['id', 'name', 'status', 'username', 'account', 'password', 'realName', 'memo']); + + // 数据验证 + $this->dataValidate($params); + $this->checkCompanyNameAndAccountExists(ArrHelper::getValue('id,name,account', $params)); + + Db::startTrans(); + $this->updateCkbAbout($params)->updateS2About($params); + Db::commit(); + + return json([ + 'code' => 200, + 'msg' => '更新成功' + ]); + } catch (\Exception $e) { + Db::rollback(); + + return json([ + 'code' => $e->getCode(), + 'msg' => $e->getMessage() + ]); + } + } +} \ No newline at end of file diff --git a/SuperAdmin/app/dashboard/projects/[id]/edit/page.tsx b/SuperAdmin/app/dashboard/projects/[id]/edit/page.tsx index 4825aabd..d5150158 100644 --- a/SuperAdmin/app/dashboard/projects/[id]/edit/page.tsx +++ b/SuperAdmin/app/dashboard/projects/[id]/edit/page.tsx @@ -69,12 +69,13 @@ export default function EditProjectPage({ params }: { params: { id: string } }) setIsSubmitting(true) try { - const response = await fetch(`http://yishi.com/company/update/${params.id}`, { + const response = await fetch(`http://yishi.com/company/update`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ + id: params.id, name: projectName, account, memo: description, From bb59175fdbb1e62eceac8437918bf3d57bb4da6f Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 21 Apr 2025 10:45:29 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=BA=93=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cunkebao/app/content/[id]/edit/page.tsx | 2 +- .../controller/ContentLibraryController.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Cunkebao/app/content/[id]/edit/page.tsx b/Cunkebao/app/content/[id]/edit/page.tsx index 808c1ba8..a7809573 100644 --- a/Cunkebao/app/content/[id]/edit/page.tsx +++ b/Cunkebao/app/content/[id]/edit/page.tsx @@ -98,7 +98,7 @@ export default function EditContentLibraryPage({ params }: { params: Promise<{ i const data = response.data // 直接使用API返回的好友和群组数据 - const friends = data.sourceFriends || []; + const friends = data.selectedFriends || []; const groups = data.sourceGroups || []; setFormData({ diff --git a/Server/application/cunkebao/controller/ContentLibraryController.php b/Server/application/cunkebao/controller/ContentLibraryController.php index b1024a29..01ffed19 100644 --- a/Server/application/cunkebao/controller/ContentLibraryController.php +++ b/Server/application/cunkebao/controller/ContentLibraryController.php @@ -111,6 +111,24 @@ class ContentLibraryController extends Controller $library['timeEnd'] = date('Y-m-d', $library['timeEnd']); } + // 获取好友详细信息 + if (!empty($library['sourceFriends'])) { + $friendIds = $library['sourceFriends']; + $friendsInfo = []; + + if (!empty($friendIds)) { + // 查询好友信息,使用wechat_account表 + $friendsInfo = Db::name('wechat_account') + ->field('wechatId, nickname, avatar') + ->whereIn('wechatId', $friendIds) + ->select(); + } + + // 将好友信息添加到返回数据中 + $library['selectedFriends'] = $friendsInfo; + } + + return json([ 'code' => 200, From cc055643283da40f4e4bcf0a0ad46feb3f2b6822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 11:05:53 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E8=B6=85=E7=AE=A1=E5=90=8E=E5=8F=B0=20-=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/superadmin/config/route.php | 3 +- .../controller/CompanyController.php | 269 ------------------ .../company/DeleteCompanyController.php | 135 +++++++++ 3 files changed, 137 insertions(+), 270 deletions(-) create mode 100644 Server/application/superadmin/controller/company/DeleteCompanyController.php diff --git a/Server/application/superadmin/config/route.php b/Server/application/superadmin/config/route.php index 449b495b..d3269626 100644 --- a/Server/application/superadmin/config/route.php +++ b/Server/application/superadmin/config/route.php @@ -38,5 +38,6 @@ Route::group('', function () { Route::post('update', 'app\superadmin\controller\company\UpdateCompanyController@index'); Route::get('list', 'app\superadmin\controller\company\GetCompanyListController@index'); Route::get('detail/:id', 'app\superadmin\controller\company\GetCompanyDetailForUpdateController@index'); + Route::post('delete/:id', 'app\superadmin\controller\company\DeleteCompanyController@index'); }); -})->middleware(['app\superadmin\middleware\AdminAuth']); \ No newline at end of file +})->middleware(['app\superadmin\middleware\AdminAuth']); \ No newline at end of file diff --git a/Server/application/superadmin/controller/CompanyController.php b/Server/application/superadmin/controller/CompanyController.php index d979e86c..2fe73235 100644 --- a/Server/application/superadmin/controller/CompanyController.php +++ b/Server/application/superadmin/controller/CompanyController.php @@ -16,238 +16,6 @@ use think\facade\Session; */ class CompanyController extends Controller { - /** - * 创建新项目 - * @return \think\response\Json - */ - public function create() - { - // 获取参数 - $params = Request::only(['name', 'nickname', 'account', 'password', 'realName', 'description']); - - try { - // 开启事务 - Db::startTrans(); - $curl = CurlHandle::getInstant()->setBaseUrl('http://yishi.com/'); - - // 1. 调用创建部门接口 - $departmentResponse = $curl->setMethod('post')->send('v1/api/account/department/create', [ - 'name' => $params['name'], - 'memo' => $params['description'] ?: '', - ]); - - $departmentData = json_decode($departmentResponse, true); - if ($departmentData['code'] != 200) { - throw new \Exception($departmentData['msg']); - } - - // 2. 调用创建账号接口 - $accountResponse = $curl->setMethod('post')->send('v1/api/account/create', [ - 'userName' => $params['account'], - 'password' => $params['password'], - 'realName' => $params['realName'], - 'nickname' => $params['nickname'], - 'departmentId' => $departmentData['data']['id'] - ]); - - $accountData = json_decode($accountResponse, true); - if ($accountData['code'] != 200) { - throw new \Exception($accountData['msg']); - } - - // 3. 插入公司表 - $companyData = [ - 'companyId' => $departmentData['data']['id'], - 'name' => $departmentData['data']['name'], - 'mome' => $departmentData['data']['memo'] - ]; - - if (!companyModel::create($companyData)) { - throw new \Exception('创建公司记录失败'); - } - - // 4. 插入用户表 - $userData = [ - 'account' => $params['account'], - 'passwordMd5' => md5($params['password']), - 'passwordLocal' => $params['password'], - 'companyId' => $departmentData['data']['id'] - ]; - - if (!Users::create($userData)) { - throw new \Exception('创建用户记录失败'); - } - - // 提交事务 - Db::commit(); - - return json([ - 'code' => 200, - 'msg' => '创建成功', - 'data' => [ - 'companyId' => $departmentData['data']['id'], - 'name' => $departmentData['data']['name'], - 'memo' => $departmentData['data']['memo'] - ] - ]); - - } catch (\Exception $e) { - // 回滚事务 - Db::rollback(); - return json([ - 'code' => 500, - 'msg' => '创建失败:' . $e->getMessage() - ]); - } - } - - /** - * 获取项目列表 - * @return \think\response\Json - */ - public function getList() - { - // 获取分页参数 - $page = $this->request->param('page/d', 1); - $limit = $this->request->param('limit/d', 10); - $keyword = $this->request->param('keyword/s', ''); - - // 构建查询条件 - $where = []; - if (!empty($keyword)) { - $where[] = ['name', 'like', "%{$keyword}%"]; - } - - // 查询项目数据 - $total = companyModel::where($where)->count(); - $list = companyModel::where($where) - ->field('id, name, status, tenantId, companyId, memo, createTime') - ->order('id', 'desc') - ->page($page, $limit) - ->select(); - - // 获取每个项目的子账号数量 - $data = []; - foreach ($list as $item) { - // 查询该项目下的子账号数量 - $userCount = Users::where('companyId', $item['companyId']) - ->where('deleteTime', 0) - ->count(); - - $data[] = [ - 'id' => $item['id'], - 'name' => $item['name'], - 'status' => $item['status'], - 'tenantId' => $item['tenantId'], - 'companyId' => $item['companyId'], - 'memo' => $item['memo'], - 'userCount' => $userCount, - 'createTime' => date('Y-m-d H:i:s', $item['createTime']) - ]; - } - - return json([ - 'code' => 200, - 'msg' => '获取成功', - 'data' => [ - 'list' => $data, - 'total' => $total, - 'page' => $page, - 'limit' => $limit - ] - ]); - } - - /** - * 获取项目详情 - * @param int $id 项目ID - * @return \think\response\Json - */ - public function getDetail($id) - { - $company = companyModel::get($id); - if (!$company) { - return json(['code' => 404, 'msg' => '项目不存在']); - } - - // 获取项目下的子账号数量 - $userCount = Users::where('companyId', $id) - ->where('deleteTime', 0) - ->count(); - - $data = [ - 'id' => $company->id, - 'name' => $company->name, - 'status' => $company->status, - 'tenantId' => $company->tenantId, - 'companyId' => $company->companyId, - 'memo' => $company->memo, - 'userCount' => $userCount, - 'createTime' => date('Y-m-d H:i:s', $company->createTime) - ]; - - return json([ - 'code' => 200, - 'msg' => '获取成功', - 'data' => $data - ]); - } - - /** - * 更新项目信息 - * @return \think\response\Json - */ - public function update() - { - if (!$this->request->isPost()) { - return json(['code' => 405, 'msg' => '请求方法不允许']); - } - - // 获取请求参数 - $id = $this->request->post('id/d', 0); - $name = $this->request->post('name/s', ''); - $status = $this->request->post('status/d'); - $tenantId = $this->request->post('tenantId/d'); - $companyId = $this->request->post('companyId/d'); - $memo = $this->request->post('memo/s', ''); - - // 参数验证 - if (empty($id) || empty($name)) { - return json(['code' => 400, 'msg' => '请填写必要参数']); - } - - // 查询项目 - $company = companyModel::get($id); - if (!$company) { - return json(['code' => 404, 'msg' => '项目不存在']); - } - - // 检查项目名称是否已存在(排除自身) - $exists = companyModel::where('name', $name) - ->where('id', '<>', $id) - ->find(); - if ($exists) { - return json(['code' => 400, 'msg' => '项目名称已存在']); - } - - // 更新数据 - $company->name = $name; - if (isset($status)) $company->status = $status; - if (isset($tenantId)) $company->tenantId = $tenantId; - if (isset($companyId)) $company->companyId = $companyId; - $company->memo = $memo; - $company->updateTime = time(); - - if ($company->save()) { - return json([ - 'code' => 200, - 'msg' => '更新成功' - ]); - } - - return json(['code' => 500, 'msg' => '更新失败']); - } - /** * 删除项目 * @return \think\response\Json @@ -287,41 +55,4 @@ class CompanyController extends Controller return json(['code' => 500, 'msg' => '删除失败']); } - - /** - * 更新项目状态 - * @return \think\response\Json - */ - public function updateStatus() - { - if (!$this->request->isPost()) { - return json(['code' => 405, 'msg' => '请求方法不允许']); - } - - $id = $this->request->post('id/d', 0); - $status = $this->request->post('status/d'); - - if (empty($id) || !isset($status)) { - return json(['code' => 400, 'msg' => '参数不完整']); - } - - // 查询项目 - $company = companyModel::get($id); - if (!$company) { - return json(['code' => 404, 'msg' => '项目不存在']); - } - - // 更新状态 - $company->status = $status; - $company->updateTime = time(); - - if ($company->save()) { - return json([ - 'code' => 200, - 'msg' => '状态更新成功' - ]); - } - - return json(['code' => 500, 'msg' => '状态更新失败']); - } } \ No newline at end of file diff --git a/Server/application/superadmin/controller/company/DeleteCompanyController.php b/Server/application/superadmin/controller/company/DeleteCompanyController.php new file mode 100644 index 00000000..6c43f85f --- /dev/null +++ b/Server/application/superadmin/controller/company/DeleteCompanyController.php @@ -0,0 +1,135 @@ + 'require|regex:/^[1-9]\d*$/', + ], [ + 'id.regex' => '非法请求', + 'id.require' => '非法请求', + ]); + + if (!$validate->check($params)) { + throw new \Exception($validate->getError(), 400); + } + + return $this; + } + + /** + * 删除项目 + * + * @param int $id + * @throws \Exception + */ + protected function deleteCompany(int $id): void + { + $company = CompanyModel::where('id', $id)->find(); + + if (!$company) { + throw new \Exception('项目不存在', 404); + } + + if (!$company->delete()) { + throw new \Exception('项目删除失败', 400); + } + } + + /** + * 删除用户 + * + * @param int $companId + * @throws \Exception + */ + protected function deleteUser(int $companId): void + { + $user = UserModel::where('companyId', $companId)->find(); + + if (!$user) { + throw new \Exception('用户不存在', 404); + } + + if (!$user->delete()) { + throw new \Exception('用户删除失败', 400); + } + } + + /** + * 删除存客宝数据 + * + * @param int $companId + * @return self + * @throws \Exception + */ + protected function delteCkbAbout(int $companId): self + { + // 1. 删除项目 + $this->deleteCompany($companId); + + // 2. 删除用户 + $this->deleteUser($companId); + + return $this; + } + + /** + * 删除 s2 数据 + * + * @return void + */ + protected function deleteS2About() + { + + } + + /** + * 删除项目 + * + * @return \think\response\Json + */ + public function index() + { + try { + $params = $this->request->only('id'); + $companId = $params['id']; + + $this->dataValidate($params); + + Db::startTrans(); + $this->delteCkbAbout($companId)->deleteS2About($companId); + Db::commit(); + + return json([ + 'code' => 200, + 'msg' => '删除成功' + ]); + } catch (\Exception $e) { + Db::rollback(); + + return json([ + 'code' => $e->getCode(), + 'msg' => $e->getMessage() + ]); + } + } +} \ No newline at end of file From fef6e0fd84419b43ada2b1f111cdee27cd9d65ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 11:46:54 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E8=B6=85=E7=AE=A1=E5=90=8E=E5=8F=B0=20-=20?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E5=88=A0=E9=99=A4=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/superadmin/config/route.php | 2 +- .../company/DeleteCompanyController.php | 16 ++-- SuperAdmin/app/dashboard/projects/page.tsx | 82 ++++++++++++++++++- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/Server/application/superadmin/config/route.php b/Server/application/superadmin/config/route.php index d3269626..f24e000b 100644 --- a/Server/application/superadmin/config/route.php +++ b/Server/application/superadmin/config/route.php @@ -36,8 +36,8 @@ Route::group('', function () { Route::group('company', function () { Route::post('create', 'app\superadmin\controller\company\CreateCompanyController@index'); Route::post('update', 'app\superadmin\controller\company\UpdateCompanyController@index'); + Route::post('delete', 'app\superadmin\controller\company\DeleteCompanyController@index'); Route::get('list', 'app\superadmin\controller\company\GetCompanyListController@index'); Route::get('detail/:id', 'app\superadmin\controller\company\GetCompanyDetailForUpdateController@index'); - Route::post('delete/:id', 'app\superadmin\controller\company\DeleteCompanyController@index'); }); })->middleware(['app\superadmin\middleware\AdminAuth']); \ No newline at end of file diff --git a/Server/application/superadmin/controller/company/DeleteCompanyController.php b/Server/application/superadmin/controller/company/DeleteCompanyController.php index 6c43f85f..29547137 100644 --- a/Server/application/superadmin/controller/company/DeleteCompanyController.php +++ b/Server/application/superadmin/controller/company/DeleteCompanyController.php @@ -61,16 +61,14 @@ class DeleteCompanyController extends BaseController * @param int $companId * @throws \Exception */ - protected function deleteUser(int $companId): void + protected function deleteUsers(int $companId): void { - $user = UserModel::where('companyId', $companId)->find(); + $users = UserModel::where('companyId', $companId)->select(); - if (!$user) { - throw new \Exception('用户不存在', 404); - } - - if (!$user->delete()) { - throw new \Exception('用户删除失败', 400); + foreach ($users as $user) { + if (!$user->delete()) { + throw new \Exception($user->username . ' 用户删除失败', 400); + } } } @@ -87,7 +85,7 @@ class DeleteCompanyController extends BaseController $this->deleteCompany($companId); // 2. 删除用户 - $this->deleteUser($companId); + $this->deleteUsers($companId); return $this; } diff --git a/SuperAdmin/app/dashboard/projects/page.tsx b/SuperAdmin/app/dashboard/projects/page.tsx index cd179a62..83b366c8 100644 --- a/SuperAdmin/app/dashboard/projects/page.tsx +++ b/SuperAdmin/app/dashboard/projects/page.tsx @@ -8,6 +8,14 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" import { Plus, Search, MoreHorizontal, Edit, Eye, Trash, ChevronLeft, ChevronRight } from "lucide-react" import { toast } from "sonner" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" interface Project { id: number @@ -27,6 +35,9 @@ export default function ProjectsPage() { const [currentPage, setCurrentPage] = useState(1) const [totalPages, setTotalPages] = useState(1) const [pageSize] = useState(10) + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false) + const [deletingProjectId, setDeletingProjectId] = useState(null) + const [isDeleting, setIsDeleting] = useState(false) // 获取项目列表 useEffect(() => { @@ -59,6 +70,44 @@ export default function ProjectsPage() { } } + const handleDeleteClick = (projectId: number) => { + setDeletingProjectId(projectId) + setDeleteDialogOpen(true) + } + + const handleConfirmDelete = async () => { + if (!deletingProjectId) return + + setIsDeleting(true) + try { + const response = await fetch("http://yishi.com/company/delete", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: deletingProjectId + }), + }) + + const data = await response.json() + + if (data.code === 200) { + toast.success("删除成功") + // 刷新项目列表 + window.location.reload() + } else { + toast.error(data.msg || "删除失败") + } + } catch (error) { + toast.error("网络错误,请稍后重试") + } finally { + setIsDeleting(false) + setDeleteDialogOpen(false) + setDeletingProjectId(null) + } + } + return (
@@ -127,7 +176,10 @@ export default function ProjectsPage() { 编辑项目 - + handleDeleteClick(project.id)} + > 删除项目 @@ -179,6 +231,34 @@ export default function ProjectsPage() {
)} + + {/* 删除确认对话框 */} + + + + 确认删除 + + 删除项目将会删除本项目关联的所有账号,项目删除后不可恢复,是否确认删除? + + + + + + + +
) } From e39b71d5401bdeedd85599ef7ed6d7bf49e0b5ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 12:04:37 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E8=B6=85=E7=AE=A1=E5=90=8E=E5=8F=B0=20-=20?= =?UTF-8?q?=20=E8=8E=B7=E5=8F=96=E5=9F=BA=E7=A1=80=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/superadmin/config/route.php | 5 ++ .../controller/CompanyController.php | 58 ------------------ .../dashboard/GetBasestatisticsController.php | 61 +++++++++++++++++++ 3 files changed, 66 insertions(+), 58 deletions(-) delete mode 100644 Server/application/superadmin/controller/CompanyController.php create mode 100644 Server/application/superadmin/controller/dashboard/GetBasestatisticsController.php diff --git a/Server/application/superadmin/config/route.php b/Server/application/superadmin/config/route.php index f24e000b..2ee4b18b 100644 --- a/Server/application/superadmin/config/route.php +++ b/Server/application/superadmin/config/route.php @@ -7,6 +7,11 @@ Route::post('auth/login', 'app\superadmin\controller\auth\AuthLoginController@in // 需要登录认证的路由组 Route::group('', function () { + // 仪表盘概述 + Route::group('dashboard', function () { + Route::get('base', 'app\superadmin\controller\dashboard\GetBasestatisticsController@index'); + }); + // 菜单管理相关路由 Route::group('menu', function () { Route::get('tree', 'app\superadmin\controller\MenuController@getMenuTree'); diff --git a/Server/application/superadmin/controller/CompanyController.php b/Server/application/superadmin/controller/CompanyController.php deleted file mode 100644 index 2fe73235..00000000 --- a/Server/application/superadmin/controller/CompanyController.php +++ /dev/null @@ -1,58 +0,0 @@ -request->isPost()) { - return json(['code' => 405, 'msg' => '请求方法不允许']); - } - - $id = $this->request->post('id/d', 0); - if (empty($id)) { - return json(['code' => 400, 'msg' => '请指定要删除的项目']); - } - - // 查询项目 - $company = companyModel::get($id); - if (!$company) { - return json(['code' => 404, 'msg' => '项目不存在']); - } - - // 检查是否有关联的子账号 - $userCount = Users::where('companyId', $id) - ->where('deleteTime', 0) - ->count(); - if ($userCount > 0) { - return json(['code' => 400, 'msg' => '该项目下还有关联的子账号,无法删除']); - } - - // 执行删除 - if ($company->delete()) { - return json([ - 'code' => 200, - 'msg' => '删除成功' - ]); - } - - return json(['code' => 500, 'msg' => '删除失败']); - } -} \ No newline at end of file diff --git a/Server/application/superadmin/controller/dashboard/GetBasestatisticsController.php b/Server/application/superadmin/controller/dashboard/GetBasestatisticsController.php new file mode 100644 index 00000000..552340be --- /dev/null +++ b/Server/application/superadmin/controller/dashboard/GetBasestatisticsController.php @@ -0,0 +1,61 @@ +getCompanyCount(); + } + + /** + * 获取基础统计信息 + * + * @return \think\response\Json + */ + public function index() + { + return json([ + 'code' => 200, + 'msg' => '获取成功', + 'data' => [ + 'companyCount' => $this->getCompanyCount(), + 'adminCount' => $this->getAdminCount(), + 'customerCount' => $this->getCustomerCount(), + ] + ]); + } +} \ No newline at end of file From 3126efc00dafb429e1f2c6200b979b005aa68bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 12:09:35 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E8=B6=85=E7=AE=A1=E5=90=8E=E5=8F=B0=20-=20?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E6=A6=82=E8=BF=B0=E8=8E=B7=E5=8F=96=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E7=BB=9F=E8=AE=A1=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SuperAdmin/app/dashboard/page.tsx | 90 +++++++++++++++---------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/SuperAdmin/app/dashboard/page.tsx b/SuperAdmin/app/dashboard/page.tsx index c3fb6c2d..3550cf9f 100644 --- a/SuperAdmin/app/dashboard/page.tsx +++ b/SuperAdmin/app/dashboard/page.tsx @@ -1,65 +1,59 @@ "use client" -import { useEffect, useState } from "react" +import { useState, useEffect } from "react" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" -import { Users, FolderKanban, UserCog } from "lucide-react" -import useAuthCheck from "@/hooks/useAuthCheck" -import { getAdminInfo, getGreeting } from "@/lib/utils" -import ClientOnly from "@/components/ClientOnly" +import { Building2, Users, UserCog } from "lucide-react" +import { toast } from "sonner" + +interface DashboardStats { + companyCount: number + adminCount: number + customerCount: number +} export default function DashboardPage() { - const [greeting, setGreeting] = useState("") - const [userName, setUserName] = useState("") - - // 验证用户是否已登录 - useAuthCheck() + const [stats, setStats] = useState({ + companyCount: 0, + adminCount: 0, + customerCount: 0 + }) + const [isLoading, setIsLoading] = useState(true) useEffect(() => { - // 获取用户信息 - const adminInfo = getAdminInfo() - if (adminInfo) { - setUserName(adminInfo.name || "管理员") - } else { - setUserName("管理员") - } - }, []) + const fetchStats = async () => { + try { + const response = await fetch("http://yishi.com/dashboard/base") + const data = await response.json() - // 单独处理问候语,避免依赖问题 - useEffect(() => { - // 设置问候语 - const updateGreeting = () => { - if (userName) { - setGreeting(getGreeting(userName)) + if (data.code === 200) { + setStats(data.data) + } else { + toast.error(data.msg || "获取统计信息失败") + } + } catch (error) { + toast.error("网络错误,请稍后重试") + } finally { + setIsLoading(false) } } - - updateGreeting() - - // 每分钟更新一次问候语,以防用户长时间停留在页面 - const interval = setInterval(updateGreeting, 60000) - - return () => clearInterval(interval) - }, [userName]) + + fetchStats() + }, []) return (
-

欢迎使用超级管理员后台

-

- - {greeting || getGreeting(userName)} - - !通过此平台,您可以管理项目、客户和管理员权限。 -

+

仪表盘

-
+
项目总数 - + -
24
-

较上月增长 12%

+
+ {isLoading ? "..." : stats.companyCount} +
@@ -69,8 +63,9 @@ export default function DashboardPage() { -
1,284
-

较上月增长 8%

+
+ {isLoading ? "..." : stats.customerCount} +
@@ -80,8 +75,9 @@ export default function DashboardPage() { -
8
-

较上月增长 2 人

+
+ {isLoading ? "..." : stats.adminCount} +
From 3de879e959570587a2317a3c8abae7a70802571c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 14:13:32 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=A2=9E=E5=8A=A0=E8=AE=BE=E5=A4=87=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/GetCompanyListController.php | 18 ++++++++++++++++++ SuperAdmin/app/dashboard/projects/page.tsx | 14 +++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Server/application/superadmin/controller/company/GetCompanyListController.php b/Server/application/superadmin/controller/company/GetCompanyListController.php index 27d734d9..bff4d2ce 100644 --- a/Server/application/superadmin/controller/company/GetCompanyListController.php +++ b/Server/application/superadmin/controller/company/GetCompanyListController.php @@ -3,8 +3,10 @@ namespace app\superadmin\controller\company; use app\common\model\Company as CompanyModel; +use app\common\model\Device as DeviceModel; use app\common\model\User as usersModel; use app\superadmin\controller\BaseController; +use Eison\Utils\Helper\ArrHelper; /** * 公司控制器 @@ -29,6 +31,20 @@ class GetCompanyListController extends BaseController return array_merge($params, $where); } + /** + * 获取设备统计 + * + * @return array + */ + protected function getDevices() + { + $devices = DeviceModel::field('companyId, count(id) as numCount')->group('companyId')->select(); + $devices = $devices ? $devices->toArray() : array(); + + return ArrHelper::columnTokey('companyId', $devices); + } + + /** * 获取项目列表 * @@ -77,9 +93,11 @@ class GetCompanyListController extends BaseController protected function makeReturnedResult(\think\Paginator $list): array { $result = []; + $devices = $this->getDevices(); foreach ($list->items() as $item) { $item->userCount = $this->countUserInCompany($item->companyId); + $item->deviceCount = $devices[$item->companyId]->numCount ?? 0; array_push($result, $item->toArray()); } diff --git a/SuperAdmin/app/dashboard/projects/page.tsx b/SuperAdmin/app/dashboard/projects/page.tsx index 83b366c8..f4e0a0ba 100644 --- a/SuperAdmin/app/dashboard/projects/page.tsx +++ b/SuperAdmin/app/dashboard/projects/page.tsx @@ -16,6 +16,7 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog" +import { Badge } from "@/components/ui/badge" interface Project { id: number @@ -26,6 +27,7 @@ interface Project { memo: string | null userCount: number createTime: string + deviceCount: number } export default function ProjectsPage() { @@ -138,8 +140,9 @@ export default function ProjectsPage() { 项目名称 状态 - 用户数量 - 创建时间 + 用户数量 + 设备数量 + 创建时间 操作 @@ -154,8 +157,13 @@ export default function ProjectsPage() { projects.map((project) => ( {project.name} - {project.status === 1 ? '启用' : '禁用'} + + + {project.status === 1 ? "启用" : "禁用"} + + {project.userCount} + {project.deviceCount} {project.createTime} From 8d8283c4fd1417be1d0e4984c8fcd9f0d596db35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 21 Apr 2025 14:13:32 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=A2=9E=E5=8A=A0=E8=AE=BE=E5=A4=87=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/GetCompanyListController.php | 25 ++++++++++++++++--- SuperAdmin/app/dashboard/projects/page.tsx | 14 ++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Server/application/superadmin/controller/company/GetCompanyListController.php b/Server/application/superadmin/controller/company/GetCompanyListController.php index 27d734d9..1b65c938 100644 --- a/Server/application/superadmin/controller/company/GetCompanyListController.php +++ b/Server/application/superadmin/controller/company/GetCompanyListController.php @@ -3,8 +3,10 @@ namespace app\superadmin\controller\company; use app\common\model\Company as CompanyModel; +use app\common\model\Device as DeviceModel; use app\common\model\User as usersModel; use app\superadmin\controller\BaseController; +use Eison\Utils\Helper\ArrHelper; /** * 公司控制器 @@ -29,6 +31,20 @@ class GetCompanyListController extends BaseController return array_merge($params, $where); } + /** + * 获取设备统计 + * + * @return array + */ + protected function getDevices() + { + $devices = DeviceModel::field('companyId, count(id) as numCount')->group('companyId')->select(); + $devices = $devices ? $devices->toArray() : array(); + + return ArrHelper::columnTokey('companyId', $devices); + } + + /** * 获取项目列表 * @@ -71,15 +87,18 @@ class GetCompanyListController extends BaseController /** * 构建返回数据 * - * @param \think\Paginator $list + * @param \think\Paginator $Companylist * @return array */ - protected function makeReturnedResult(\think\Paginator $list): array + protected function makeReturnedResult(\think\Paginator $Companylist): array { $result = []; + $devices = $this->getDevices(); + + foreach ($Companylist->items() as $item) { - foreach ($list->items() as $item) { $item->userCount = $this->countUserInCompany($item->companyId); + $item->deviceCount = $devices[$item->companyId]['numCount'] ?? 0; array_push($result, $item->toArray()); } diff --git a/SuperAdmin/app/dashboard/projects/page.tsx b/SuperAdmin/app/dashboard/projects/page.tsx index 83b366c8..f4e0a0ba 100644 --- a/SuperAdmin/app/dashboard/projects/page.tsx +++ b/SuperAdmin/app/dashboard/projects/page.tsx @@ -16,6 +16,7 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog" +import { Badge } from "@/components/ui/badge" interface Project { id: number @@ -26,6 +27,7 @@ interface Project { memo: string | null userCount: number createTime: string + deviceCount: number } export default function ProjectsPage() { @@ -138,8 +140,9 @@ export default function ProjectsPage() { 项目名称 状态 - 用户数量 - 创建时间 + 用户数量 + 设备数量 + 创建时间 操作 @@ -154,8 +157,13 @@ export default function ProjectsPage() { projects.map((project) => ( {project.name} - {project.status === 1 ? '启用' : '禁用'} + + + {project.status === 1 ? "启用" : "禁用"} + + {project.userCount} + {project.deviceCount} {project.createTime}