1.替换修改救助人员接口
2.用户管理添加专业人员和操作人员模块
This commit is contained in:
2025-11-27 16:24:38 +08:00
parent 98a2680b63
commit 3d4177b647
10 changed files with 1319 additions and 5 deletions
@@ -0,0 +1,267 @@
import { Ref, ref } from 'vue';
import { cloneDeep } from 'lodash-es';
export function showFormTip(domId: string) {
const dom: HTMLElement | null = document.getElementById(domId);
function showDom() {
if (dom) {
dom.style.display = 'block';
dom.scrollIntoView();
}
}
function hiddenDom() {
if (dom) {
dom.style.display = 'none';
}
}
return {
showDom,
hiddenDom,
};
}
/**
* 获取用户其他信息
*/
export function useUserOtherInfo() {
//就诊人信息
const userOtherInfo = ref({
sex_dictText: '',
age: '',
idCard: '',
phone: '',
departName: '',
userDepartName: '',
workNo: '',
});
function setUserOtherInfo(values) {
for (const key in userOtherInfo.value) {
userOtherInfo.value[key] = values[key] || '';
}
userOtherInfo.value['departName'] = values?.userOrgName || values?.secondDepart?.departName || '';
userOtherInfo.value['userDepartName'] = values?.userDepartName || values?.threeDepart?.departName || '';
}
return {
userOtherInfo,
setUserOtherInfo,
};
}
function setInfo(record, list, callback?: Function) {
if (callback) {
callback(list);
return;
}
list.forEach((item) => {
const { field } = item;
const isEmpty = (obj, field) => {
if (!obj) return true;
return obj[field] === undefined || obj[field] === null || obj[field] === '';
};
if (!isEmpty(record, field)) {
if (Object.hasOwn(item, 'customRender')) {
// @ts-ignore
item.value = item.customRender(record);
} else if (Object.hasOwn(item, 'slot')) {
item.value = { ...record, dataIndex: field };
} else {
item.value = record[field] || '';
}
} else {
item.value = '';
}
});
return list;
}
interface IUseTreatmentInfo {
label?: string;
value: string;
component: string;
field: string;
slot?: string;
}
/**
* 就诊详情
*/
export function useTreatmentInfo() {
const basicInfo: Ref<IUseTreatmentInfo[]> = ref([
{
label: '就诊人',
value: '',
component: 'Input',
field: 'userName',
slot: 'userName',
},
{
label: '工号',
value: '',
component: 'Input',
field: 'workNo',
},
{
label: '联系电话',
value: '',
component: 'Input',
field: 'phone',
},
{
label: '身份证号',
value: '',
component: 'Input',
field: 'idCard',
},
{
label: '所属单位',
value: '',
component: 'Input',
field: 'userOrgName',
},
{
label: '所属部门',
value: '',
component: 'Input',
field: 'userDepartName',
},
{
label: '员工档案',
value: '',
component: 'Input',
field: 'createTime',
slot: 'employeeFile',
},
]);
const medicalInformation: Ref<IUseTreatmentInfo[]> = ref([
{
label: '就诊医生',
value: '',
component: 'Input',
field: 'doctorName',
},
{
label: '就诊时间',
value: '',
component: 'Input',
field: 'diagnosisDate',
},
{
label: '诊断',
value: '',
component: 'Textarea',
field: 'diagnosisDisease',
},
{
label: '主诉',
value: '',
component: 'Textarea',
field: 'mainDemands',
},
{
label: '查体',
value: '',
component: 'Textarea',
field: 'inspectionTool',
},
{
label: '现病史',
value: '',
component: 'Textarea',
field: 'historyPresentIllness',
},
{
label: '既往史',
value: '',
component: 'Textarea',
field: 'pastHistory',
},
{
label: '过敏史',
value: '',
component: 'Textarea',
field: 'allergicHistory',
},
]);
const medicineList: Ref<IUseTreatmentInfo[]> = ref([
{
label: '药品名称',
value: '',
component: 'Input',
field: 'medicineName',
},
{
label: '规格',
value: '',
component: 'Input',
field: 'medicineSpecification',
},
{
label: '价格',
value: '',
component: 'Input',
field: 'sellingPrice',
},
{
label: '数量',
value: '',
component: 'Input',
field: 'drugsNum',
},
{
label: '用法用量',
value: '',
component: 'Input',
field: 'dosage',
},
]);
const lifeAdvice: Ref<IUseTreatmentInfo[]> = ref([
{
label: '医嘱',
value: '',
component: 'Textarea',
field: 'doctorAdvice',
},
{
label: '运动处方',
value: '',
component: 'Textarea',
field: 'exerciseFormula',
},
{
label: '膳食处方',
value: '',
component: 'Textarea',
field: 'foodFormula',
},
]);
function setFormValues(values = {}) {
basicInfo.value = setInfo(values, basicInfo.value);
medicalInformation.value = setInfo(values, medicalInformation.value);
lifeAdvice.value = setInfo(values, lifeAdvice.value);
}
function getMedicineList(values = []) {
return setInfo(values, medicineList.value);
}
function getMedicineDetail(values = []) {
let res = setInfo(values, medicineList.value);
return cloneDeep(res);
}
return {
basicInfo,
medicalInformation,
lifeAdvice,
setFormValues,
getMedicineList,
getMedicineDetail,
};
}
//val是正常值则返回正常,否则返回--
export function useShowValue(val: string | boolean | number) {
if (typeof val == undefined || val == null || val == '') {
return '--';
}
return val;
}
@@ -0,0 +1,93 @@
<template>
<div class="medical-card">
<div v-if="$slots.title"><slot name="title"></slot></div>
<div v-if="!$slots.title && title" class="title">{{ title }}</div>
<div v-for="(item, index) in cardList" :key="index">
<template v-if="item.hasOwnProperty('slot')">
<slot :name="item.slot" v-bind="item.value"></slot>
</template>
<template v-else>
<div v-if="item.component == 'Input'" class="input-box">
<div class="input-label">{{ item.label }}</div>
<div class="input-value">{{ useShowValue(item.value) }}</div>
</div>
<div v-if="item.component == 'Textarea' || item.component == 'InputTextArea'" class="textarea-box">
<div class="textarea-label">{{ item.label }}</div>
<div class="textarea-value">{{ useShowValue(item.value) }}</div>
</div>
<div v-if="item.component == 'Image'" class="input-box">
<div class="input-label">{{ item.label }}</div>
<div>
<Image
:width="100"
:height="100"
style="margin: 0"
:src="getFileAccessHttpUrl(item.value)"
:fallback="getFamaleDefaultImage()"
/>
</div>
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { Image } from 'ant-design-vue';
import { useShowValue } from '/@/views/emergency/personnelManagement/components/hooks';
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
const props = defineProps({
list: {
type: Array,
default: () => {
return [];
},
},
title: {
type: String,
default: () => {
return '';
},
},
});
const cardList = computed(() => props.list);
</script>
<style scoped lang="less">
.medical-card {
border: 1px solid #f0f0f0;
padding: 10px;
margin: 10px 0;
position: relative;
.title {
font-weight: bold;
line-height: 30px;
}
.input-box {
display: flex;
margin-bottom: 15px;
.input-label {
width: 100px;
text-align: right;
}
.input-value {
width: calc(100% - 100px);
}
}
.textarea-box {
width: 100%;
display: flex;
margin-bottom: 15px;
overflow: hidden;
flex-wrap: wrap;
.textarea-label {
width: 100px;
text-align: right;
}
.textarea-value {
width: calc(100% - 100px);
}
}
}
</style>
@@ -0,0 +1,117 @@
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
destroyOnClose
:title="title"
:width="600"
@ok="handleSubmit"
:showFooter="showFooter"
:maskClosable="false"
>
<div class="form-container" v-show="title != '详情'">
<BasicForm @register="registerForm" />
</div>
<div class="form-container" v-show="title == '详情'">
<MedicalCard :list="getDetailSchema()" title="" />
</div>
</BasicDrawer>
</template>
<script lang="ts" setup>
import { ref, unref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { BasicForm, useForm } from '/@/components/Form/index';
import { saveOrUpdate } from '../personnelManagement.api';
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
import { dealPassword } from '/@/views/system/user/user.data';
import { formSchema, getPersonType, useDetailForm } from '/@/views/emergency/personnelManagement/personnelManagement.data';
import MedicalCard from '/@/views/emergency/personnelManagement/components/medicalCard.vue';
import { useRoute } from 'vue-router';
const { adaptiveWidth } = useDrawerAdaptiveWidth();
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const showFooter = ref(true);
//设置标题
const title = ref('');
const route = useRoute();
/**
* 5 操作人员
* 6 专业人员
*/
const type = getPersonType(route.path.split('/').pop() as string);
const { setDetailFormData, getDetailSchema } = useDetailForm(type == 6);
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate, updateSchema }] = useForm({
labelWidth: 120,
schemas: formSchema(type == 6),
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
//表单赋值
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
//重置表单
await resetFields();
setDrawerProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
title.value = data.type;
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
setDetailFormData(data.record);
}
await clearValidate();
// 隐藏底部时禁用整个表单
await setProps({ disabled: !data?.showFooter });
});
//表单提交事件
async function handleSubmit() {
try {
let data = await validate();
if (!isUpdate.value) {
data = {
...data,
password: dealPassword(data?.password),
};
}
setDrawerProps({ confirmLoading: true });
//提交表单
await saveOrUpdate({ ...data, type }, isUpdate.value);
//关闭弹窗
closeDrawer();
//刷新列表
emit('success');
} finally {
setDrawerProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
.form-container {
overflow: auto;
}
.title {
box-sizing: border-box;
color: #333;
font-weight: bold;
padding: 12px 16px;
}
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-calendar-picker) {
width: 100%;
}
:deep(.ant-picker) {
width: 100% !important;
}
</style>
@@ -0,0 +1,61 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
export enum Api {
list = '/health-emergency/emergency/profession/user/list',
save = '/health-emergency/emergency/profession/user/add',
edit = '/health-emergency/emergency/profession/user/edit',
deleteOne = '/health-emergency/emergency/profession/user/deleteBatch',
deleteBatch = '/health-emergency/emergency/profession/user/deleteBatch',
}
/**
* 列表接口
* @param params
*/
export const list = (params: any) => defHttp.get({ url: Api.list, params });
/**
* 删除单个
*/
export const deleteOne = (params: any, handleSuccess: Function) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.post({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 批量删除
* @param params
* @param handleSuccess
*/
export const batchDelete = (params: any, handleSuccess: Function) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.post({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 保存或者更新
* @param params
* @param isUpdate
*/
export const saveOrUpdate = (params: any, isUpdate: Boolean) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
@@ -0,0 +1,397 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { h, ref } from 'vue';
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
import { getEmergencyList } from '/@/views/consult/agentManagement/agentManagement.api';
import { allCenterApi } from '/@/views/emergency/scheduling/scheduling.api';
import { rules } from '/@/utils/helper/validator';
import { Image } from 'ant-design-vue';
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { EyeOutlined } from '@ant-design/icons-vue';
import { ComponentType } from '/@/components/Form/src/types';
//列表数据
export const columns = function (showGoodAt: boolean): BasicColumn[] {
return [
{
title: '用户账号',
align: 'center',
width: 150,
fixed: 'left',
dataIndex: 'username',
},
{
title: '姓名',
align: 'center',
fixed: 'left',
dataIndex: 'realname',
},
{
title: '头像',
align: 'center',
dataIndex: 'avatar',
width: 100,
customRender: ({ text }) => {
const t = text ? text.replace(',', '') : null;
return h(Image, {
placeholder: true,
src: getFileAccessHttpUrl(t),
height: 50,
width: 50,
fallback: getFamaleDefaultImage(''),
previewMask: () => {
return h(EyeOutlined, {
style: {
color: 'white',
},
});
},
});
},
},
{
title: '所属应急中心',
align: 'center',
dataIndex: 'centerName',
},
{
title: '职称',
align: 'center',
width: 90,
dataIndex: 'post_dictText',
},
{
title: '毕业院校',
align: 'center',
dataIndex: 'school',
},
{
title: '学历',
align: 'center',
dataIndex: 'edu_dictText',
},
{
title: '擅长症状',
align: 'center',
dataIndex: 'goodAt',
ifShow: showGoodAt,
},
];
};
//查询数据
export const searchFormSchema: FormSchema[] = [
{
label: '姓名',
field: 'name',
component: 'Input',
},
{
label: '所属应急中心',
field: 'centerId',
component: 'ApiSelect',
componentProps: {
//@ts-ignore
api: allCenterApi,
labelField: 'centerName',
valueField: 'id',
immediate: true,
resultField: 'records',
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input?.trim()?.toLowerCase();
return option.label.toLowerCase().indexOf(str) >= 0;
},
getPopupContainer: () => document.body,
},
},
];
//表单数据
// @ts-ignore
export const formSchema = function (showGoodAt: boolean): FormSchema[] {
return [
// 主键Id
{
label: '',
field: 'userId',
show: false,
component: 'Input',
},
{
label: '用户账号',
field: 'username',
component: 'Input',
componentProps: ({ formModel }) => {
return {
autocomplete: 'off',
onInput: (event: Event) => {
const target = event.target;
formModel.username = target?.value?.replace(/[^\w]/g, '');
},
};
},
rules: [{ required: true, message: '请输入用户账号' }],
dynamicDisabled: ({ values }) => {
return !!values.userId;
},
},
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
required: true,
componentProps: () => ({
maxCount: 1,
}),
},
{
label: '密码',
field: 'password',
component: 'StrengthMeter',
componentProps: {
//@ts-ignore
autocomplete: 'new-password',
readOnly: true,
onfocus: (field) => {
field.target.readOnly = false;
},
},
dynamicRules: () => {
return [
{
required: true,
validator: (_, value) => {
const { message } = checkPassword(value);
if (message === 'ok') {
return Promise.resolve();
} else {
return Promise.reject(message);
}
},
trigger: 'blur',
},
];
},
ifShow: ({ values }) => {
return !values.userId;
},
},
{
label: '确认密码',
field: 'confirmPassword',
component: 'InputPassword',
dynamicRules: ({ values }) => rules.confirmPassword(values, true),
ifShow: ({ values }) => {
return !values.userId;
},
},
{
label: '姓名',
field: 'realname',
component: 'Input',
required: true,
},
{
label: '所属应急中心',
field: 'centerId',
component: 'ApiSelect',
required: true,
componentProps: {
//@ts-ignore
api: getEmergencyList,
params: {
pageNo: 1,
pageSize: 200,
},
labelField: 'centerName',
valueField: 'id',
immediate: true,
resultField: 'records',
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input?.trim()?.toLowerCase();
return option.label.toLowerCase().indexOf(str) >= 0;
},
getPopupContainer: () => document.body,
},
},
{
label: '擅长症状',
field: 'goodAt',
component: 'InputTextArea',
required: true,
ifShow: showGoodAt,
},
{
label: '职称',
field: 'post',
component: 'JDictSelectTag',
componentProps: () => ({
dictCode: 'z_doct_lev',
getPopupContainer: () => document.body,
}),
required: true,
},
{
label: '毕业院校',
field: 'school',
component: 'Input',
},
{
label: '学历',
field: 'edu',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'education',
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input.trim().toLowerCase();
return option.label.toLowerCase().indexOf(str) >= 0;
},
getPopupContainer: () => document.body,
},
},
{
label: '人员类型',
field: 'type',
component: 'Input',
show: false,
},
];
};
interface DetailForm extends FormSchema {
value: string;
customRender?: Function;
component: ComponentType | 'Image';
}
export function useDetailForm(showGoodAt: boolean) {
const detailFormSchema = ref<DetailForm[]>([
{
label: '用户账号',
field: 'username',
component: 'Input',
value: '',
},
{
label: '姓名',
field: 'realname',
component: 'Input',
value: '',
},
{
label: '头像',
field: 'avatar',
component: 'Image',
value: '',
},
{
label: '所属应急中心',
field: 'centerName',
component: 'Input',
value: '',
},
{
label: '职称',
field: 'post_dictText',
component: 'Input',
value: '',
},
{
label: '毕业院校',
field: 'school',
component: 'Input',
value: '',
},
{
label: '学历',
field: 'edu_dictText',
component: 'Input',
value: '',
},
{
label: '擅长症状',
field: 'goodAt',
component: 'InputTextArea',
value: '',
ifShow: showGoodAt,
},
]);
function setData(record: Recordable, list: DetailForm[], callback?: Function) {
if (callback) {
callback(list);
return;
}
list = list.filter((item) => {
return item.ifShow === undefined || item.ifShow;
});
list.forEach((item) => {
const { field } = item;
const isEmpty = (obj, field) => {
if (!obj) return true;
return obj[field] === undefined || obj[field] === null || obj[field] === '';
};
if (!isEmpty(record, field)) {
if (Object.hasOwn(item, 'customRender')) {
// @ts-ignore
item.value = item.customRender(record);
} else if (Object.hasOwn(item, 'slot')) {
//@ts-ignore
item.value = { ...record, dataIndex: field };
} else {
item.value = record[field] || '';
}
} else {
item.value = '';
}
});
return list;
}
function getDetailSchema() {
return detailFormSchema.value.filter((item) => {
return item.ifShow === undefined || item.ifShow;
});
}
function setDetailFormData(record: Recordable) {
//@ts-ignore
setData(record, getDetailSchema());
}
return {
detailFormSchema,
getDetailSchema,
setDetailFormData,
};
}
/**
* 流程表单调用这个方法获取formSchema
*/
export function getBpmFormSchema(): FormSchema[] {
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
return formSchema;
}
/**
* @description: 人员类型
*/
export function getPersonType(t: string) {
enum PersonType {
'professional' = '6', //专业人员
'operation' = '5', //操作人员
}
return PersonType[t];
}
export const week_text = (key) => {
const type = {
1: '星期一',
2: '星期二',
3: '星期三',
4: '星期四',
5: '星期五',
6: '星期六',
7: '星期日',
};
return type[key];
};
@@ -0,0 +1,181 @@
<template>
<div>
<!--引用表格-->
<BasicTable :rowSelection="rowSelection" @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button v-auth="'profession:person_add'" preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd"> 新增 </a-button>
<a-button v-auth="'profession:person_delete'" @click="batchHandleDelete" type="primary" preIcon="ant-design:delete-outlined"
>批量删除
</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<!-- 表单区域 -->
<PersonnelModal @register="registerDrawer" @success="handleSuccess" />
<!--修改密码-->
<RestPass @register="restPassModal" />
</div>
</template>
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { useDrawer } from '/@/components/Drawer';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import { BasicTable, TableAction } from '/@/components/Table';
import { columns, searchFormSchema } from './personnelManagement.data';
import { batchDelete, deleteOne, list } from './personnelManagement.api';
import RestPass from '/@/views/system/user/restPass/RestPass.vue';
import PersonnelModal from './components/personnelModal.vue';
const [registerDrawer, { openDrawer: openFormDrawer }] = useDrawer();
//注册model
const [restPassModal, { openModal: restPaddModel }] = useModal();
/**
* 5 操作人员
* 6 专业人员
*/
const props = defineProps({
type: { type: String, default: () => '5' },
});
console.log(props);
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '应急分中心-操作人员/专业人员',
api: list,
columns: columns(props.type === '6'),
canResize: false,
showIndexColumn: true,
rowKey: 'userId',
formConfig: {
labelWidth: 100,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch: (par) => {
par['type'] = props.type;
return par;
},
actionColumn: {
width: 180,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
/**
* 新增
*/
function handleAdd() {
openFormDrawer(true, {
isUpdate: false,
showFooter: true,
type: '新增',
});
}
/**
* 编辑事件
*/
async function handleEdit(record: Recordable) {
openFormDrawer(true, {
record,
isUpdate: true,
showFooter: true,
type: '编辑',
});
}
/**
* 详情事件
*/
async function handleDetail(record: Recordable) {
openFormDrawer(true, {
record,
isUpdate: true,
showFooter: false,
type: '详情',
});
}
/**
* 删除事件
*/
function handleDelete(record: Recordable) {
deleteOne({ ids: record.userId }, handleSuccess);
}
/**
* 批量删除事件
*/
function batchHandleDelete() {
if (selectedRowKeys.value.length === 0) {
message.warning('未选中任何数据');
return;
}
batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
reload();
}
/**
* 操作栏
*/
function getTableAction(record: Recordable) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'profession:person_update',
},
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
];
}
// 重置密码
function restPass(record: Recordable) {
restPaddModel(true, {
record: record.userId,
isUpdate: true,
showFooter: false,
});
}
/**
* 下拉操作栏
*/
function getDropDownAction(record: Recordable) {
return [
{
label: '删除',
onClick: handleDelete.bind(null, record),
auth: 'profession:person_delete',
},
{
label: '重置密码',
onClick: restPass.bind(null, record),
auth: 'profession:person_reset_pass',
},
];
}
</script>
<style lang="less" scoped>
:deep(.ant-popover-buttons) {
display: flex !important;
}
</style>
@@ -0,0 +1,181 @@
<template>
<div>
<!--引用表格-->
<BasicTable :rowSelection="rowSelection" @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button v-auth="'profession:person_add'" preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd"> 新增 </a-button>
<a-button v-auth="'profession:person_delete'" @click="batchHandleDelete" type="primary" preIcon="ant-design:delete-outlined"
>批量删除
</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<!-- 表单区域 -->
<PersonnelModal @register="registerDrawer" @success="handleSuccess" />
<!--修改密码-->
<RestPass @register="restPassModal" />
</div>
</template>
<script lang="ts" setup>
import { message } from 'ant-design-vue';
import { useDrawer } from '/@/components/Drawer';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import { BasicTable, TableAction } from '/@/components/Table';
import { columns, searchFormSchema } from './personnelManagement.data';
import { batchDelete, deleteOne, list } from './personnelManagement.api';
import RestPass from '/@/views/system/user/restPass/RestPass.vue';
import PersonnelModal from './components/personnelModal.vue';
const [registerDrawer, { openDrawer: openFormDrawer }] = useDrawer();
//注册model
const [restPassModal, { openModal: restPaddModel }] = useModal();
/**
* 5 操作人员
* 6 专业人员
*/
const props = defineProps({
type: { type: String, default: () => '6' },
});
console.log(props);
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '应急分中心-操作人员/专业人员',
api: list,
columns: columns(props.type === '6'),
canResize: false,
showIndexColumn: true,
rowKey: 'userId',
formConfig: {
labelWidth: 100,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch: (par) => {
par['type'] = props.type;
return par;
},
actionColumn: {
width: 180,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
/**
* 新增
*/
function handleAdd() {
openFormDrawer(true, {
isUpdate: false,
showFooter: true,
type: '新增',
});
}
/**
* 编辑事件
*/
async function handleEdit(record: Recordable) {
openFormDrawer(true, {
record,
isUpdate: true,
showFooter: true,
type: '编辑',
});
}
/**
* 详情事件
*/
async function handleDetail(record: Recordable) {
openFormDrawer(true, {
record,
isUpdate: true,
showFooter: false,
type: '详情',
});
}
/**
* 删除事件
*/
function handleDelete(record: Recordable) {
deleteOne({ ids: record.userId }, handleSuccess);
}
/**
* 批量删除事件
*/
function batchHandleDelete() {
if (selectedRowKeys.value.length === 0) {
message.warning('未选中任何数据');
return;
}
batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
reload();
}
/**
* 操作栏
*/
function getTableAction(record: Recordable) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'profession:person_update',
},
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
];
}
// 重置密码
function restPass(record: Recordable) {
restPaddModel(true, {
record: record.userId,
isUpdate: true,
showFooter: false,
});
}
/**
* 下拉操作栏
*/
function getDropDownAction(record: Recordable) {
return [
{
label: '删除',
onClick: handleDelete.bind(null, record),
auth: 'profession:person_delete',
},
{
label: '重置密码',
onClick: restPass.bind(null, record),
auth: 'profession:person_reset_pass',
},
];
}
</script>
<style lang="less" scoped>
:deep(.ant-popover-buttons) {
display: flex !important;
}
</style>
+17
View File
@@ -6,6 +6,8 @@ import { Component, h } from 'vue';
import HealthUserEmployeeEx from './HealthUserEmployeeEx/HealthUserEmployeeExList.vue';
import healthExpert from '/@/views/consult/doctor/message/conDoctorList.vue';
import healthHelper from '/@/views/consult/helper/conHelperList.vue';
import personnelManagement1 from '/@/views/system/user/personnelManagement/personnelManagement1.vue';
import personnelManagement2 from '/@/views/system/user/personnelManagement/personnelManagement2.vue';
import { encipher } from '/@/utils/jsencrypt';
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
import { isShowIdCard } from '/@/utils/getEnv';
@@ -649,6 +651,7 @@ export interface UserType {
title: string;
component: Component;
auth?: string;
type?: string;
}
export const typeList: UserType[] = [
@@ -664,6 +667,20 @@ export const typeList: UserType[] = [
component: healthExpert,
auth: 'system:consultation:con_doctor:list',
},
{
key: 4,
title: '操作人员',
component: personnelManagement1,
auth: 'system:health_operator_ex:list',
type: '5',
},
{
key: 5,
title: '专业人员',
component: personnelManagement2,
auth: 'system:health_user_operator_ex:list',
type: '6',
},
{
key: 3,
title: '全科医生',