6.0 KiB
6.0 KiB
医生列表接口优化
问题描述
在挂号预约页面中,获取医生列表时调用了 adminapi/auth.admin/lists?role_id=1 接口,该接口需要管理员权限,可能导致权限不足的问题。
解决方案
创建一个专门的接口 adminapi/tcm.diagnosis/getDoctors 用于获取医生列表,不需要额外的权限验证。
实现细节
1. 后端实现
控制器方法
文件: server/app/adminapi/controller/tcm/DiagnosisController.php
/**
* @notes 获取医生列表
* @return \think\response\Json
*/
public function getDoctors()
{
$result = DiagnosisLogic::getDoctors();
return $this->data($result);
}
逻辑层方法
文件: server/app/adminapi/logic/tcm/DiagnosisLogic.php
/**
* @notes 获取医生列表
* @return array
*/
public static function getDoctors()
{
try {
// 通过中间表查询角色ID为1的管理员(医生)
$doctors = \app\common\model\auth\Admin::alias('a')
->join('admin_role ar', 'a.id = ar.admin_id')
->where('ar.role_id', 1)
->where('a.disable', 0)
->field(['a.id', 'a.name', 'a.account'])
->order('a.id', 'asc')
->select()
->toArray();
return $doctors;
} catch (\Exception $e) {
\think\facade\Log::error('获取医生列表失败: ' . $e->getMessage());
return [];
}
}
2. 前端实现
API 方法
文件: admin/src/api/tcm.ts
// 获取医生列表
export function getDoctors() {
return request.get({ url: '/tcm.diagnosis/getDoctors' })
}
组件更新
文件: admin/src/views/tcm/diagnosis/appointment.vue
// 导入新的 API
import { getDoctors } from '@/api/tcm'
// 移除旧的导入
// import { adminLists } from '@/api/perms/admin'
// 更新加载医生列表的方法
const loadDoctors = async () => {
try {
loading.value = true
const res = await getDoctors()
doctorList.value = res || []
} catch (error) {
console.error('加载医生列表失败:', error)
feedback.msgError('加载医生列表失败')
} finally {
loading.value = false
}
}
数据库结构
表关系
zyt_admin (管理员表)
├─ id
├─ name
├─ account
└─ disable
zyt_admin_role (管理员角色关联表)
├─ admin_id → zyt_admin.id
└─ role_id → 1 (医生) / 2 (医助)
SQL 查询
SELECT a.id, a.name, a.account
FROM zyt_admin a
INNER JOIN zyt_admin_role ar ON a.id = ar.admin_id
WHERE ar.role_id = 1
AND a.disable = 0
ORDER BY a.id ASC
接口说明
请求
GET /adminapi/tcm.diagnosis/getDoctors
响应
{
"code": 1,
"msg": "success",
"data": [
{
"id": 1,
"name": "张医生",
"account": "doctor1"
},
{
"id": 2,
"name": "李医生",
"account": "doctor2"
}
]
}
返回字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 医生ID |
| name | string | 医生姓名 |
| account | string | 医生账号 |
优势
- 权限独立:不依赖管理员列表接口的权限
- 数据精简:只返回必要的字段(id、name、account)
- 性能优化:直接通过中间表查询医生角色
- 易于维护:专门的接口更容易理解和维护
- 正确的关联:使用中间表
admin_role而不是直接查询role_id字段
查询条件
- 通过
zyt_admin_role中间表关联 ar.role_id = 1:只查询医生角色a.disable = 0:只查询启用状态的医生- 按
a.id升序排列
测试
测试步骤
- 登录管理后台
- 访问诊单管理页面
- 点击某条诊单的"挂号"按钮
- 查看医生下拉列表是否正常显示
预期结果
- ✅ 医生列表正常加载
- ✅ 下拉框显示所有启用的医生
- ✅ 不会出现权限不足的错误
- ✅ 可以正常选择医生和预约
测试 SQL
-- 检查医生数据
SELECT
a.id,
a.name,
a.account,
ar.role_id,
a.disable
FROM zyt_admin a
INNER JOIN zyt_admin_role ar ON a.id = ar.admin_id
WHERE ar.role_id = 1
ORDER BY a.id ASC;
-- 检查中间表数据
SELECT * FROM zyt_admin_role WHERE role_id = 1;
已修改的文件
- ✅
server/app/adminapi/controller/tcm/DiagnosisController.php - ✅
server/app/adminapi/logic/tcm/DiagnosisLogic.php - ✅
admin/src/api/tcm.ts - ✅
admin/src/views/tcm/diagnosis/appointment.vue
相关接口
医助列表接口
同时也创建了医助列表接口,使用相同的逻辑:
GET /adminapi/tcm.diagnosis/getAssistants
查询条件:ar.role_id = 2(医助角色)
注意事项
- 中间表关联:必须通过
zyt_admin_role中间表查询,不能直接查询role_id字段 - 角色ID:
- 医生:
role_id = 1 - 医助:
role_id = 2
- 医生:
- 状态检查:只返回
disable = 0的用户 - 字段精简:只返回必要的字段,减少数据传输
- 错误处理:捕获异常并记录日志,返回空数组而不是抛出错误
数据库检查
检查医生数据
-- 查看所有医生
SELECT
a.id,
a.name,
a.account,
ar.role_id,
a.disable,
a.create_time
FROM zyt_admin a
INNER JOIN zyt_admin_role ar ON a.id = ar.admin_id
WHERE ar.role_id = 1
ORDER BY a.id ASC;
添加测试医生
-- 1. 添加管理员
INSERT INTO zyt_admin (
name,
account,
password,
disable,
create_time,
update_time
) VALUES (
'测试医生',
'test_doctor',
'e10adc3949ba59abbe56e057f20f883e', -- 密码:123456
0,
UNIX_TIMESTAMP(),
UNIX_TIMESTAMP()
);
-- 2. 获取刚插入的ID
SET @admin_id = LAST_INSERT_ID();
-- 3. 添加角色关联
INSERT INTO zyt_admin_role (admin_id, role_id)
VALUES (@admin_id, 1);
修复日期: 2024-03-04 状态: ✅ 完成