Commit f189d2ae authored by 刘春's avatar 刘春

feat(医生管理): 新增医生列表筛选功能

- 添加科室列表和职称列表接口
- 实现医生列表的筛选和分页功能
- 新增 AddUserModal 组件用于新增用户
- 优化角色管理页面,支持分页和新增用户功能
- 更新 API 配置和类型定义
parent da37d9e5
...@@ -52,4 +52,30 @@ const resetPd = (data: resetPd) => { ...@@ -52,4 +52,30 @@ const resetPd = (data: resetPd) => {
return request('/bi-manager/user/resetPd', 'POST', data); return request('/bi-manager/user/resetPd', 'POST', data);
}; };
export default { addUser, delUser, editUser, getUserList, resetPd }; /**
* 科室列表
* @param {deptName: string}
* @returns
*/
const getDeptList = (data: { deptName: string }) => {
return request('/bi-manager/user/getDeptList', 'POST', data);
};
/**
* 职称列表
* @param {deptName: string}
* @returns
*/
const getRankList = (data: { rankName: string }) => {
return request('/bi-manager/user/getRankList', 'POST', data);
};
export default {
addUser,
delUser,
editUser,
getUserList,
resetPd,
getDeptList,
getRankList
};
...@@ -8,8 +8,8 @@ export const loginInfo: { ...@@ -8,8 +8,8 @@ export const loginInfo: {
}; };
/** 子系统id */ /** 子系统id */
// export const APPID: string = '384EB79867A231EFE065000000000001';
export const APPID: string = '384EB79867A231EFE065000000000001'; export const APPID: string = '384EB79867A231EFE065000000000001';
// export const APPID: string = 'B7686CC82A1F41AAB3F7477241B4D11E';
/** 隐藏侧栏和顶栏的菜单 */ /** 隐藏侧栏和顶栏的菜单 */
export const hideSlideAndHeaderMenus: string[] = []; export const hideSlideAndHeaderMenus: string[] = [];
......
...@@ -16,12 +16,14 @@ declare module 'vue' { ...@@ -16,12 +16,14 @@ declare module 'vue' {
AddSys: typeof import('./../views/report/components/AddSys.vue')['default'] AddSys: typeof import('./../views/report/components/AddSys.vue')['default']
AddTheme: typeof import('./../views/theme/components/AddTheme.vue')['default'] AddTheme: typeof import('./../views/theme/components/AddTheme.vue')['default']
AddUser: typeof import('./../views/role/components/AddUser.vue')['default'] AddUser: typeof import('./../views/role/components/AddUser.vue')['default']
AddUserModal: typeof import('./../views/role/components/AddUserModal.vue')['default']
AlipayFilled: typeof import('./../components/icons/AlipayFilled.vue')['default'] AlipayFilled: typeof import('./../components/icons/AlipayFilled.vue')['default']
BackRoute: typeof import('./../components/BackRoute/index.vue')['default'] BackRoute: typeof import('./../components/BackRoute/index.vue')['default']
BaseEditor: typeof import('./../components/MonacoEditor/components/base-editor.vue')['default'] BaseEditor: typeof import('./../components/MonacoEditor/components/base-editor.vue')['default']
ByteMdEditor: typeof import('./../components/ByteMdEditor/index.vue')['default'] ByteMdEditor: typeof import('./../components/ByteMdEditor/index.vue')['default']
ByteMdViewer: typeof import('./../components/ByteMdViewer/index.vue')['default'] ByteMdViewer: typeof import('./../components/ByteMdViewer/index.vue')['default']
CommonUpload: typeof import('./../components/CommonUpload/index.vue')['default'] CommonUpload: typeof import('./../components/CommonUpload/index.vue')['default']
copy: typeof import('./../views/role/components/AddUser copy.vue')['default']
DictData: typeof import('./../components/DictData/index.vue')['default'] DictData: typeof import('./../components/DictData/index.vue')['default']
DiffEditor: typeof import('./../components/MonacoEditor/components/diff-editor.vue')['default'] DiffEditor: typeof import('./../components/MonacoEditor/components/diff-editor.vue')['default']
FileGroup: typeof import('./../components/FilePicker/components/file-group.vue')['default'] FileGroup: typeof import('./../components/FilePicker/components/file-group.vue')['default']
......
...@@ -6,6 +6,19 @@ ...@@ -6,6 +6,19 @@
<div class="p-l-4px"> <div class="p-l-4px">
<FcCardTip title="医生管理" /> <FcCardTip title="医生管理" />
</div> </div>
<FcSearch
:items="searchItems"
v-model="searchPrams"
type="labelBg"
@search="fetchDoctorList"
@reset="
() => {
resetFields();
fetchDoctorList();
}
"
/>
</template> </template>
<template #toolbar_tools> <template #toolbar_tools>
...@@ -53,6 +66,25 @@ ...@@ -53,6 +66,25 @@
>{{ item }}</el-tag >{{ item }}</el-tag
> >
</template> </template>
<template #pager>
<vxe-pager
:layouts="[
'Sizes',
'PrevJump',
'PrevPage',
'Number',
'NextPage',
'NextJump',
'FullJump',
'Total'
]"
v-model:current-page="params.pageNum"
v-model:page-size="params.pageSize"
:total="params.total"
@page-change="handlePageChange"
/>
</template>
</vxe-grid> </vxe-grid>
</div> </div>
<AddDoctor ref="AddDoctorRef" @reload="fetchDoctorList" /> <AddDoctor ref="AddDoctorRef" @reload="fetchDoctorList" />
...@@ -68,6 +100,9 @@ ...@@ -68,6 +100,9 @@
import doctorApi from '@/api/doctorApi'; import doctorApi from '@/api/doctorApi';
// coms // coms
import AddDoctor from './components/AddDoctor.vue'; import AddDoctor from './components/AddDoctor.vue';
import { FcSearch } from '@fancy-design/coms';
// tools
import { useFormData } from '@/utils/use-form-data';
const AddDoctorRef = ref(); const AddDoctorRef = ref();
...@@ -118,6 +153,13 @@ ...@@ -118,6 +153,13 @@
}); });
}; };
// 分页切换
const handlePageChange = ({ currentPage, pageSize }) => {
params.pageNum = currentPage;
params.pageSize = pageSize;
fetchDoctorList();
};
// 获取医生列表 // 获取医生列表
const params = reactive({ const params = reactive({
pageNum: 1, pageNum: 1,
...@@ -127,7 +169,10 @@ ...@@ -127,7 +169,10 @@
const pageLoading = ref(false); const pageLoading = ref(false);
const fetchDoctorList = async () => { const fetchDoctorList = async () => {
pageLoading.value = true; pageLoading.value = true;
const [error, ret] = await tryit(doctorApi.getUserList)(params); const [error, ret] = await tryit(doctorApi.getUserList)({
...params,
...searchPrams
});
if (error) { if (error) {
console.error(error); console.error(error);
return; return;
...@@ -140,6 +185,8 @@ ...@@ -140,6 +185,8 @@
}; };
onMounted(() => { onMounted(() => {
fetchDoctorList(); fetchDoctorList();
fetchDeptList();
fetchRankList();
}); });
const gridOptions = reactive<VxeGridProps>({ const gridOptions = reactive<VxeGridProps>({
...@@ -215,4 +262,90 @@ ...@@ -215,4 +262,90 @@
}, },
data: [] data: []
}); });
const [searchPrams, resetFields] = useFormData({
recipeId: '',
patientName: '',
patientId: ''
});
// 筛选配置
const searchItems = computed(() => [
{
prop: 'userCode',
label: '医生编码',
type: 'input',
col: {
span: 4
}
},
{
prop: 'userName',
label: '医生名称',
type: 'input',
col: {
span: 4
}
},
{
prop: 'deptCode',
label: '科室',
type: 'select',
col: {
span: 4
},
options: deptList.value || []
},
{
prop: 'technicalTitleCode',
label: '职称',
type: 'select',
col: {
span: 4
},
options: rankList.value || []
}
]);
// 获取科室列表
const deptList = ref<
Array<{
label: string;
value: string;
}>
>([]);
const fetchDeptList = async () => {
const [err, res] = await tryit(doctorApi.getDeptList)({ deptName: '' });
if (err) {
console.error(err.message);
return;
}
deptList.value = (res.data as Array<any>).map((item) => {
return {
label: item.deptName,
value: item.deptCode
};
});
};
// 获取职称列表
const rankList = ref<
Array<{
label: string;
value: string;
}>
>([]);
const fetchRankList = async () => {
const [err, res] = await tryit(doctorApi.getRankList)({ rankName: '' });
if (err) {
console.error(err.message);
return;
}
rankList.value = (res.data as Array<any>).map((item) => {
return {
label: item.rankName,
value: item.rankCode
};
});
};
</script> </script>
<script setup lang="ts">
// types
import type { VxeGridInstance, VxeGridProps } from 'vxe-table';
// tools
import { tryit } from 'radash';
import { useFormData } from '@/utils/use-form-data';
// apis
import doctorApi from '@/api/doctorApi';
// coms
import { FcSearch } from '@fancy-design/coms';
const modalVisible = ref(false);
const handleOpen = () => {
modalVisible.value = true;
fetchDoctorList();
fetchRankList();
fetchDeptList();
};
defineExpose({
open: handleOpen
});
const pageLoading = ref(false);
const gridOptions = reactive<VxeGridProps>({
border: 'inner',
showHeaderOverflow: true,
showOverflow: true,
height: 'auto',
rowConfig: {
keyField: 'id',
isHover: true
},
columnConfig: {
resizable: true
},
sortConfig: {
trigger: 'cell',
remote: true
},
filterConfig: {
remote: true
},
checkboxConfig: {
trigger: 'row'
},
columns: [
{
type: 'checkbox',
width: 60
},
{
field: 'userName',
title: '医生名称'
},
{
field: 'userCode',
title: '医生编码'
},
{
field: 'deptName',
title: '科室名称'
},
{
field: 'deptCode',
title: '科室编码'
},
{
field: 'jurisdictionName',
title: '权限',
slots: { default: 'jurisdictionName_slot' }
},
{
field: 'roleNames',
title: '角色',
slots: { default: 'roleNames_slot' }
},
{
field: 'wxId',
title: '微信号',
formatter: 'em'
}
],
data: []
});
// 点击取消
const handleCancel = () => {
modalVisible.value = false;
};
// 点击确认
const handleConfirm = () => {
if (selectUserList.value.length === 0) {
return ElMessage.warning('请选择医生');
}
console.log(selectUserList.value, 'sss');
};
// 获取医生列表
const params = reactive({
pageNum: 1,
pageSize: 10,
total: 0
});
const fetchDoctorList = async () => {
pageLoading.value = true;
const [error, ret] = await tryit(doctorApi.getUserList)({
...params,
...searchPrams
});
if (error) {
console.error(error);
return;
}
if (ret.code === 200) {
gridOptions.data = ret.data!.data;
params.total = ret.data!.total;
}
pageLoading.value = false;
};
const [searchPrams, resetFields] = useFormData({
recipeId: '',
patientName: '',
patientId: ''
});
// 筛选配置
const searchItems = computed(() => [
{
prop: 'userCode',
label: '医生编码',
type: 'input',
col: {
span: 4
}
},
{
prop: 'userName',
label: '医生名称',
type: 'input',
col: {
span: 4
}
},
{
prop: 'deptCode',
label: '科室',
type: 'select',
col: {
span: 4
},
options: deptList.value || []
},
{
prop: 'technicalTitleCode',
label: '职称',
type: 'select',
col: {
span: 4
},
options: rankList.value || []
}
]);
// 获取科室列表
const deptList = ref<
Array<{
label: string;
value: string;
}>
>([]);
const fetchDeptList = async () => {
const [err, res] = await tryit(doctorApi.getDeptList)({ deptName: '' });
if (err) {
console.error(err.message);
return;
}
deptList.value = (res.data as Array<any>).map((item) => {
return {
label: item.deptName,
value: item.deptCode
};
});
};
// 获取职称列表
const rankList = ref<
Array<{
label: string;
value: string;
}>
>([]);
const fetchRankList = async () => {
const [err, res] = await tryit(doctorApi.getRankList)({ rankName: '' });
if (err) {
console.error(err.message);
return;
}
rankList.value = (res.data as Array<any>).map((item) => {
return {
label: item.rankName,
value: item.rankCode
};
});
};
// 分页切换
const handlePageChange = ({ currentPage, pageSize }) => {
params.pageNum = currentPage;
params.pageSize = pageSize;
fetchDoctorList();
};
// 获取表格选择
const GridRef = ref<VxeGridInstance>();
const selectUserList = computed(() => {
return GridRef.value?.getCheckboxRecords() || [];
});
</script>
<template>
<ele-modal v-model="modalVisible" title="新增用户" width="1200px">
<ele-loading :loading="pageLoading">
<ele-card
:body-style="{
padding: '0px',
height: '65vh',
overflow: 'hidden'
}"
>
<div flex flex-col overflow-hidden h-full>
<FcSearch
:items="searchItems"
v-model="searchPrams"
type="labelBg"
@search="fetchDoctorList"
@reset="
() => {
resetFields();
fetchDoctorList();
}
"
/>
<vxe-grid v-bind="gridOptions" ref="GridRef">
<!-- 权限列表 -->
<template #jurisdictionName_slot="{ row }">
<el-tag
style="margin: 0 3px"
type="primary"
v-for="item in row.jurisdictionName"
:key="item"
>{{ item }}</el-tag
>
</template>
<!-- 角色列表 -->
<template #roleNames_slot="{ row }">
<el-tag
style="margin: 0 3px"
type="primary"
v-for="item in row.roleNames"
:key="item"
>{{ item }}</el-tag
>
</template>
<template #pager>
<vxe-pager
:layouts="[
'Sizes',
'PrevJump',
'PrevPage',
'Number',
'NextPage',
'NextJump',
'FullJump',
'Total'
]"
v-model:current-page="params.pageNum"
v-model:page-size="params.pageSize"
:total="params.total"
@page-change="handlePageChange"
/>
</template>
</vxe-grid>
</div>
</ele-card>
</ele-loading>
<template #footer>
<el-button type="primary" plain @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确认</el-button>
</template>
</ele-modal>
</template>
...@@ -91,11 +91,31 @@ ...@@ -91,11 +91,31 @@
<CirclePlus /> <CirclePlus />
</el-icon> </el-icon>
</template> </template>
<template #pager>
<vxe-pager
:layouts="[
'Sizes',
'PrevJump',
'PrevPage',
'Number',
'NextPage',
'NextJump',
'FullJump',
'Total'
]"
v-model:current-page="userParams.pageNum"
v-model:page-size="userParams.pageSize"
:total="userParams.total"
@page-change="handlePageChange"
/>
</template>
</vxe-grid> </vxe-grid>
</div> </div>
</div> </div>
<AddRole ref="AddRoleRef" @reload="fetchRoleList" /> <AddRole ref="AddRoleRef" @reload="fetchRoleList" />
<AddUser ref="AddUserRef" :curRole @reload="fetchRoleList" />" <AddUser ref="AddUserRef" :curRole @reload="fetchRoleList" />"
<AddUserModal ref="AddUserModalRef" @reload="fetchRoleList" />
</ele-loading> </ele-loading>
</template> </template>
...@@ -103,6 +123,7 @@ ...@@ -103,6 +123,7 @@
// coms // coms
import AddRole from './components/AddRole.vue'; import AddRole from './components/AddRole.vue';
import AddUser from './components/AddUser.vue'; import AddUser from './components/AddUser.vue';
import AddUserModal from './components/AddUserModal.vue';
// tools // tools
import { FcCardTip } from '@fancy-design/coms'; import { FcCardTip } from '@fancy-design/coms';
import { CirclePlus } from '@element-plus/icons-vue'; import { CirclePlus } from '@element-plus/icons-vue';
...@@ -115,9 +136,10 @@ ...@@ -115,9 +136,10 @@
// 添加用户 // 添加用户
const AddUserRef = ref<InstanceType<typeof AddUser>>(); const AddUserRef = ref<InstanceType<typeof AddUser>>();
const AddUserModalRef = ref<InstanceType<typeof AddUserModal>>();
const handleAddUser = () => { const handleAddUser = () => {
if (!curRole) return ElMessage.warning('请选择角色'); if (!curRole) return ElMessage.warning('请选择角色');
AddUserRef.value?.open('add'); AddUserModalRef.value?.open();
}; };
// 获取角色列表 // 获取角色列表
...@@ -161,20 +183,35 @@ ...@@ -161,20 +183,35 @@
const handleClickFirst = ({ row }) => { const handleClickFirst = ({ row }) => {
curRole.value = row; curRole.value = row;
LGridRef.value?.setCurrentRow(row); LGridRef.value?.setCurrentRow(row);
fetchUserByRole(row.roleId); fetchUserByRole();
};
// 分页切换
const handlePageChange = ({ currentPage, pageSize }) => {
userParams.pageNum = currentPage;
userParams.pageSize = pageSize;
fetchUserByRole();
}; };
// 根据角色获取用户 // 根据角色获取用户
const fetchUserByRole = async (id) => { const userParams = reactive({
pageNum: 1,
pageSize: 10,
total: 0
});
const fetchUserByRole = async () => {
pageLoading.value = true; pageLoading.value = true;
const [err, ret] = await tryit(roleApi.getUserListById)({ id }); const [err, ret] = await tryit(roleApi.getUserListById)({
id: curRole.value?.roleId || '',
...userParams
});
if (err) { if (err) {
console.error(err); console.error(err);
return; return;
} }
if (ret.code === 200) { if (ret.code === 200) {
rgridOptions.data = ret.data; rgridOptions.data = ret.data.list;
rgridOptions.data?.map((item) => (item.status = String(item.status))); userParams.total = ret.data.total;
} }
pageLoading.value = false; pageLoading.value = false;
}; };
......
...@@ -159,7 +159,7 @@ export default defineConfig(({ command, mode }) => { ...@@ -159,7 +159,7 @@ export default defineConfig(({ command, mode }) => {
changeOrigin: true changeOrigin: true
}, },
'/bi-manager': { '/bi-manager': {
target: 'http://10.1.0.138:4396/', target: 'http://10.1.0.101:4396/',
changeOrigin: true changeOrigin: true
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment