update
init
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/sys/healthUserEmployeeEx/list',
|
||||
save = '/sys/healthUserEmployeeEx/add',
|
||||
edit = '/sys/healthUserEmployeeEx/edit',
|
||||
deleteOne = '/sys/healthUserEmployeeEx/delete',
|
||||
deleteBatch = '/sys/healthUserEmployeeEx/deleteBatch',
|
||||
importExcel = '/sys/healthUserEmployeeEx/importExcel',
|
||||
exportXls = '/sys/healthUserEmployeeEx/exportXls',
|
||||
queryById = '/sys/healthUserEmployeeEx/queryById',
|
||||
getWatchDeviceByUserId = '/health-watch/watch/watchDevice/getWatchDeviceByUserId',
|
||||
updateUserDepart = '/health-system/system/sysUserDepartChangeApply/add',
|
||||
exportTempXls = '/sys/healthUserEmployeeEx/exportTemp',
|
||||
exportTempDepart = '/sys/healthUserEmployeeEx/departTemp',
|
||||
importDepartExcel = '/sys/healthUserEmployeeEx/importDepartExcel',
|
||||
checkUser = '/sys/healthUserEmployeeEx/checkUser',
|
||||
updateUser = '/sys/healthUserEmployeeEx/updateUser',
|
||||
checkDepart = '/sys/healthUserEmployeeEx/checkDepart',
|
||||
updateDepart = '/sys/healthUserEmployeeEx/updateDepart',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
export const checkUserUrl = Api.checkUser;
|
||||
export const updateUserUrl = Api.updateUser;
|
||||
|
||||
export const checkDepartUrl = Api.checkDepart;
|
||||
export const updateDepartUrl = Api.updateDepart;
|
||||
|
||||
// export const exportExcel = (params) => defHttp.get({ url: Api.exportXls, params });
|
||||
export const exportExcel = (params) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: '确定启动导出任务吗?',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.get({ url: Api.exportXls, params });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const getExportTempUrl = Api.exportTempXls;
|
||||
|
||||
export const getExportDepartTempUrl = Api.exportTempDepart;
|
||||
|
||||
|
||||
export const queryByIdUrl = Api.queryById;
|
||||
|
||||
/**
|
||||
* 请求编辑数据
|
||||
*/
|
||||
export const resEditData = async (params) => {
|
||||
return await defHttp.get({ url: Api.queryById, params }, { joinParamsToUrl: true });
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
export const getImportDepartUrl = Api.importDepartExcel;
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否确认删除',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteOne,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc 查询用户是否绑定手表
|
||||
*/
|
||||
export const getWatchDeviceByUserId = (params) => defHttp.get({ url: Api.getWatchDeviceByUserId, params });
|
||||
|
||||
/**
|
||||
* @desc 更新用户单位
|
||||
* */
|
||||
export const updateUserDepart=(params)=>defHttp.post({url:Api.updateUserDepart,params})
|
||||
@@ -0,0 +1,839 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { h } from 'vue';
|
||||
import { Image, message } from 'ant-design-vue';
|
||||
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getSecondaryDepartmentList, getThirdDepartmentList } from '/@/views/system/user/user.api';
|
||||
import { allSecondaryDepartsNew, getFourthDepartsNew } from '/@/utils/system/api';
|
||||
import { rules } from '/@/utils/helper/validator';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
import { isShowIdCard } from '/@/utils/getEnv';
|
||||
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '员工账号',
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
dataIndex: 'username',
|
||||
},
|
||||
{
|
||||
title: '员工姓名',
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
dataIndex: 'realname',
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
align: 'center',
|
||||
dataIndex: 'sex_dictText',
|
||||
width: 64,
|
||||
},
|
||||
{
|
||||
title: '员工编号',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empSysno'],
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
align: 'center',
|
||||
dataIndex: 'avatar',
|
||||
width: 64,
|
||||
customRender: ({ text, record }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text) || '',
|
||||
height: 40,
|
||||
width: 40,
|
||||
fallback: getFamaleDefaultImage(record.sex),
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
align: 'center',
|
||||
dataIndex: 'idCard',
|
||||
width: 160,
|
||||
ifShow: isShowIdCard(),
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
align: 'center',
|
||||
dataIndex: 'phone',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status_dictText',
|
||||
width: 80,
|
||||
slots: { customRender: 'statusTag' },
|
||||
},
|
||||
{
|
||||
title: '单位名称',
|
||||
align: 'center',
|
||||
dataIndex: ['secondDepart', 'departName'],
|
||||
},
|
||||
{
|
||||
title: '部门名称',
|
||||
align: 'center',
|
||||
dataIndex: ['departTree', '2'],
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '四级部门名称',
|
||||
align: 'center',
|
||||
dataIndex: ['departTree', '3'],
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '出生日期',
|
||||
align: 'center',
|
||||
dataIndex: 'birthday',
|
||||
},
|
||||
{
|
||||
title: '职务',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empJob_dictText'],
|
||||
},
|
||||
{
|
||||
title: '行政级别',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empLevel_dictText'],
|
||||
},
|
||||
{
|
||||
title: '民族',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empNation_dictText'],
|
||||
},
|
||||
{
|
||||
title: '学历',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empDegree_dictText'],
|
||||
},
|
||||
{
|
||||
title: '婚姻状况',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empMarriage_dictText'],
|
||||
},
|
||||
{
|
||||
title: '籍贯',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empNativeplace'],
|
||||
},
|
||||
{
|
||||
title: '工种',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'medicalWorkTypeCode_dictText'],
|
||||
},
|
||||
{
|
||||
title: '用工形式',
|
||||
align: 'center',
|
||||
dataIndex: ['extension', 'empType_dictText'],
|
||||
},
|
||||
];
|
||||
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '员工账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '员工姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '员工编号',
|
||||
field: 'empNo',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
ifShow: isShowIdCard(),
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '单位名称',
|
||||
field: 'orgCode',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: allSecondaryDepartsNew,
|
||||
resultField: 'result',
|
||||
labelField: 'departName',
|
||||
valueField: 'orgCode',
|
||||
immediate: true,
|
||||
onChange: (_value, option) => {
|
||||
formModel.departId = option?.id || '';
|
||||
formModel.orgCode2 = '';
|
||||
},
|
||||
onDeselect: () => {
|
||||
formModel.departId = '';
|
||||
formModel.orgCode2 = '';
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '部门名称',
|
||||
field: 'orgCode2',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: getThirdDepartmentList,
|
||||
resultField: 'list',
|
||||
labelField: 'departName',
|
||||
params: {
|
||||
secondDepartId: formModel?.departId || '',
|
||||
},
|
||||
valueField: 'orgCode',
|
||||
immediate: false,
|
||||
onFocus: () => {
|
||||
if (!formModel.departId) {
|
||||
return message.warn('请先选择单位!');
|
||||
}
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '四级部门名称',
|
||||
field: 'deptCode',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: getFourthDepartsNew,
|
||||
resultField: 'result',
|
||||
labelField: 'departName',
|
||||
params: {
|
||||
idOrCode: formModel.orgCode2 || '',
|
||||
},
|
||||
valueField: 'orgCode',
|
||||
immediate: false,
|
||||
onFocus: () => {
|
||||
if (!formModel.orgCode2) {
|
||||
return message.warn('请先选择部门!');
|
||||
}
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
//表单数据
|
||||
export const formSchema: (isUpdate: boolean) => FormSchema[] = (isUpdate) => {
|
||||
return [
|
||||
{
|
||||
label: '员工账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
onInput: () => {
|
||||
formModel.username = formModel.username.replace(/[^a-zA-Z0-9_]/g, '');
|
||||
},
|
||||
autocomplete: 'off',
|
||||
placeholder: '请输入员工姓名全拼+数字',
|
||||
};
|
||||
},
|
||||
required: true,
|
||||
dynamicDisabled: isUpdate,
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
required: !isUpdate,
|
||||
ifShow: !isUpdate,
|
||||
},
|
||||
{
|
||||
label: '员工姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '员工编号',
|
||||
field: 'empSysno',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
onInput: () => {
|
||||
formModel.empSysno = formModel.empSysno.replace(/[^0-9]/g, '');
|
||||
},
|
||||
};
|
||||
},
|
||||
dynamicRules: ({ model, schema }) =>
|
||||
rules.duplicateCheckRuleAndDelFlag('health_user_employee_ex', 'emp_sysno', 'false', model, schema, false),
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'sex2',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '头像',
|
||||
field: 'avatar',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'secondDepartName',
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
dynamicDisabled: true,
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '部门',
|
||||
field: 'orgCode',
|
||||
component: 'JSelectDeptStaff',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
sync: true,
|
||||
checkStrictly: true,
|
||||
defaultExpandLevel: 1,
|
||||
initOptions: isUpdate
|
||||
? [
|
||||
{
|
||||
value: formModel.departId,
|
||||
label: ' ' + formModel.secondDepartName + ' - ' + formModel.departName + ' ',
|
||||
},
|
||||
]
|
||||
: [],
|
||||
};
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '出生日期',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
onInput: () => {
|
||||
formModel.idCard = formModel.idCard.replace(/[^Xx0-9]/g, '');
|
||||
},
|
||||
};
|
||||
},
|
||||
// rules: [
|
||||
// {
|
||||
// required: true,
|
||||
// },
|
||||
// {
|
||||
// pattern: /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|[xX])$/,
|
||||
// message: '${label}格式有误',
|
||||
// },
|
||||
// ],
|
||||
dynamicRules: ({ model, schema }) =>
|
||||
rules.idcard(true).concat(rules.duplicateCheckRuleAndDelFlag('sys_user', 'id_card', 'false', model, schema, false)),
|
||||
// dynamicRules: ({ model, schema }) => rules.idcard(true).concat(rules.duplicateCheckRule('sys_user', 'id_card', model, schema, false)),
|
||||
},
|
||||
|
||||
/*{
|
||||
label: '身份证正面',
|
||||
field: 'empIdcardFace',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '身份证反面',
|
||||
field: 'empIdcardBack',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
},*/
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
onInput: () => {
|
||||
formModel.phone = formModel.phone.replace(/[^0-9]/g, '');
|
||||
},
|
||||
};
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
pattern: /^1[3456789][0-9]{9}$/,
|
||||
message: '${label}格式有误',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
field: 'email',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{
|
||||
pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
|
||||
message: '${label}格式有误',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '职务',
|
||||
field: 'empJob',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'e_job',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'empTitle',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'e_title',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: '子组',
|
||||
// field: 'empGroup',
|
||||
// component: 'JDictSelectTag',
|
||||
// componentProps: {
|
||||
// dictCode: 'emp_group',
|
||||
// showSearch: true,
|
||||
// filterOption: (input: string, option: any): boolean => {
|
||||
// const str: string = input.trim().toLowerCase();
|
||||
// return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
{
|
||||
label: '职位',
|
||||
field: 'empPosition',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_position',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
label: '行政级别',
|
||||
field: 'empLevel',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_level',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '员工状态',
|
||||
field: 'empStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_status',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '政治面貌',
|
||||
field: 'empPolitical',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_political',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'empNation',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'nation',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
field: 'empDegree',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_education',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '婚姻状况',
|
||||
field: 'empMarriage',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'mr_state',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
field: 'empNativeplace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '入职时间',
|
||||
field: 'empWorktime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '体检形式',
|
||||
field: 'medicalOnJob',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'medical_on_job',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '工种',
|
||||
field: 'medicalWorkTypeCode',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'medical_worktype',
|
||||
showSearch: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '其他工种',
|
||||
field: 'medicalWorkTypeOther',
|
||||
component: 'Input',
|
||||
ifShow: ({ model }) => {
|
||||
return model.medicalWorkTypeCode === '0014' || model.medicalWorkTypeCode === '0033' || model.medicalWorkTypeCode === '999999';
|
||||
},
|
||||
required: ({ model }) => {
|
||||
return model.medicalWorkTypeCode === '0014' || model.medicalWorkTypeCode === '0033' || model.medicalWorkTypeCode === '999999';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '危害因素',
|
||||
field: 'medicalHazardFactorCode',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'medical_hazard',
|
||||
showSearch: true,
|
||||
mode: 'multiple',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '其他危害',
|
||||
field: 'medicalHazardFactorOther',
|
||||
component: 'Input',
|
||||
ifShow: ({ model }) => {
|
||||
return model.medicalHazardFactorCode?.join(',').indexOf('0999') > -1;
|
||||
},
|
||||
required: ({ model }) => {
|
||||
return model.medicalHazardFactorCode?.join(',').indexOf('0999') > -1;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '接害时间',
|
||||
field: 'medicalHazardDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '用工形式',
|
||||
field: 'empType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'contract',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '上市员工',
|
||||
field: 'listedFlag',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
type: 'radio',
|
||||
dictCode: 'sf_10',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '工作地点',
|
||||
field: 'workSpace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '居住地点',
|
||||
field: 'liveSpace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'personType',
|
||||
component: 'Input',
|
||||
defaultValue: '1',
|
||||
dynamicDisabled: true,
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'departName',
|
||||
component: 'Input',
|
||||
dynamicDisabled: true,
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'departId',
|
||||
component: 'Input',
|
||||
dynamicDisabled: true,
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
//迁移用户
|
||||
export const migrateUserFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '员工姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '员工编号',
|
||||
field: 'workNo',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '单位名称',
|
||||
field: 'oldSecond',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '部门名称',
|
||||
field: 'oldThird',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '迁移单位',
|
||||
field: 'toDepartCode',
|
||||
component: 'ApiTreeSelect',
|
||||
required: true,
|
||||
componentProps: ({ formModel }) => {
|
||||
let treeData: any;
|
||||
return {
|
||||
api: getSecondaryDepartmentList,
|
||||
fieldNames: {
|
||||
label: 'departName',
|
||||
value: 'orgCode',
|
||||
},
|
||||
immediate: true,
|
||||
onSelect: (val, v) => {
|
||||
formModel.toDepartId = v.id;
|
||||
},
|
||||
onOptionsChange: (data) => {
|
||||
treeData = data;
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
loadData: async (treeNode: any) => {
|
||||
return new Promise(async (resolve) => {
|
||||
const { id } = treeNode.dataRef;
|
||||
const result = await getThirdDepartmentList({ secondDepartId: id });
|
||||
|
||||
const add = (pid, children, treeArray) => {
|
||||
if (treeArray && treeArray.length > 0) {
|
||||
// @ts-ignore
|
||||
for (const item of treeArray) {
|
||||
if (item.id == pid) {
|
||||
if (!children || children.length == 0) {
|
||||
item.isLeaf = true;
|
||||
} else {
|
||||
item['children'] = children;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
add(pid, children, item.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
add(id, result, treeData);
|
||||
resolve(treeData);
|
||||
});
|
||||
},
|
||||
getPopupContainer: () => document.body,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'isBind',
|
||||
component: 'ApiSelect',
|
||||
slot: 'isBind',
|
||||
required: true,
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '是(解除绑定,手表仍属于当前单位)',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '否(不解除绑定,手表跟随用户一并迁移至新单位)',
|
||||
value: '0',
|
||||
},
|
||||
],
|
||||
},
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '是否解绑',
|
||||
field: 'watchStatus',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '迁移部门id',
|
||||
field: 'toDepartId',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '原部门Code',
|
||||
field: 'fromDepartCode',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '原部门Id',
|
||||
field: 'fromDepartId',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'userId',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,424 @@
|
||||
<template xmlns="">
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable :rowSelection="rowSelection" @register="registerTable">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="'system:health_user_employee_ex:add'" preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd">
|
||||
新增
|
||||
</a-button>
|
||||
<a-button
|
||||
v-auth="'system:health_user_employee_ex:deleteBatch'"
|
||||
preIcon="ant-design:delete-outlined"
|
||||
type="primary"
|
||||
@click="batchHandleDelete"
|
||||
>
|
||||
批量删除
|
||||
</a-button>
|
||||
<a-button-group>
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:export-outlined"
|
||||
@click="onExportXlsx"
|
||||
v-auth="'system:health_user_employee_ex:exportXls'"
|
||||
>
|
||||
导出
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:export-outlined"
|
||||
@click="exportRecord"
|
||||
v-auth="'system:health_user_employee_ex:exportXls'"
|
||||
>
|
||||
查看导出任务
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
<a-button-group>
|
||||
<a-tooltip placement="top" arrow-point-at-center>
|
||||
<template #title>
|
||||
<span>
|
||||
批量导入员工信息:<br />
|
||||
1.下载【员工信息模板】;<br />
|
||||
2.在模板中填写员工信息,点击【员工信息导入】<br />
|
||||
3.导入成功后,点击【查看任务】,依次进行数据【校验】及【更新】,校验不成功则按错误提示修改信息,重新导入<br />
|
||||
</span>
|
||||
</template>
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:download-outlined"
|
||||
@click="downloadTemp"
|
||||
v-auth="'system:health_user_employee_ex:importExcel'"
|
||||
>员工信息模板下载</a-button
|
||||
>
|
||||
<j-upload-button
|
||||
type="primary"
|
||||
preIcon="ant-design:import-outlined"
|
||||
@click="onImportXls"
|
||||
v-auth="'system:health_user_employee_ex:importExcel'"
|
||||
>员工信息导入</j-upload-button
|
||||
>
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:search-outlined"
|
||||
@click="importUser"
|
||||
v-auth="'system:health_user_employee_ex:importExcel'"
|
||||
>查看任务</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
</a-button-group>
|
||||
<a-button-group>
|
||||
<a-tooltip placement="top" arrow-point-at-center>
|
||||
<template #title>
|
||||
<span>
|
||||
批量导入员工部门更新信息:<br />
|
||||
1.下载【员工部门更新模版】;<br />
|
||||
2.在模板中填写员工信息,点击【员工部门更新信息导入】<br />
|
||||
3.导入成功后,点击【查看任务】,依次进行数据【校验】及【更新】,校验不成功则按错误提示修改信息,重新导入<br />
|
||||
</span>
|
||||
</template>
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:download-outlined"
|
||||
@click="downloadDepartTemp"
|
||||
v-auth="'system:health_user_employee_ex:importDepartExcel'"
|
||||
>员工部门更新模版下载</a-button
|
||||
>
|
||||
<j-upload-button
|
||||
type="primary"
|
||||
preIcon="ant-design:import-outlined"
|
||||
@click="onImportXlsx"
|
||||
v-auth="'system:health_user_employee_ex:importDepartExcel'"
|
||||
>员工部门更新信息导入</j-upload-button
|
||||
>
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:search-outlined"
|
||||
@click="importDepart"
|
||||
v-auth="'system:health_user_employee_ex:importDepartExcel'"
|
||||
>查看任务</a-button
|
||||
>
|
||||
</a-tooltip>
|
||||
</a-button-group>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<template #statusTag="{ record }">
|
||||
<Tag :color="record.status == '2' ? 'red' : 'green'">
|
||||
{{ record.status_dictText }}
|
||||
</Tag>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<HealthUserEmployeeExDrawer :showFooter="showFooter" @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
<!--迁移用户-->
|
||||
<MigrateUsers @register="restMigrateUsersModal" @success="handleSuccess" />
|
||||
<!-- 导出文件记录 -->
|
||||
<ExportUtil task-code="userEmployeeExExport" @register="registerExport" />
|
||||
<ImportUtil task-code="importUpdateUserEmpInfo" :check-url="checkUserUrl" :update-url="updateUserUrl" @register="registerUserImport" />
|
||||
<ImportUtil
|
||||
task-code="importUpdateUserDepartInfo"
|
||||
:check-url="checkDepartUrl"
|
||||
:update-url="updateDepartUrl"
|
||||
@register="registerDepartImport"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-healthUserEmployeeEx" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import HealthUserEmployeeExDrawer from './components/HealthUserEmployeeExDrawer.vue';
|
||||
import MigrateUsers from '/@/views/system/user/HealthUserEmployeeEx/components/migrateUsers.vue';
|
||||
import { columns, searchFormSchema } from './HealthUserEmployeeEx.data';
|
||||
import {
|
||||
batchDelete,
|
||||
checkDepartUrl,
|
||||
checkUserUrl,
|
||||
deleteOne,
|
||||
exportExcel,
|
||||
getExportDepartTempUrl,
|
||||
getExportTempUrl,
|
||||
getExportUrl,
|
||||
getImportDepartUrl,
|
||||
getImportUrl,
|
||||
getWatchDeviceByUserId,
|
||||
list,
|
||||
resEditData,
|
||||
updateDepartUrl,
|
||||
updateUserUrl,
|
||||
} from './HealthUserEmployeeEx.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
import RestPass from '../restPass/RestPass.vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { lockUser } from '/@/views/system/user/hospitalDoctor/HospitalDoctor.api';
|
||||
import ExportUtil from '/@/utils/export/exportUtil.vue';
|
||||
import JUploadButton from '/@/components/Button/src/JUploadButton.vue';
|
||||
import ImportUtil from '/@/utils/import/ImportUtil.vue';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
import { getEnvInfo } from '/@/utils/getEnv';
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const [registerExport, { openDrawer: exportDrawer }] = useDrawer();
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
const [restMigrateUsersModal, { openModal }] = useModal();
|
||||
const [registerUserImport, { openDrawer: userImportDrawer }] = useDrawer();
|
||||
const [registerDepartImport, { openDrawer: departImportDrawer }] = useDrawer();
|
||||
const showFooter = ref(true);
|
||||
//注册table数据
|
||||
const { tableContext, onExportXls, onImportXls, onImportXlsx } = useListPage({
|
||||
tableProps: {
|
||||
title: '员工',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
clickToRowSelect: false,
|
||||
beforeFetch: (params) => {
|
||||
if (params.orgCode2) {
|
||||
params.orgCode = params.orgCode2;
|
||||
}
|
||||
},
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 240,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '员工',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
importConfig2: {
|
||||
url: getImportDepartUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload, getForm }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
showFooter.value = true;
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
type: '新增',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable, type) {
|
||||
showFooter.value = true;
|
||||
getEdit(record, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable, type) {
|
||||
showFooter.value = false;
|
||||
getEdit(record, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编辑数据
|
||||
*/
|
||||
function getEdit(record, type) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
openDrawer(true, {
|
||||
record: {
|
||||
...res.extension,
|
||||
...res,
|
||||
orgCode: res?.depart?.id,
|
||||
departId: res?.depart?.id,
|
||||
departName: res?.depart?.departName,
|
||||
secondDepartName: res?.secondDepart?.departName,
|
||||
},
|
||||
type,
|
||||
isUpdate: true,
|
||||
showFooter: unref(showFooter),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
message.warning('未选中任何数据');
|
||||
return;
|
||||
}
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record, '编辑'),
|
||||
auth: 'system:health_user_employee_ex:edit',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'system:health_user_employee_ex:delete',
|
||||
},
|
||||
{
|
||||
label: '用户转出',
|
||||
onClick: handleMigrateUsers.bind(null, record),
|
||||
auth: 'system:sys_user_depart_change_apply:add',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
function restPass(record) {
|
||||
restPaddModel(true, {
|
||||
record: record.id,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
|
||||
// 1 锁定用户 2 激活用户
|
||||
async function handleUserOpt(record, type) {
|
||||
const params = {
|
||||
userId: record.id,
|
||||
status: type,
|
||||
};
|
||||
await lockUser(params, type, handleSuccess);
|
||||
}
|
||||
|
||||
async function handleMigrateUsers(record: Recordable) {
|
||||
const res = getEnvInfo();
|
||||
let result = false;
|
||||
let params = {
|
||||
...record,
|
||||
orgCode: '',
|
||||
oldSecond: record.secondDepart?.departName,
|
||||
oldThird: record.depart?.departName,
|
||||
workNo: record?.extension?.empNo,
|
||||
};
|
||||
if (res.VITE_PLATFORM !== 'QH') {
|
||||
result = await getWatchDeviceByUserId({ userId: record.id });
|
||||
params.hasWatch = result;
|
||||
}
|
||||
openModal(true, {
|
||||
record: params,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '重置密码',
|
||||
onClick: restPass.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '锁定用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 2),
|
||||
},
|
||||
{
|
||||
label: '激活用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 1),
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record, '详情'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 导出到记录表
|
||||
async function onExportXlsx() {
|
||||
const form = getForm().getFieldsValue();
|
||||
await exportExcel(form);
|
||||
}
|
||||
function exportRecord() {
|
||||
exportDrawer(true, {});
|
||||
}
|
||||
//导出模版按钮
|
||||
function downloadTemp() {
|
||||
let optionConfig = {
|
||||
exportConfig: {
|
||||
name: '员工信息导入模版',
|
||||
url: getExportTempUrl,
|
||||
params: {
|
||||
isXlsx: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
onExportXls(optionConfig);
|
||||
}
|
||||
//部门模版按钮
|
||||
function downloadDepartTemp() {
|
||||
let optionConfig = {
|
||||
exportConfig: {
|
||||
name: '员工更新部门导入模版',
|
||||
url: getExportDepartTempUrl,
|
||||
params: {
|
||||
isXlsx: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
onExportXls(optionConfig);
|
||||
}
|
||||
|
||||
function importUser() {
|
||||
userImportDrawer(true, () => {
|
||||
reload();
|
||||
});
|
||||
}
|
||||
|
||||
function importDepart() {
|
||||
departImportDrawer(true, () => {
|
||||
reload();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:maskClosable="false"
|
||||
:title="titleType"
|
||||
:width="adaptiveWidth * 1.5"
|
||||
destroyOnClose
|
||||
showFooter
|
||||
v-bind="$attrs"
|
||||
@ok="handleSubmit"
|
||||
@register="registerDrawer"
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, useAttrs } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { formSchema } from '../HealthUserEmployeeEx.data';
|
||||
import { saveOrUpdate } from '../HealthUserEmployeeEx.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
import { dealParams } from '/@/views/system/user/user.data';
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
const attrs = useAttrs();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const titleType = ref(String);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, updateSchema, validate, clearValidate }] = useForm({
|
||||
schemas: formSchema(unref(isUpdate)),
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
});
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
titleType.value = data.type;
|
||||
if (typeof data.record === 'object') {
|
||||
if (data.record.medicalHazardFactorCode !== null) {
|
||||
data.record.medicalHazardFactorCode = data.record.medicalHazardFactorCode.split(',');
|
||||
}
|
||||
await setFieldsValue({ ...data.record });
|
||||
}
|
||||
await updateSchema(formSchema(unref(isUpdate)));
|
||||
await clearValidate();
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !attrs.showFooter });
|
||||
});
|
||||
|
||||
function preSubmit(values) {
|
||||
return {
|
||||
...values,
|
||||
extension: values,
|
||||
};
|
||||
}
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = preSubmit(await validate());
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
if (!values.birthday) {
|
||||
values.birthday = values.idCard.substring(6, 10) + '-' + values.idCard.substring(10, 12) + '-' + values.idCard.substring(12, 14);
|
||||
}
|
||||
|
||||
//提交表单
|
||||
await saveOrUpdate(dealParams(values), isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<!--迁移用户-->
|
||||
<template>
|
||||
<BasicModal :width="700" destroyOnClose title="迁移用户" v-bind="$attrs" @ok="handleSubmit" @register="registerModal">
|
||||
<BasicForm @register="registerForm">
|
||||
<template #isBind="{ model, schema }">
|
||||
<div style="margin-left: 50px">
|
||||
<h3 style="font-weight: 700">当前员工已绑定手表,是否解除绑定?</h3>
|
||||
<a-radio-group v-model:value="model.isBind" :options="schema.componentProps.options">
|
||||
<template #label="{ label }">
|
||||
<span>{{ label }}</span>
|
||||
</template>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { migrateUserFormSchema } from '/@/views/system/user/HealthUserEmployeeEx/HealthUserEmployeeEx.data';
|
||||
import { updateUserDepart } from '/@/views/system/user/HealthUserEmployeeEx/HealthUserEmployeeEx.api';
|
||||
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema, clearValidate }] = useForm({
|
||||
schemas: migrateUserFormSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
// 如果未绑定手表,则隐藏解绑提示
|
||||
if (data.record.hasWatch === true) {
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'isBind',
|
||||
show: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
userId: data.record.id,
|
||||
fromDepartCode: data.record.depart?.orgCode || data.record.secondDepart?.orgCode,
|
||||
fromDepartId: data.record.depart?.id || data.record.secondDepart?.id,
|
||||
});
|
||||
}
|
||||
await clearValidate();
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
values.watchStatus = values.isBind == '1';
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await updateUserDepart(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" title="修改密码" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" name="PassWordModal" setup>
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formPasswordSchema } from './user.data';
|
||||
import { changePassword } from './user.api';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||
schemas: formPasswordSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
//表单赋值
|
||||
await setFieldsValue({ ...data });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await changePassword(values);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="handleCreate"> 新增 </a-button>
|
||||
<JThirdAppButton biz-type="user" :selected-row-keys="selectedRowKeys" syncToApp syncToLocal @sync-finally="onSyncFinally" />
|
||||
<a-button preIcon="ant-design:user-delete-outlined" type="primary" @click="openQuitModal(true, {})">离职信息 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--用户抽屉-->
|
||||
<UserDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 离职受理人弹窗 -->
|
||||
<UserQuitAgentModal @register="registerQuitAgentModal" @success="reload" />
|
||||
<!-- 离职人员列弹窗 -->
|
||||
<UserQuitModal @register="registerQuitModal" @success="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="tenant-system-user" setup>
|
||||
//ts语法
|
||||
import { BasicTable, TableAction, ActionItem } from '/@/components/Table';
|
||||
import UserDrawer from './UserDrawer.vue';
|
||||
import JThirdAppButton from '/@/components/jeecg/thirdApp/JThirdAppButton.vue';
|
||||
import UserQuitAgentModal from './UserQuitAgentModal.vue';
|
||||
import UserQuitModal from './UserQuitModal.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { columns, searchFormSchema } from './user.data';
|
||||
import {
|
||||
list,
|
||||
deleteUser,
|
||||
batchDeleteUser,
|
||||
getImportUrl,
|
||||
getExportUrl,
|
||||
frozenBatch,
|
||||
syncUser,
|
||||
getUserTenantPageList,
|
||||
updateUserTenantStatus,
|
||||
} from './user.api';
|
||||
// import { usePermission } from '/@/hooks/web/usePermission'
|
||||
// const { hasPermission } = usePermission();
|
||||
import { userTenantColumns, userTenantFormSchema } from './user.data';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
|
||||
const { createMessage, createConfirm } = useMessage();
|
||||
|
||||
//注册drawer
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
//离职代理人model
|
||||
const [registerQuitAgentModal, { openModal: openQuitAgentModal }] = useModal();
|
||||
//离职用户列表model
|
||||
const [registerQuitModal, { openModal: openQuitModal }] = useModal();
|
||||
const userStore = useUserStore();
|
||||
const createBy = userStore.getUserInfo.username;
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
designScope: 'user-list',
|
||||
tableProps: {
|
||||
title: '租户用户列表',
|
||||
api: getUserTenantPageList,
|
||||
columns: userTenantColumns,
|
||||
size: 'small',
|
||||
formConfig: {
|
||||
schemas: userTenantFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
params['userTenantStatus'] = '1,3,4';
|
||||
return Object.assign({ column: 'createTime', order: 'desc' }, params);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
//注册table数据
|
||||
const [registerTable, { reload, updateTableDataRecord }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleCreate() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
async function handleDetail(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
*同步钉钉和微信回调
|
||||
*/
|
||||
function onSyncFinally({ isToLocal }) {
|
||||
// 同步到本地时刷新下数据
|
||||
if (isToLocal) {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record): ActionItem[] {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
// ifShow: () => hasPermission('system:user:edit'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record): ActionItem[] {
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '离职',
|
||||
onClick: handleQuit.bind(null, record.username),
|
||||
//update-begin---author:wangshuai ---date:20230130 for:[QQYUN-3974]租户的创建人 不应该有离职按钮------------
|
||||
ifShow: () => {
|
||||
return record.username !== record.createBy;
|
||||
},
|
||||
//update-end---author:wangshuai ---date:20230130 for:[QQYUN-3974]租户的创建人 不应该有离职按钮------------
|
||||
},
|
||||
{
|
||||
label: '同意',
|
||||
onClick: updateStatus.bind(null, record.id, '1'),
|
||||
ifShow: () => {
|
||||
return (record.status === '3' || record.status === '4') && record.createBy === createBy;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '拒绝',
|
||||
popConfirm: {
|
||||
title: '是否确认拒绝',
|
||||
confirm: updateStatus.bind(null, record.id, '4'),
|
||||
},
|
||||
ifShow: () => {
|
||||
return record.status === '3' && record.createBy === createBy;
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 离职
|
||||
* @param userName
|
||||
*/
|
||||
function handleQuit(userName) {
|
||||
//打开离职代理人弹窗
|
||||
openQuitAgentModal(true, { userName });
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户租户状态
|
||||
* @param id
|
||||
* @param status
|
||||
*/
|
||||
function updateStatus(id, status) {
|
||||
updateUserTenantStatus({ userId: id, status: status })
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
handleSuccess();
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
createMessage.warning(e.message);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :width="800" title="用户代理" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formAgentSchema } from './user.data';
|
||||
import { getUserAgent, saveOrUpdateAgent } from './user.api';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||
schemas: formAgentSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
//查询获取表单数据
|
||||
const res = await getUserAgent({ userName: data.userName });
|
||||
data = res.result ? res.result : data;
|
||||
//表单赋值
|
||||
await setFieldsValue({ ...data });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdateAgent(values);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
:title="getTitle"
|
||||
:width="adaptiveWidth"
|
||||
@ok="handleSubmit"
|
||||
:showFooter="showFooter"
|
||||
destroyOnClose
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent, ref, computed, unref, useAttrs } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from './user.data';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { saveOrUpdateUser, getUserRoles, getUserDepartList } from './user.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const attrs = useAttrs();
|
||||
const isUpdate = ref(true);
|
||||
const rowId = ref('');
|
||||
const departOptions = ref([]);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema, clearValidate }] = useForm({
|
||||
labelWidth: 90,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
// TODO [VUEN-527] https://www.teambition.com/task/6239beb894b358003fe93626
|
||||
const showFooter = ref(true);
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
await resetFields();
|
||||
showFooter.value = data?.showFooter ?? true;
|
||||
setDrawerProps({ confirmLoading: false, showFooter: showFooter.value });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
rowId.value = data.record.id;
|
||||
//租户信息定义成数组
|
||||
if (data.record.relTenantIds && !Array.isArray(data.record.relTenantIds)) {
|
||||
data.record.relTenantIds = data.record.relTenantIds.split(',');
|
||||
} else {
|
||||
//【issues/I56C5I】用户管理中连续点两次编辑租户配置就丢失了
|
||||
//data.record.relTenantIds = [];
|
||||
}
|
||||
|
||||
//查角色/赋值/try catch 处理,不然编辑有问题
|
||||
try {
|
||||
const userRoles = await getUserRoles({ userid: data.record.id });
|
||||
if (userRoles && userRoles.length > 0) {
|
||||
data.record.selectedroles = userRoles;
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
//查所属部门/赋值
|
||||
const userDepart = await getUserDepartList({ userId: data.record.id });
|
||||
if (userDepart && userDepart.length > 0) {
|
||||
data.record.selecteddeparts = userDepart;
|
||||
let selectDepartKeys = Array.from(userDepart, ({ key }) => key);
|
||||
data.record.selecteddeparts = selectDepartKeys.join(',');
|
||||
departOptions.value = userDepart.map((item) => {
|
||||
return { label: item.title, value: item.key };
|
||||
});
|
||||
}
|
||||
//负责部门/赋值
|
||||
data.record.departIds && !Array.isArray(data.record.departIds) && (data.record.departIds = data.record.departIds.split(','));
|
||||
//update-begin---author:zyf Date:20211210 for:避免空值显示异常------------
|
||||
data.record.departIds = data.record.departIds == '' ? [] : data.record.departIds;
|
||||
//update-begin---author:zyf Date:20211210 for:避免空值显示异常------------
|
||||
}
|
||||
//处理角色用户列表情况(和角色列表有关系)
|
||||
data.selectedroles && (await setFieldsValue({ selectedroles: data.selectedroles }));
|
||||
//编辑时隐藏密码/角色列表隐藏角色信息/我的部门时隐藏所属部门
|
||||
updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: !unref(isUpdate),
|
||||
},
|
||||
{
|
||||
field: 'confirmPassword',
|
||||
ifShow: !unref(isUpdate),
|
||||
},
|
||||
{
|
||||
field: 'selectedroles',
|
||||
show: !data.isRole,
|
||||
},
|
||||
{
|
||||
field: 'departIds',
|
||||
componentProps: { options: departOptions },
|
||||
},
|
||||
{
|
||||
field: 'selecteddeparts',
|
||||
show: !data?.departDisabled ?? false,
|
||||
},
|
||||
{
|
||||
field: 'selectedroles',
|
||||
show: !data?.departDisabled ?? false,
|
||||
},
|
||||
]);
|
||||
// 无论新增还是编辑,都可以设置表单值
|
||||
if (typeof data.record === 'object') {
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await clearValidate();
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
//update-begin-author:taoyan date:2022-5-24 for: VUEN-1117【issue】0523周开源问题
|
||||
setProps({ disabled: !showFooter.value });
|
||||
//update-end-author:taoyan date:2022-5-24 for: VUEN-1117【issue】0523周开源问题
|
||||
});
|
||||
//获取标题
|
||||
const getTitle = computed(() => (!unref(isUpdate) ? '新增用户' : '编辑用户'));
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
|
||||
//提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
values.userIdentity === 1 && (values.departIds = '');
|
||||
let isUpdateVal = unref(isUpdate);
|
||||
//提交表单
|
||||
await saveOrUpdateUser(values, isUpdateVal);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success', { isUpdateVal, values });
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :width="800" title="离职交接" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup name="user-quit-agent-modal">
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formQuitAgentSchema } from './user.data';
|
||||
import { getUserAgent, userQuitAgent } from './user.api';
|
||||
import dayjs from 'dayjs';
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
//表单配置
|
||||
const [registerForm, { resetFields, setFieldsValue, validate, clearValidate }] = useForm({
|
||||
schemas: formQuitAgentSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
setModalProps({ confirmLoading: false });
|
||||
//查询获取表单数据
|
||||
const res = await getUserAgent({ userName: data.userName });
|
||||
data = res.result ? res.result : data;
|
||||
let date = new Date();
|
||||
if (!data.startTime) {
|
||||
data.startTime = dayjs(date).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
if (!data.endTime) {
|
||||
data.endTime = getYear(date);
|
||||
}
|
||||
//表单赋值
|
||||
await setFieldsValue({ ...data });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await userQuitAgent(values);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取后30年
|
||||
*/
|
||||
function getYear(date) {
|
||||
//update-begin---author:wangshuai ---date:20221207 for:[QQYUN-3285]交接人设置 结束时间有问题------------
|
||||
//这是一个数值
|
||||
let y = date.getFullYear() + 30;
|
||||
let m = dayjs(date).format('MM');
|
||||
let d = dayjs(date).format('DD');
|
||||
let hour = dayjs(date).format('HH:mm:ss');
|
||||
console.log('年月日', y + '-' + m + '-' + d);
|
||||
return dayjs(y + '-' + m + '-' + d + ' ' + hour).format('YYYY-MM-DD HH:mm:ss');
|
||||
//update-end---author:wangshuai ---date:20221207 for:[QQYUN-3285]交接人设置 结束时间有问题--------------
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" title="离职人员信息" :showOkBtn="false" width="1000px" destroyOnClose>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleRevert">
|
||||
<Icon icon="ant-design:redo-outlined" />
|
||||
批量取消
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button
|
||||
>批量操作
|
||||
<Icon icon="ant-design:down-outlined" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="user-quit-modal">
|
||||
import { ref, toRaw, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||
import { recycleColumns } from './user.data';
|
||||
import { getQuitList, putCancelQuit, deleteRecycleBin } from './user.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
const [registerModal] = useModalInner(() => {
|
||||
checkedKeys.value = [];
|
||||
});
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
tableProps: {
|
||||
api: getQuitList,
|
||||
columns: recycleColumns,
|
||||
rowKey: 'id',
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
},
|
||||
});
|
||||
//注册table数据
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys, selectedRows }] = tableContext;
|
||||
|
||||
/**
|
||||
* 取消离职事件
|
||||
* @param record
|
||||
*/
|
||||
async function handleCancelQuit(record) {
|
||||
await putCancelQuit({ userIds: record.id, usernames: record.username }, reload);
|
||||
emit('success');
|
||||
}
|
||||
/**
|
||||
* 批量取消离职事件
|
||||
*/
|
||||
function batchHandleRevert() {
|
||||
Modal.confirm({
|
||||
title: '取消离职',
|
||||
content: '取消离职交接人也会清空',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
let rowValue = selectedRows.value;
|
||||
let rowData: any = [];
|
||||
for (const value of rowValue) {
|
||||
rowData.push(value.username);
|
||||
}
|
||||
handleCancelQuit({ id: toRaw(unref(selectedRowKeys)).join(','), username: rowData.join(',') });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//获取操作栏事件
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '取消离职',
|
||||
icon: 'ant-design:redo-outlined',
|
||||
popConfirm: {
|
||||
title: '是否取消离职,取消离职交接人也会清空',
|
||||
confirm: handleCancelQuit.bind(null, record),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.ant-popover-inner-content) {
|
||||
width: 185px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" title="用户回收站" :showOkBtn="false" width="1000px" destroyOnClose>
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-dropdown v-if="checkedKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined" />
|
||||
批量删除
|
||||
</a-menu-item>
|
||||
<a-menu-item key="1" @click="batchHandleRevert">
|
||||
<Icon icon="ant-design:redo-outlined" />
|
||||
批量还原
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button
|
||||
>批量操作
|
||||
<Icon icon="ant-design:down-outlined" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRaw, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||
import {recycleColumns, recycleSearchFormSchema} from './user.data';
|
||||
import { getRecycleBinList, putRecycleBin, deleteRecycleBin } from './user.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
// 声明Emits
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
const [registerModal] = useModalInner(() => {
|
||||
checkedKeys.value = [];
|
||||
});
|
||||
//注册table数据
|
||||
const [registerTable, { reload }] = useTable({
|
||||
api: getRecycleBinList,
|
||||
columns: recycleColumns,
|
||||
rowKey: 'id',
|
||||
striped: true,
|
||||
size: "small",
|
||||
useSearchForm: true,
|
||||
showTableSetting: false,
|
||||
clickToRowSelect: false,
|
||||
bordered: true,
|
||||
showIndexColumn: false,
|
||||
pagination: true,
|
||||
// tableSetting: { fullScreen: true },
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: recycleSearchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 150,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
// slots: { customRender: 'action' },
|
||||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
/**
|
||||
* 选择列配置
|
||||
*/
|
||||
const rowSelection = {
|
||||
type: 'checkbox',
|
||||
columnWidth: 50,
|
||||
selectedRowKeys: checkedKeys,
|
||||
onChange: onSelectChange,
|
||||
};
|
||||
/**
|
||||
* 选择事件
|
||||
*/
|
||||
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||
checkedKeys.value = selectedRowKeys;
|
||||
}
|
||||
/**
|
||||
* 还原事件
|
||||
*/
|
||||
async function handleRevert(record) {
|
||||
await putRecycleBin({ userIds: record.id }, reload);
|
||||
emit('success');
|
||||
}
|
||||
/**
|
||||
* 批量还原事件
|
||||
*/
|
||||
function batchHandleRevert() {
|
||||
handleRevert({ id: toRaw(unref(checkedKeys)).join(',') });
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteRecycleBin({ userIds: record.id }, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
function batchHandleDelete() {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '删除',
|
||||
content: '确定要永久删除吗?删除后将不可恢复!',
|
||||
onOk: () => handleDelete({ id: toRaw(unref(checkedKeys)).join(',') }),
|
||||
onCancel() {},
|
||||
});
|
||||
}
|
||||
//获取操作栏事件
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '取回',
|
||||
icon: 'ant-design:redo-outlined',
|
||||
popConfirm: {
|
||||
title: '是否确认还原',
|
||||
confirm: handleRevert.bind(null, record),
|
||||
},
|
||||
},
|
||||
/*{
|
||||
label: '彻底删除',
|
||||
icon: 'ant-design:scissor-outlined',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},*/
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div style="min-height: 400px">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div v-if="!formDisabled" style="width: 100%; text-align: center">
|
||||
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { getBpmFormSchema } from '../healthOperatorEx.data';
|
||||
import { queryByIdUrl, saveOrUpdate } from '../healthOperatorEx.api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'HealthOperatorExForm',
|
||||
components: {
|
||||
BasicForm,
|
||||
},
|
||||
props: {
|
||||
formData: propTypes.object.def({}),
|
||||
formBpm: propTypes.bool.def(true),
|
||||
},
|
||||
setup(props) {
|
||||
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: getBpmFormSchema(props.formData),
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
const formDisabled = computed(() => {
|
||||
if (props.formData.disabled === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
let formData = {};
|
||||
async function initFormData() {
|
||||
let params = { id: props.formData.dataId };
|
||||
const data = await defHttp.get({ url: queryByIdUrl, params });
|
||||
formData = { ...data };
|
||||
//设置表单的值
|
||||
await setFieldsValue(formData);
|
||||
//默认是禁用
|
||||
await setProps({ disabled: formDisabled.value });
|
||||
}
|
||||
|
||||
async function submitForm() {
|
||||
let data = getFieldsValue();
|
||||
let params = Object.assign({}, formData, data);
|
||||
await saveOrUpdate(params, true);
|
||||
}
|
||||
|
||||
initFormData();
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
formDisabled,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:title="title"
|
||||
width="70%"
|
||||
:showFooter="showFooter"
|
||||
destroyOnClose
|
||||
v-bind="$attrs"
|
||||
@ok="handleSubmit"
|
||||
@register="registerDrawer"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div style="height: 60vh">
|
||||
<BasicForm @register="registerForm" />
|
||||
</div>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { formSchema } from '../healthOperatorEx.data';
|
||||
import { saveOrUpdate } from '../healthOperatorEx.api';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref<boolean>(true);
|
||||
const showFooter = ref<boolean>(true);
|
||||
//设置标题
|
||||
const title = ref(String);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate, updateSchema }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
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;
|
||||
showFooter.value = data.showFooter;
|
||||
title.value = data.type;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: false,
|
||||
},
|
||||
]);
|
||||
await clearValidate();
|
||||
} else {
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,140 @@
|
||||
import { defHttp } from "/@/utils/http/axios";
|
||||
import { useMessage } from "/@/hooks/web/useMessage";
|
||||
import { dealPassword } from "/@/views/system/user/user.data";
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/sys/healthUserOperatorEx/operatorList',
|
||||
save = '/sys/healthUserOperatorEx/addOpertor',
|
||||
edit = '/sys/healthUserOperatorEx/editOpertor',
|
||||
deleteOne = '/sys/healthUserOperatorEx/delete',
|
||||
deleteBatch = '/sys/healthUserOperatorEx/deleteBatch',
|
||||
importExcel = '/sys/healthUserOperatorEx/importExcel',
|
||||
exportXls = '/sys/healthUserOperatorEx/exportXls',
|
||||
queryById = '/sys/healthUserOperatorEx/queryById',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 编辑页面回显
|
||||
*/
|
||||
export const queryByIdUrl = Api.queryById;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 请求编辑数据
|
||||
*/
|
||||
export const resEditData = async (params) => {
|
||||
return await defHttp.get({ url: Api.queryById, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let passwordObj = {};
|
||||
if (!isUpdate.value) {
|
||||
passwordObj = {
|
||||
password: dealPassword(params?.password),
|
||||
};
|
||||
}
|
||||
const data = {
|
||||
healthUserOperatorEx: {
|
||||
id: params?.id,
|
||||
userId: params?.userId,
|
||||
nativePlace: params?.nativePlace,
|
||||
nation: params?.nation,
|
||||
doctorTitle: params?.doctorTitle,
|
||||
goodAt: params?.goodAt,
|
||||
goodAtSymptom: params?.goodAtSymptom,
|
||||
goodAtSickness: params?.goodAtSickness,
|
||||
experience: params?.experience,
|
||||
cardNo: params?.cardNo,
|
||||
healthStatus: params?.healthStatus,
|
||||
college: params?.college,
|
||||
graduateDate: params?.graduateDate,
|
||||
education: params?.education,
|
||||
awardsPapers: params?.awardsPapers,
|
||||
resume: params?.resume,
|
||||
reason: params?.reason,
|
||||
onDutyTime: params?.onDutyTime,
|
||||
createTime: params?.createTime,
|
||||
phone: params?.phone,
|
||||
},
|
||||
sysUserModel: {
|
||||
username: params?.userName,
|
||||
...passwordObj,
|
||||
realname: params?.realname,
|
||||
birthday: params?.birthday,
|
||||
id: params?.id,
|
||||
sex: params?.sex,
|
||||
phone: params?.phone,
|
||||
avatar: params?.avatar,
|
||||
},
|
||||
},
|
||||
url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params: data });
|
||||
};
|
||||
@@ -0,0 +1,389 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
import { isShowIdCard } from '/@/utils/getEnv';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
dataIndex: 'userName',
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'realName',
|
||||
},
|
||||
// {
|
||||
// title: '籍贯',
|
||||
// align: 'center',
|
||||
// dataIndex: 'nativePlace',
|
||||
// },
|
||||
// {
|
||||
// title: '民族',
|
||||
// align: 'center',
|
||||
// dataIndex: 'nation',
|
||||
// customRender: ({ text }) => {
|
||||
// return render.renderDict(text, 'nation') || '';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '职称',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorTitle',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'z_doct_lev');
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '擅长',
|
||||
// align: 'center',
|
||||
// dataIndex: 'goodAt',
|
||||
// },
|
||||
// {
|
||||
// title: '执业经历',
|
||||
// align: 'center',
|
||||
// dataIndex: 'experience',
|
||||
// },
|
||||
// {
|
||||
// title: '擅长症状',
|
||||
// align: 'center',
|
||||
// dataIndex: 'goodAtSymptom',
|
||||
// },
|
||||
// {
|
||||
// title: '擅长疾病',
|
||||
// align: 'center',
|
||||
// dataIndex: 'goodAtSickness',
|
||||
// },
|
||||
{
|
||||
title: '注册时间',
|
||||
align: 'center',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
align: 'center',
|
||||
dataIndex: 'cardNo',
|
||||
width: 160,
|
||||
ifShow: isShowIdCard(),
|
||||
},
|
||||
{
|
||||
title: '健康状况',
|
||||
align: 'center',
|
||||
dataIndex: 'healthStatus',
|
||||
customRender: ({ text }) => (text && render.renderDict(text, 'jk_status')) || '',
|
||||
},
|
||||
{
|
||||
title: '毕业院校',
|
||||
align: 'center',
|
||||
dataIndex: 'college',
|
||||
},
|
||||
{
|
||||
title: '毕业时间',
|
||||
align: 'center',
|
||||
dataIndex: 'graduateDate',
|
||||
customRender: ({ text }) => {
|
||||
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '学历',
|
||||
align: 'center',
|
||||
dataIndex: 'education',
|
||||
customRender: ({ text }) => (text && render.renderDict(text, 'emp_education')) || '',
|
||||
},
|
||||
// {
|
||||
// title: '获奖及论文发表',
|
||||
// align: 'center',
|
||||
// dataIndex: 'awardsPapers',
|
||||
// },
|
||||
// {
|
||||
// title: '工作经历',
|
||||
// align: 'center',
|
||||
// dataIndex: 'resume',
|
||||
// },
|
||||
// {
|
||||
// title: '入选理由',
|
||||
// align: 'center',
|
||||
// dataIndex: 'reason',
|
||||
// },
|
||||
{
|
||||
title: '值班时间',
|
||||
align: 'center',
|
||||
dataIndex: 'onDutyTime',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'realName',
|
||||
label: '姓名',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'userId',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'userName',
|
||||
component: 'Input',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
autocomplete: 'off',
|
||||
onInput: (event) => {
|
||||
const target = event.target;
|
||||
formModel.username = target.value.replace(/[^\w]/g, '');
|
||||
},
|
||||
};
|
||||
},
|
||||
required: true,
|
||||
rules: [{ required: true, message: '请输入用户账号' }],
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
show: ({ values }) => {
|
||||
return !values.id;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
label: '性别',
|
||||
componentProps: {
|
||||
dictCode: 'sex2',
|
||||
type: 'radio',
|
||||
},
|
||||
rules: [{ required: true, message: '请选择性别' }],
|
||||
},
|
||||
{
|
||||
label: '头像',
|
||||
field: 'avatar',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [{ required: true, pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' }],
|
||||
},
|
||||
// {
|
||||
// label: '人员类型',
|
||||
// field: 'userType',
|
||||
// component: 'JDictSelectTag',
|
||||
// componentProps: {
|
||||
// dictCode: 'p_type',
|
||||
// },
|
||||
// },
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'cardNo',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{ required: true, pattern: /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|[xX])$/, message: '身份证号码格式有误' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
field: 'nativePlace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'nation',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'nation',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '出生日期',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorTitle',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_lev',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '擅长',
|
||||
field: 'goodAt',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '执业经历',
|
||||
field: 'experience',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '擅长症状',
|
||||
field: 'goodAtSymptom',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '擅长疾病',
|
||||
field: 'goodAtSickness',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '注册时间',
|
||||
field: 'createTime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '健康状况',
|
||||
field: 'healthStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'jk_status',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '毕业院校',
|
||||
field: 'college',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '毕业时间',
|
||||
field: 'graduateDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
field: 'education',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_education',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '获奖及论文发表',
|
||||
field: 'awardsPapers',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '工作经历',
|
||||
field: 'resume',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '入选理由',
|
||||
field: 'reason',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
field: 'onDutyTime',
|
||||
label: '值班时间',
|
||||
component: 'CheckboxGroup',
|
||||
ifShow: false,
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '周一上午', value: '周一上午' },
|
||||
{ label: '周一下午', value: '周一下午' },
|
||||
{ label: '周二上午', value: '周二上午' },
|
||||
{ label: '周二下午', value: '周二下午' },
|
||||
{ label: '周三上午', value: '周三上午' },
|
||||
{ label: '周三下午', value: '周三下午' },
|
||||
{ label: '周四上午', value: '周四上午' },
|
||||
{ label: '周四下午', value: '周四下午' },
|
||||
{ label: '周五上午', value: '周五上午' },
|
||||
{ label: '周五下午', value: '周五下午' },
|
||||
{ label: '周六上午', value: '周六上午' },
|
||||
{ label: '周六下午', value: '周六下午' },
|
||||
{ label: '周日上午', value: '周日上午' },
|
||||
{ label: '周日下午', value: '周日下午' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined" v-auth="'system:health_operator_ex:add'">
|
||||
新增
|
||||
</a-button>
|
||||
<!-- <a-button-->
|
||||
<!-- type="primary"-->
|
||||
<!-- preIcon="ant-design:export-outlined"-->
|
||||
<!-- v-auth="'system:health_user_operator_ex:exportXls'"-->
|
||||
<!-- @click="onExportXls"-->
|
||||
<!-- >-->
|
||||
<!-- 导出-->
|
||||
<!-- </a-button>-->
|
||||
<!-- <j-upload-button-->
|
||||
<!-- type="primary"-->
|
||||
<!-- preIcon="ant-design:import-outlined"-->
|
||||
<!-- v-auth="'system:health_user_operator_ex:importExcel'"-->
|
||||
<!-- @click="onImportXls"-->
|
||||
<!-- >导入-->
|
||||
<!-- </j-upload-button>-->
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="batchHandleDelete"
|
||||
v-auth="'system:health_operator_ex:deleteBatch'"
|
||||
preIcon="ant-design:delete-outlined"
|
||||
>
|
||||
批量删除
|
||||
</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{ text }">
|
||||
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)"
|
||||
>下载
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<healthOperatorExModal @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-healthOperatorEx" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import healthOperatorExModal from './components/healthOperatorExModal.vue';
|
||||
import { columns, searchFormSchema } from './healthOperatorEx.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list, resEditData } from './healthOperatorEx.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { lockUser } from '/@/views/system/user/hospitalDoctor/HospitalDoctor.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
import RestPass from '../restPass/RestPass.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
//注册model
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'health_user_operator_ex',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '操作人员',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
type: '新增',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.sysUserModel, ...res.healthUserOperatorEx, phone: res.sysUserModel.phone };
|
||||
data.userName = res.sysUserModel.username;
|
||||
openDrawer(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
type: '编辑',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.sysUserModel, ...res.healthUserOperatorEx };
|
||||
data.userName = res.sysUserModel.username;
|
||||
openDrawer(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
type: '详情',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return message.warning('未选中任何数据');
|
||||
}
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'system:health_operator_ex:edit',
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
// 重置密码
|
||||
function restPass(record) {
|
||||
restPaddModel(true, {
|
||||
record: record.userId,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
// 1 锁定用户 2 激活用户
|
||||
async function handleUserOpt(record, type) {
|
||||
const params = {
|
||||
userId: record.userId,
|
||||
status: type,
|
||||
};
|
||||
await lockUser(params, type, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'system:health_operator_ex:delete',
|
||||
},
|
||||
{
|
||||
label: '重置密码',
|
||||
onClick: restPass.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '锁定用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 2),
|
||||
},
|
||||
{
|
||||
label: '激活用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 1),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,120 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/sys/healthUserDoctorEx/list',
|
||||
save = '/sys/healthUserDoctorEx/add',
|
||||
edit = '/sys/healthUserDoctorEx/edit',
|
||||
deleteOne = '/sys/healthUserDoctorEx/delete',
|
||||
deleteBatch = '/sys/healthUserDoctorEx/deleteBatch',
|
||||
importExcel = '/sys/healthUserDoctorEx/importExcel',
|
||||
exportXls = '/sys/healthUserDoctorEx/exportXls',
|
||||
queryById = '/sys/healthUserDoctorEx/queryById',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 编辑页面回显
|
||||
*/
|
||||
export const queryByIdUrl = Api.queryById;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 请求编辑数据
|
||||
*/
|
||||
export const resEditData = async (params, handleSuccess) => {
|
||||
return await defHttp.get({ url: Api.queryById, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const data = {
|
||||
healthUserDoctorEx: {
|
||||
doctorName: params.realname,
|
||||
doctorTitle: params.doctorTitle,
|
||||
doctorJob: params.doctorJob,
|
||||
hospitalId: params.hospitalId,
|
||||
hospitalName: params.hospitalName,
|
||||
officeId: params.officeName,
|
||||
doctorStatus: params.doctorStatus,
|
||||
type: params.type,
|
||||
isAccept: params.isAccept,
|
||||
goodAt: params.goodAt,
|
||||
goodAtSymptom: params.goodAtSymptom,
|
||||
goodAtSickness: params.goodAtSickness,
|
||||
experience: params.experience,
|
||||
nationality: params.nationality,
|
||||
nativePlace: params.nativePlace,
|
||||
address: params.address,
|
||||
joinWork: params.joinWork,
|
||||
healthStatus: params.healthStatus,
|
||||
eq: params.eq,
|
||||
school: params.school,
|
||||
outTime: params.outTime,
|
||||
contactAddress: params.contactAddress,
|
||||
memo: params.memo,
|
||||
onDutyTime: params.onDutyTime,
|
||||
award: params.award,
|
||||
},
|
||||
sysUserModel: {
|
||||
avatar: params.avatar,
|
||||
username: params.username,
|
||||
realname: params.realname,
|
||||
idCard: params.idCard,
|
||||
email: params.email,
|
||||
phone: params.phone,
|
||||
sex: params.sex,
|
||||
password: params.password,
|
||||
},
|
||||
},
|
||||
url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params: data });
|
||||
};
|
||||
@@ -0,0 +1,396 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { getHospitalsList, getOfficeList } from '../user.api';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '专家名称',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorName',
|
||||
},
|
||||
{
|
||||
title: '所属医院名称',
|
||||
align: 'center',
|
||||
dataIndex: 'hospitalName',
|
||||
},
|
||||
{
|
||||
title: '所属科室名称',
|
||||
align: 'center',
|
||||
dataIndex: 'officeName',
|
||||
},
|
||||
{
|
||||
title: '职务',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorTitle',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'z_doct_lev');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '职称',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorJob',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'z_doct_job');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '执业经历',
|
||||
align: 'center',
|
||||
dataIndex: 'experience',
|
||||
},
|
||||
{
|
||||
title: '医生状态',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorStatus',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'doc_status');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '是否接受咨询',
|
||||
align: 'center',
|
||||
dataIndex: 'isAccept',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'doc_accept_flag');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '专家类型',
|
||||
align: 'center',
|
||||
dataIndex: 'type',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'z_doct_typ');
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '状态',
|
||||
// align:"center",
|
||||
// dataIndex: 'status',
|
||||
// customRender: ({ text }) => {
|
||||
// // 1-正常,2-冻结
|
||||
// return text == '1' ? '正常' : '冻结' ;
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: '值班时间',
|
||||
// align:"center",
|
||||
// dataIndex: 'onDutyTime'
|
||||
// },
|
||||
];
|
||||
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'doctorJob',
|
||||
label: '职称',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: () => {
|
||||
return {
|
||||
dictCode: 'z_doct_job',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'doctorTitle',
|
||||
label: '职务',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: () => {
|
||||
return {
|
||||
dictCode: 'z_doct_lev',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'goodAtSymptom',
|
||||
label: '擅长症状',
|
||||
component: 'Input',
|
||||
colProps: { span: 8 },
|
||||
},
|
||||
];
|
||||
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
// 主键隐藏字段
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '职务',
|
||||
field: 'doctorTitle',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_lev',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorJob',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_job',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '医院名称',
|
||||
field: 'hospitalName',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getHospitalsList,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: false,
|
||||
// onChange: (e) => {
|
||||
// console.log('selected:', e);
|
||||
// },
|
||||
// // 请求后回调
|
||||
// onOptionsChange: (options) => {
|
||||
// console.log('get options', options.length, options);
|
||||
// },
|
||||
onOptionsChange: (options) => {
|
||||
// console.log("options",options)
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'hospitalId', // 医院名称选中的医院ID
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '科室名称',
|
||||
field: 'officeName',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getOfficeList,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: false,
|
||||
onChange: (e) => {
|
||||
// console.log('selected:', e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '医生状态',
|
||||
field: 'doctorStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'doc_status',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '专家类型',
|
||||
field: 'type',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_typ',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '是否接受咨询',
|
||||
field: 'isAccept',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'doc_accept_flag',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'avatar',
|
||||
label: '头像',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '真实名字',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '擅长',
|
||||
field: 'goodAt',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '擅长症状',
|
||||
field: 'goodAtSymptom',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '擅长疾病',
|
||||
field: 'goodAtSickness',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '职业经历',
|
||||
field: 'experience',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'nationality',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
field: 'nativePlace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '住址',
|
||||
field: 'address',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'joinWork',
|
||||
label: '参加工作时间',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'onDutyTime',
|
||||
label: '值班时间',
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '周一上午', value: '周一上午' },
|
||||
{ label: '周一下午', value: '周一下午' },
|
||||
{ label: '周二上午', value: '周二上午' },
|
||||
{ label: '周二下午', value: '周二下午' },
|
||||
{ label: '周三上午', value: '周三上午' },
|
||||
{ label: '周三下午', value: '周三下午' },
|
||||
{ label: '周四上午', value: '周四上午' },
|
||||
{ label: '周四下午', value: '周四下午' },
|
||||
{ label: '周五上午', value: '周五上午' },
|
||||
{ label: '周五下午', value: '周五下午' },
|
||||
{ label: '周六上午', value: '周六上午' },
|
||||
{ label: '周六下午', value: '周六下午' },
|
||||
{ label: '周日上午', value: '周日上午' },
|
||||
{ label: '周日下午', value: '周日下午' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '身份证号码',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '健康状况',
|
||||
field: 'healthStatus',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
field: 'eq',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '毕业学校',
|
||||
field: 'school',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'outTime',
|
||||
label: '毕业时间',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '获奖或论文',
|
||||
field: 'award',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱',
|
||||
component: 'Input',
|
||||
rules: [{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }],
|
||||
componentProps: {
|
||||
placeholder: '请输入邮箱',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [{ required: false, pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' }],
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
label: '性别',
|
||||
componentProps: {
|
||||
dictCode: 'sex',
|
||||
type: 'radioButton',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '联系地址',
|
||||
field: 'contactAddress',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
field: 'memo',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable :rowSelection="rowSelection" @register="registerTable">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="'system:health_user_doctor_ex:add'" preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd">
|
||||
新增</a-button
|
||||
>
|
||||
<a-button v-auth="'system:health_user_doctor_ex:exportXls'" preIcon="ant-design:export-outlined" type="primary" @click="onExportXls">
|
||||
导出</a-button
|
||||
>
|
||||
<j-upload-button
|
||||
v-auth="'system:health_user_doctor_ex:importExcel'"
|
||||
preIcon="ant-design:import-outlined"
|
||||
type="primary"
|
||||
@click="onImportXls"
|
||||
>导入</j-upload-button
|
||||
>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined" />
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button
|
||||
>批量操作
|
||||
<Icon icon="mdi:chevron-down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<!--省市区字段回显插槽-->
|
||||
<template #pcaSlot="{ text }">
|
||||
{{ getAreaTextByCode(text) }}
|
||||
</template>
|
||||
<template #fileSlot="{ text }">
|
||||
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
|
||||
<a-button v-else :ghost="true" preIcon="ant-design:download-outlined" size="small" type="primary" @click="downloadFile(text)"
|
||||
>下载</a-button
|
||||
>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<HealthUserDoctorExModal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-healthUserDoctorEx" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import HealthUserDoctorExModal from './components/HealthUserDoctorExModal.vue';
|
||||
import { columns, searchFormSchema } from './HealthUserDoctorEx.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list, resEditData } from './HealthUserDoctorEx.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: 'health_user_doctor_ex',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: 'health_user_doctor_ex',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.userInfo, ...res.healthUserDoctorEx };
|
||||
openModal(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.userInfo, ...res.healthUserDoctorEx };
|
||||
openModal(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'system:health_user_doctor_ex:edit',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
auth: 'system:health_user_doctor_ex:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div style="min-height: 400px">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div v-if="!formDisabled" style="width: 100%; text-align: center">
|
||||
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { getBpmFormSchema } from '../HealthUserDoctorEx.data';
|
||||
import { queryByIdUrl, saveOrUpdate } from '../HealthUserDoctorEx.api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'HealthUserDoctorExForm',
|
||||
components: {
|
||||
BasicForm,
|
||||
},
|
||||
props: {
|
||||
formData: propTypes.object.def({}),
|
||||
formBpm: propTypes.bool.def(true),
|
||||
},
|
||||
setup(props) {
|
||||
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: getBpmFormSchema(props.formData),
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
const formDisabled = computed(() => {
|
||||
if (props.formData.disabled === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
let formData = {};
|
||||
async function initFormData() {
|
||||
let params = { id: props.formData.dataId };
|
||||
const data = await defHttp.get({ url: queryByIdUrl, params });
|
||||
formData = { ...data };
|
||||
//设置表单的值
|
||||
await setFieldsValue(formData);
|
||||
//默认是禁用
|
||||
await setProps({ disabled: formDisabled.value });
|
||||
}
|
||||
|
||||
async function submitForm() {
|
||||
let data = getFieldsValue();
|
||||
let params = Object.assign({}, formData, data);
|
||||
await saveOrUpdate(params, true);
|
||||
}
|
||||
|
||||
initFormData();
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
formDisabled,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<BasicModal :title="title" :width="800" destroyOnClose v-bind="$attrs" @ok="handleSubmit" @register="registerModal">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { formSchema } from '../HealthUserDoctorEx.data';
|
||||
import { saveOrUpdate } from '../HealthUserDoctorEx.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
formSchema[3].componentProps.onOptionsChange = (options) => {
|
||||
onSelectHospital(options);
|
||||
};
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
// 选择医院名称
|
||||
async function onSelectHospital(options) {
|
||||
await setFieldsValue({
|
||||
hospitalName: options[0]['label'],
|
||||
hospitalId: options[0]['value'],
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,136 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { dealPassword } from '/@/views/system/user/user.data';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/sys/healthUserOperatorEx/list',
|
||||
save = '/sys/healthUserOperatorEx/add',
|
||||
edit = '/sys/healthUserOperatorEx/edit',
|
||||
deleteOne = '/sys/healthUserOperatorEx/delete',
|
||||
deleteBatch = '/sys/healthUserOperatorEx/deleteBatch',
|
||||
importExcel = '/sys/healthUserOperatorEx/importExcel',
|
||||
exportXls = '/sys/healthUserOperatorEx/exportXls',
|
||||
getEdit = '/sys/healthUserOperatorEx/queryById',
|
||||
queryById = '/system/healthUserOperatorEx/queryById',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 编辑页面回显
|
||||
*/
|
||||
export const queryByIdUrl = Api.queryById;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 请求编辑数据
|
||||
*/
|
||||
export const resEditData = async (params) => {
|
||||
return await defHttp.get({ url: Api.getEdit, params }, { joinParamsToUrl: true });
|
||||
};
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let passwordObj = {};
|
||||
if (!isUpdate.value) {
|
||||
passwordObj = {
|
||||
password: dealPassword(params?.password),
|
||||
};
|
||||
}
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
const data = {
|
||||
healthUserOperatorEx: {
|
||||
id: params?.id,
|
||||
userId: params?.userId,
|
||||
userType: params?.userType,
|
||||
nativePlace: params?.nativePlace,
|
||||
nation: params?.nation,
|
||||
doctorTitle: params?.doctorTitle,
|
||||
goodAt: params?.goodAt,
|
||||
experience: params?.experience,
|
||||
goodAtSymptom: params?.goodAtSymptom,
|
||||
goodAtSickness: params?.goodAtSickness,
|
||||
createTime: params?.createTime,
|
||||
cardNo: params?.cardNo,
|
||||
healthStatus: params?.healthStatus,
|
||||
college: params?.college,
|
||||
graduateDate: params?.graduateDate,
|
||||
education: params?.education,
|
||||
awardsPapers: params?.awardsPapers,
|
||||
resume: params?.resume,
|
||||
reason: params?.reason,
|
||||
onDutyTime: params?.onDutyTime,
|
||||
},
|
||||
sysUserModel: {
|
||||
username: params?.username,
|
||||
...passwordObj,
|
||||
realname: params?.realname,
|
||||
birthday: params?.birthday,
|
||||
sex: params?.sex,
|
||||
phone: params?.phone,
|
||||
id: params?.id,
|
||||
avatar: params?.avatar,
|
||||
},
|
||||
};
|
||||
return defHttp.post({ url: url, data });
|
||||
};
|
||||
@@ -0,0 +1,420 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
import { isShowIdCard } from '/@/utils/getEnv';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
dataIndex: 'userName',
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'realName',
|
||||
},
|
||||
{
|
||||
title: '籍贯',
|
||||
align: 'center',
|
||||
dataIndex: 'nativePlace',
|
||||
},
|
||||
{
|
||||
title: '民族',
|
||||
align: 'center',
|
||||
dataIndex: 'nation',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'nation') || '';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '出生日期',
|
||||
align: 'center',
|
||||
dataIndex: 'birthday',
|
||||
customRender: ({ text }) => {
|
||||
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '职称',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorTitle',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'z_doct_lev');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '擅长',
|
||||
align: 'center',
|
||||
dataIndex: 'goodAt',
|
||||
},
|
||||
{
|
||||
title: '执业经历',
|
||||
align: 'center',
|
||||
dataIndex: 'experience',
|
||||
},
|
||||
{
|
||||
title: '擅长症状',
|
||||
align: 'center',
|
||||
dataIndex: 'goodAtSymptom',
|
||||
},
|
||||
{
|
||||
title: '擅长疾病',
|
||||
align: 'center',
|
||||
dataIndex: 'goodAtSickness',
|
||||
},
|
||||
{
|
||||
title: '注册时间',
|
||||
align: 'center',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
align: 'center',
|
||||
dataIndex: 'cardNo',
|
||||
width: 160,
|
||||
ifShow: isShowIdCard(),
|
||||
},
|
||||
{
|
||||
title: '健康状况',
|
||||
align: 'center',
|
||||
dataIndex: 'healthStatus',
|
||||
customRender: ({ text }) => (text && render.renderDict(text, 'jk_status')) || '',
|
||||
},
|
||||
{
|
||||
title: '毕业院校',
|
||||
align: 'center',
|
||||
dataIndex: 'college',
|
||||
},
|
||||
{
|
||||
title: '毕业时间',
|
||||
align: 'center',
|
||||
dataIndex: 'graduateDate',
|
||||
customRender: ({ text }) => {
|
||||
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '学历',
|
||||
align: 'center',
|
||||
dataIndex: 'education',
|
||||
customRender: ({ text }) => (text && render.renderDict(text, 'emp_education')) || '',
|
||||
},
|
||||
{
|
||||
title: '获奖及论文发表',
|
||||
align: 'center',
|
||||
dataIndex: 'awardsPapers',
|
||||
},
|
||||
{
|
||||
title: '工作简历',
|
||||
align: 'center',
|
||||
dataIndex: 'resume',
|
||||
},
|
||||
{
|
||||
title: '入选理由',
|
||||
align: 'center',
|
||||
dataIndex: 'reason',
|
||||
},
|
||||
// {
|
||||
// title: '值班时间',
|
||||
// align: 'center',
|
||||
// dataIndex: 'onDutyTime',
|
||||
// },
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'realName',
|
||||
label: '姓名',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '人员类型',
|
||||
field: 'userType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'p_type',
|
||||
},
|
||||
// required: true,
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
show: ({ values }) => {
|
||||
return !values.id;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'sex2',
|
||||
type: 'radio',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '头像',
|
||||
field: 'avatar',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
maxCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [{ required: true, pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' }],
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'cardNo',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{ required: true, pattern: /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|[xX])$/, message: '身份证号码格式有误' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
field: 'nativePlace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'nation',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: () => {
|
||||
return {
|
||||
dictCode: 'nation',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '出生日期',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorTitle',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_lev',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '毕业时间',
|
||||
field: 'graduateDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
field: 'education',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'emp_education',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: '值班时间',
|
||||
// field: 'onDutyTime',
|
||||
// component: 'CheckboxGroup',
|
||||
// componentProps: {
|
||||
// options: [
|
||||
// {
|
||||
// label: '周一上午',
|
||||
// value: '周一上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周一下午',
|
||||
// value: '周一下午',
|
||||
// },
|
||||
// {
|
||||
// label: '周二上午',
|
||||
// value: '周二上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周二下午',
|
||||
// value: '周二下午',
|
||||
// },
|
||||
// {
|
||||
// label: '周三上午',
|
||||
// value: '周三上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周三下午',
|
||||
// value: '周三下午',
|
||||
// },
|
||||
// {
|
||||
// label: '周四上午',
|
||||
// value: '周四上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周四下午',
|
||||
// value: '周四下午',
|
||||
// },
|
||||
// {
|
||||
// label: '周五上午',
|
||||
// value: '周五上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周五下午',
|
||||
// value: '周五下午',
|
||||
// },
|
||||
// {
|
||||
// label: '周六上午',
|
||||
// value: '周六上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周六下午',
|
||||
// value: '周六下午',
|
||||
// },
|
||||
// {
|
||||
// label: '周日上午',
|
||||
// value: '周日上午',
|
||||
// },
|
||||
// {
|
||||
// label: '周日下午',
|
||||
// value: '周日下午',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
label: '擅长',
|
||||
field: 'goodAt',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '执业经历',
|
||||
field: 'experience',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '擅长症状',
|
||||
field: 'goodAtSymptom',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '擅长疾病',
|
||||
field: 'goodAtSickness',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '注册时间',
|
||||
field: 'createTime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '健康状况',
|
||||
field: 'healthStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'jk_status',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '毕业院校',
|
||||
field: 'college',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '获奖及论文发表',
|
||||
field: 'awardsPapers',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '工作简历',
|
||||
field: 'resume',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '入选理由',
|
||||
field: 'reason',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined" v-auth="'system:health_user_operator_ex:add'">
|
||||
新增
|
||||
</a-button>
|
||||
<!-- <a-button-->
|
||||
<!-- type="primary"-->
|
||||
<!-- preIcon="ant-design:export-outlined"-->
|
||||
<!-- v-auth="'system:health_user_operator_ex:exportXls'"-->
|
||||
<!-- @click="onExportXls"-->
|
||||
<!-- >-->
|
||||
<!-- 导出-->
|
||||
<!-- </a-button>-->
|
||||
<!-- <j-upload-button-->
|
||||
<!-- type="primary"-->
|
||||
<!-- preIcon="ant-design:import-outlined"-->
|
||||
<!-- v-auth="'system:health_user_operator_ex:importExcel'"-->
|
||||
<!-- @click="onImportXls"-->
|
||||
<!-- >导入-->
|
||||
<!-- </j-upload-button>-->
|
||||
<a-button
|
||||
type="primary"
|
||||
preIcon="ant-design:delete-outlined"
|
||||
v-auth="'system:health_user_operator_ex:deleteBatch'"
|
||||
@click="batchHandleDelete"
|
||||
>批量删除</a-button
|
||||
>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{ text }">
|
||||
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)"
|
||||
>下载
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<HealthUserOperatorExModal :userId="userId" @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-healthUserOperatorEx" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import HealthUserOperatorExModal from './components/HealthUserOperatorExModal.vue';
|
||||
import RestPass from '../restPass/RestPass.vue';
|
||||
import { columns, searchFormSchema } from './HealthUserOperatorEx.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list, resEditData } from './HealthUserOperatorEx.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { lockUser } from '/@/views/system/user/hospitalDoctor/HospitalDoctor.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const userId = ref<String>('');
|
||||
//注册model
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: 'health_user_operator_ex',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '专业人员',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
type: '新增',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
userId.value = record.userId;
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.sysUserModel, ...res.healthUserOperatorEx };
|
||||
data.phone = res.sysUserModel.phone;
|
||||
openDrawer(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
type: '编辑',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.sysUserModel, ...res.healthUserOperatorEx };
|
||||
data.phone = res.sysUserModel.phone;
|
||||
openDrawer(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
type: '详情',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return message.warning('未选中任何数据');
|
||||
}
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'system:health_user_operator_ex:edit',
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
// 重置密码
|
||||
function restPass(record) {
|
||||
restPaddModel(true, {
|
||||
record: record.userId,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
// 1 锁定用户 2 激活用户
|
||||
async function handleUserOpt(record, type) {
|
||||
const params = {
|
||||
userId: record.userId,
|
||||
status: type,
|
||||
};
|
||||
await lockUser(params, type, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'system:health_user_operator_ex:delete',
|
||||
},
|
||||
{
|
||||
label: '重置密码',
|
||||
onClick: restPass.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '锁定用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 2),
|
||||
},
|
||||
{
|
||||
label: '激活用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 1),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div style="min-height: 400px">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div v-if="!formDisabled" style="width: 100%; text-align: center">
|
||||
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { getBpmFormSchema } from '../HealthUserOperatorEx.data';
|
||||
import { queryByIdUrl, saveOrUpdate } from '../HealthUserOperatorEx.api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'HealthUserOperatorExForm',
|
||||
components: {
|
||||
BasicForm,
|
||||
},
|
||||
props: {
|
||||
formData: propTypes.object.def({}),
|
||||
formBpm: propTypes.bool.def(true),
|
||||
},
|
||||
setup(props) {
|
||||
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: getBpmFormSchema(props.formData),
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
const formDisabled = computed(() => {
|
||||
if (props.formData.disabled === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
let formData = {};
|
||||
async function initFormData() {
|
||||
let params = { id: props.formData.dataId };
|
||||
const data = await defHttp.get({ url: queryByIdUrl, params });
|
||||
formData = { ...data };
|
||||
//设置表单的值
|
||||
await setFieldsValue(formData);
|
||||
//默认是禁用
|
||||
await setProps({ disabled: formDisabled.value });
|
||||
}
|
||||
|
||||
async function submitForm() {
|
||||
let data = getFieldsValue();
|
||||
let params = Object.assign({}, formData, data);
|
||||
await saveOrUpdate(params, true);
|
||||
}
|
||||
|
||||
initFormData();
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
formDisabled,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:maskClosable="false"
|
||||
:title="title"
|
||||
:width="adaptiveWidth"
|
||||
:showFooter="showFooter"
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
destroyOnClose
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineProps, ref, unref } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { formSchema } from '../HealthUserOperatorEx.data';
|
||||
import { saveOrUpdate } from '../HealthUserOperatorEx.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref<boolean>(true);
|
||||
const showFooter = ref<boolean>(true);
|
||||
//设置标题
|
||||
const title = ref(String);
|
||||
const props = defineProps({
|
||||
userId: String,
|
||||
});
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate, updateSchema }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
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;
|
||||
showFooter.value = data.showFooter;
|
||||
title.value = data.type;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: false,
|
||||
},
|
||||
]);
|
||||
await clearValidate();
|
||||
} else {
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
values.userId = props.userId;
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,132 @@
|
||||
import { defHttp } from "/@/utils/http/axios";
|
||||
import { useMessage } from "/@/hooks/web/useMessage";
|
||||
import { dealPassword } from "/@/views/system/user/user.data";
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/sys/healthUserStationEx/list',
|
||||
save = '/sys/healthUserStationEx/add',
|
||||
edit = '/sys/healthUserStationEx/edit',
|
||||
deleteOne = '/sys/healthUserStationEx/delete',
|
||||
deleteBatch = '/sys/healthUserStationEx/deleteBatch',
|
||||
importExcel = '/sys/healthUserStationEx/importExcel',
|
||||
exportXls = '/sys/healthUserStationEx/exportXls',
|
||||
getEdit = '/sys/healthUserStationEx/queryById',
|
||||
getHospitals = '/rest/consult/r/h/list',
|
||||
queryById = '/system/healthUserStationEx/queryById',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 编辑页面回显
|
||||
*/
|
||||
export const queryByIdUrl = Api.queryById;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 请求编辑数据
|
||||
*/
|
||||
export const resEditData = async (params) => {
|
||||
return await defHttp.get({ url: Api.getEdit, params }, { joinParamsToUrl: true });
|
||||
};
|
||||
|
||||
/**
|
||||
* 医院列表
|
||||
*/
|
||||
export const hospitalLists = async (params) => {
|
||||
return await defHttp.get({ url: Api.getHospitals, params });
|
||||
};
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let passwordObj = {};
|
||||
if (!isUpdate.value) {
|
||||
passwordObj = {
|
||||
password: dealPassword(params?.password),
|
||||
};
|
||||
}
|
||||
const url = isUpdate ? Api.edit : Api.save,
|
||||
data = {
|
||||
healthUserStationEx: {
|
||||
id: params?.id,
|
||||
hospitalId: params?.hospitalId,
|
||||
hospitalName: params?.hospitalName,
|
||||
memo: params?.memo,
|
||||
},
|
||||
sysUserModel: {
|
||||
realname: params?.realname,
|
||||
username: params?.username,
|
||||
sex: params?.sex,
|
||||
avatar: params?.avatar,
|
||||
idCard: params?.idCard,
|
||||
birthday: params?.birthday,
|
||||
email: params?.email,
|
||||
phone: params?.phone,
|
||||
workNo: params?.workNo,
|
||||
...passwordObj,
|
||||
post: params?.post,
|
||||
orgCode: params?.orgCode,
|
||||
id: params?.id,
|
||||
},
|
||||
};
|
||||
return defHttp.post({ url: url, data });
|
||||
};
|
||||
@@ -0,0 +1,232 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getNewHospitalApi, getPhysicalHospitalsList } from '../user.api';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
dataIndex: 'userName',
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'realName',
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
align: 'center',
|
||||
dataIndex: 'hospitalName',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'realName',
|
||||
label: '姓名',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'hospitalId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getNewHospitalApi,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: false,
|
||||
placeholder: '请选择驻场医院',
|
||||
},
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '医院',
|
||||
field: 'hospitalName',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
getPopupContainer: () => document.body,
|
||||
api: getNewHospitalApi,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: false,
|
||||
// onChange: (e) => {
|
||||
// console.log('selected:', e);
|
||||
// },
|
||||
// // 请求后回调
|
||||
// onOptionsChange: (options) => {
|
||||
// console.log('get options', options.length, options);
|
||||
// },
|
||||
onOptionsChange: (options) => {
|
||||
// console.log("options",options)
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
componentProps: {
|
||||
autocomplete: 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
required: true,
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
show: ({ values }) => {
|
||||
return !values.id;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'hospitalId', // 医院名称选中的医院ID
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
label: '性别',
|
||||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
type: 'radio',
|
||||
dictCode: 'sex2',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'avatar',
|
||||
label: '头像',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
text: '头像',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
pattern: /^1[3456789][0-9]{9}$/,
|
||||
message: '${label}格式有误',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
|
||||
message: '${label}格式有误',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '出生日期',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
placeholder: '请选择出生日期',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
field: 'email',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{
|
||||
pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
|
||||
message: '${label}格式有误',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '员工编号', // 原来为工号
|
||||
field: 'workNo',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '人员类型',
|
||||
field: 'personType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'p_type',
|
||||
},
|
||||
show: false,
|
||||
},
|
||||
// {
|
||||
// label: '职务',
|
||||
// field: 'post',
|
||||
// component: 'Input',
|
||||
// },
|
||||
{
|
||||
label: '部门编码',
|
||||
field: 'orgCode',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<template #customSlot="{ model, field }">
|
||||
<a-input v-model:value="model[field]" />
|
||||
</template>
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="'system:health_user_station_ex:add'" type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">
|
||||
新增
|
||||
</a-button>
|
||||
<!-- <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出 </a-button>-->
|
||||
<!-- <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入 </j-upload-button>-->
|
||||
<a-button
|
||||
type="primary"
|
||||
v-auth="'system:health_user_station_ex:deleteBatch'"
|
||||
preIcon="ant-design:delete-outlined"
|
||||
@click="batchHandleDelete"
|
||||
>批量删除</a-button
|
||||
>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{ text }">
|
||||
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)"
|
||||
>下载
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<HealthUserStationExModal @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-healthUserStationEx" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import HealthUserStationExModal from './components/HealthUserStationExModal.vue';
|
||||
import RestPass from '../restPass/RestPass.vue';
|
||||
import { columns, searchFormSchema } from './HealthUserStationEx.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list, resEditData } from './HealthUserStationEx.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { lockUser } from '/@/views/system/user/hospitalDoctor/HospitalDoctor.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//注册model
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: 'health_user_station_ex',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '驻场人员',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
// 重置密码
|
||||
function restPass(record) {
|
||||
restPaddModel(true, {
|
||||
record: record.id,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
type: '新增',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.sysUserModel, ...res.healthUserStationEx };
|
||||
openDrawer(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
type: '编辑',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
let data = { ...res.sysUserModel, ...res.healthUserStationEx };
|
||||
openDrawer(true, {
|
||||
record: data,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
type: '详情',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return message.warning('未选中任何数据');
|
||||
}
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'system:health_user_station_ex:edit',
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'system:health_user_station_ex:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
// 1 锁定用户 2 激活用户
|
||||
async function handleUserOpt(record, type) {
|
||||
const params = {
|
||||
userId: record.id,
|
||||
status: type,
|
||||
};
|
||||
await lockUser(params, type, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '重置密码',
|
||||
onClick: restPass.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '锁定用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 2),
|
||||
},
|
||||
{
|
||||
label: '激活用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 1),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div style="min-height: 400px">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div v-if="!formDisabled" style="width: 100%; text-align: center">
|
||||
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { getBpmFormSchema } from '../HealthUserStationEx.data';
|
||||
import { queryByIdUrl, saveOrUpdate } from '../HealthUserStationEx.api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'HealthUserStationExForm',
|
||||
components: {
|
||||
BasicForm,
|
||||
},
|
||||
props: {
|
||||
formData: propTypes.object.def({}),
|
||||
formBpm: propTypes.bool.def(true),
|
||||
},
|
||||
setup(props) {
|
||||
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: getBpmFormSchema(props.formData),
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
const formDisabled = computed(() => {
|
||||
if (props.formData.disabled === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
let formData = {};
|
||||
async function initFormData() {
|
||||
let params = { id: props.formData.dataId };
|
||||
const data = await defHttp.get({ url: queryByIdUrl, params });
|
||||
formData = { ...data };
|
||||
//设置表单的值
|
||||
await setFieldsValue(formData);
|
||||
//默认是禁用
|
||||
await setProps({ disabled: formDisabled.value });
|
||||
}
|
||||
|
||||
async function submitForm() {
|
||||
let data = getFieldsValue();
|
||||
let params = Object.assign({}, formData, data);
|
||||
await saveOrUpdate(params, true);
|
||||
}
|
||||
|
||||
initFormData();
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
formDisabled,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:maskClosable="false"
|
||||
:title="title"
|
||||
:width="adaptiveWidth"
|
||||
:showFooter="showFooter"
|
||||
destroyOnClose
|
||||
v-bind="$attrs"
|
||||
@ok="handleSubmit"
|
||||
@register="registerDrawer"
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { formSchema } from '../HealthUserStationEx.data';
|
||||
import { saveOrUpdate } from '../HealthUserStationEx.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref<boolean>(true);
|
||||
const showFooter = ref<boolean>(true);
|
||||
//设置标题
|
||||
const title = ref(String);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate, updateSchema }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
formSchema[0].componentProps.onOptionsChange = (options) => {
|
||||
onSelectHospital(options);
|
||||
};
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setDrawerProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
showFooter.value = data.showFooter;
|
||||
title.value = data.type;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: false,
|
||||
},
|
||||
]);
|
||||
await clearValidate();
|
||||
} else {
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit(v) {
|
||||
try {
|
||||
let values = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
// 选择医院名称
|
||||
async function onSelectHospital(options) {
|
||||
await setFieldsValue({
|
||||
hospitalName: options[0]['label'],
|
||||
hospitalId: options[0]['value'],
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/medical/hospitalUser/list',
|
||||
save = '/medical/hospitalUser/addCustom',
|
||||
edit = '/medical/hospitalUser/editCustom',
|
||||
deleteOne = '/medical/hospitalUser/delete',
|
||||
deleteBatch = '/medical/hospitalUser/deleteBatch',
|
||||
lockUser = '/sys/user/adminFrozenUser',
|
||||
hospitail = '/medical/hospital/getAllHospital',
|
||||
saveSelectHos = '/medical/checkPackage/saveCheckedItemAll',
|
||||
configured = '/medical/checkPackage/getCheckedItemAll',
|
||||
selectHosList = '/medical/checkPackage/datagridAll',
|
||||
}
|
||||
export const getHospitalsList = (params) => defHttp.get({ url: Api.hospitail, params });
|
||||
/*
|
||||
* 锁定用户
|
||||
* */
|
||||
export const lockUser = (params, type, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `确认${type === 2 ? '锁定' : '激活'}该用户吗?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.post({ url: Api.lockUser, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
// const url = isUpdate ? Api.edit : Api.save;
|
||||
if (isUpdate) {
|
||||
return defHttp.put({ url: Api.edit, params });
|
||||
} else {
|
||||
return defHttp.post({ url: Api.save, params });
|
||||
}
|
||||
};
|
||||
|
||||
export const saveSelectHosApi = (params) => {
|
||||
return defHttp.post({ url: Api.saveSelectHos, params });
|
||||
};
|
||||
|
||||
export const configuredLists = (params) => {
|
||||
return defHttp.get({ url: Api.configured, params });
|
||||
};
|
||||
/**
|
||||
* 配置体检项人员列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const selectHosList = (params) => defHttp.get({ url: Api.selectHosList, params });
|
||||
@@ -0,0 +1,184 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getPhysicalHospitalsList } from '/@/views/system/user/user.api';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
dataIndex: 'username',
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'realname',
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
align: 'center',
|
||||
dataIndex: 'hospitalName',
|
||||
},
|
||||
{
|
||||
title: '账号类型',
|
||||
align: 'center',
|
||||
dataIndex: 'pType_dictText',
|
||||
},
|
||||
{
|
||||
title: '账号状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status_dictText',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'realname',
|
||||
label: '姓名',
|
||||
width: 150,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'hospitalId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getPhysicalHospitalsList,
|
||||
resultField: 'list',
|
||||
labelField: 'hospitalName',
|
||||
valueField: 'hospitalId',
|
||||
immediate: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '账号类型',
|
||||
field: 'pType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '医院检查医生', value: '10' },
|
||||
{ label: '医院管理员', value: '9' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
label: '账号状态',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'hospital_status',
|
||||
},
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '所属医院',
|
||||
field: 'hospitalId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getPhysicalHospitalsList,
|
||||
resultField: 'list',
|
||||
labelField: 'hospitalName',
|
||||
valueField: 'hospitalId',
|
||||
immediate: true,
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '账号类型',
|
||||
field: 'pType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '医院检查医生', value: '10' },
|
||||
{ label: '医院管理员', value: '9' },
|
||||
],
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
autocomplete: 'off',
|
||||
},
|
||||
dynamicRules: ({ model }) => {
|
||||
return [{ required: !model.id, message: '请输入账号' }];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: ({ model }) => {
|
||||
return [
|
||||
{
|
||||
required: !model.id,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '账号状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
type: 'radio',
|
||||
dictCode: 'hospital_status',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
dynamicRules: ({ model }) => {
|
||||
return [{ required: model.id, message: '请选择账号状态' }];
|
||||
},
|
||||
ifShow: ({ values }) => {
|
||||
return values.id;
|
||||
},
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<template #customSlot="{ model, field }">
|
||||
<a-input v-model:value="model[field]" />
|
||||
</template>
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined" v-auth="'medical:medical_hospital_user:add'">
|
||||
新增
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
v-auth="'medical:medical_hospital_user:deleteBatch'"
|
||||
@click="batchHandleDelete"
|
||||
preIcon="ant-design:delete-outlined"
|
||||
>
|
||||
批量删除
|
||||
</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
<template #fileSlot="{ text }">
|
||||
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
|
||||
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)"
|
||||
>下载
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<HealthUserStationExModal @register="registerModal" @success="handleSuccess" />
|
||||
<CheckPageTable ref="pageTableRef" @register="registerCheckTable" @success="handleSuccess" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-hospitalDoctor" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import HealthUserStationExModal from './components/HospitalDoctorModal.vue';
|
||||
import CheckPageTable from './components/checkPageTable/CheckPageTable.vue';
|
||||
import { columns, searchFormSchema } from './HospitalDoctor.data';
|
||||
import { batchDelete, deleteOne, list, lockUser, configuredLists } from './HospitalDoctor.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { message } from 'ant-design-vue';
|
||||
import RestPass from '../restPass/RestPass.vue';
|
||||
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
const [registerCheckTable, { openModal: openHosModal }] = useModal();
|
||||
const pageTableRef = ref();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'hospitalDoctor',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
// labelWidth: 80,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
type: '新增',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
type: '编辑',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
type: '详情',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return message.warning('未选中任何数据');
|
||||
}
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
async function handleExamination(record) {
|
||||
const params = {
|
||||
doctorId: record.userId,
|
||||
};
|
||||
const res = await configuredLists(params);
|
||||
openHosModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
setTimeout(() => {
|
||||
pageTableRef.value && pageTableRef?.value?.updateSource(res);
|
||||
}, 200);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'medical:medical_hospital_user:edit',
|
||||
},
|
||||
{
|
||||
label: '配置体检项',
|
||||
onClick: handleExamination.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
// 重置密码
|
||||
function restPass(record) {
|
||||
restPaddModel(true, {
|
||||
record: record.userId,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
// 1 锁定用户 2 激活用户
|
||||
async function handleUserOpt(record, type) {
|
||||
const params = {
|
||||
userId: record.userId,
|
||||
status: type,
|
||||
};
|
||||
await lockUser(params, type, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'medical:medical_hospital_user:delete',
|
||||
},
|
||||
{
|
||||
label: '重置密码',
|
||||
onClick: restPass.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '锁定用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 2),
|
||||
},
|
||||
{
|
||||
label: '激活用户',
|
||||
auth: 'system:user:frozen',
|
||||
onClick: handleUserOpt.bind(null, record, 1),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div style="min-height: 400px">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div v-if="!formDisabled" style="width: 100%; text-align: center">
|
||||
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { getBpmFormSchema } from '../HospitalDoctor.data';
|
||||
import { saveOrUpdate } from '../HospitalDoctor.api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'HealthUserStationExForm',
|
||||
components: {
|
||||
BasicForm,
|
||||
},
|
||||
props: {
|
||||
formData: propTypes.object.def({}),
|
||||
formBpm: propTypes.bool.def(true),
|
||||
},
|
||||
setup(props) {
|
||||
const [registerForm, { getFieldsValue }] = useForm({
|
||||
labelWidth: 150,
|
||||
schemas: getBpmFormSchema(props.formData),
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
const formDisabled = computed(() => {
|
||||
if (props.formData.disabled === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
let formData = {};
|
||||
|
||||
async function submitForm() {
|
||||
let data = getFieldsValue();
|
||||
let params = Object.assign({}, formData, data);
|
||||
await saveOrUpdate(params, true);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
formDisabled,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<BasicModal :title="title" :width="800" destroyOnClose v-bind="$attrs" @ok="handleSubmit" @register="registerModal">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { formSchema } from '../HospitalDoctor.data';
|
||||
import { saveOrUpdate } from '../HospitalDoctor.api';
|
||||
import { dealParams } from '/@/views/system/user/user.data';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//设置标题
|
||||
const title = ref(String);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema, clearValidate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
title.value = data.type;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await clearValidate();
|
||||
}
|
||||
updateSchema([
|
||||
{ field: 'username', ifShow: !unref(isUpdate) },
|
||||
{ field: 'password', ifShow: !unref(isUpdate) },
|
||||
{ field: 'hospitalId', dynamicDisabled: unref(isUpdate) },
|
||||
{ field: 'pType', dynamicDisabled: unref(isUpdate) },
|
||||
]);
|
||||
// 隐藏底部时禁用整个表单
|
||||
setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(dealParams(values), isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '体检项名称',
|
||||
align: 'center',
|
||||
dataIndex: 'itemName',
|
||||
},
|
||||
{
|
||||
title: '体检项类型',
|
||||
align: 'center',
|
||||
dataIndex: 'checkItemType_dictText',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '体检项目名称',
|
||||
field: 'itemName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '体检项类型',
|
||||
field: 'checkItemType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'check_item_type',
|
||||
},
|
||||
// colProps: { span: 8 },
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
// 配置体检项数据
|
||||
|
||||
// 列表数据
|
||||
export const TransferColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '体检项名称',
|
||||
align: 'center',
|
||||
key: 'checkItemName',
|
||||
},
|
||||
{
|
||||
title: '体检项类型',
|
||||
align: 'center',
|
||||
key: 'checkItemType_dictText',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="1200" @ok="handleSubmit" @cancel="cancel">
|
||||
<div class="configuration-module">
|
||||
<BasicTable class="self-table" @register="registerTable" @row-click="(record) => handleCheck(record)">
|
||||
<template #tableTitle>
|
||||
<span class="title-span">点击行添加到体检项中</span>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<div class="operation-box">
|
||||
<div v-if="checkList[record.id]" class="operation add-row">√</div>
|
||||
<div v-else class="operation elete-row"></div>
|
||||
</div>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<transfer-table
|
||||
ref="transferTableRef"
|
||||
:key="transferTableKey"
|
||||
:columns="TransferColumns"
|
||||
:dataSource="dataSource"
|
||||
class="transfer-table"
|
||||
@deleteItem="handleRemoveCheck"
|
||||
/>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicTable } from '/@/components/Table';
|
||||
import { columns, searchFormSchema, TransferColumns } from './CheckPackageTable.data';
|
||||
import { selectHosList, saveSelectHosApi } from '../../HospitalDoctor.api';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import TransferTable from './TransferTable.vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const title = ref('配置体检项');
|
||||
const hosId = ref();
|
||||
const doctorId = ref();
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
let { hospitalId, userId } = data.record;
|
||||
hosId.value = hospitalId;
|
||||
doctorId.value = userId;
|
||||
});
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
api: selectHosList,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
labelAlign: 'right',
|
||||
// labelWidth: 100,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
labelCol: {
|
||||
style: '100px',
|
||||
},
|
||||
baseColProps: {
|
||||
xs: 8,
|
||||
sm: 8,
|
||||
md: 8,
|
||||
lg: 8,
|
||||
xl: 12,
|
||||
xxl: 8,
|
||||
},
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
xs: 8,
|
||||
sm: 8,
|
||||
md: 8,
|
||||
lg: 8,
|
||||
xl: 12,
|
||||
xxl: 8,
|
||||
},
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
params['hospitalId'] = hosId.value;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
title: '选中',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, {}, {}] = tableContext;
|
||||
const transferTableRef = ref();
|
||||
const transferTableKey = ref(true);
|
||||
const dataSource = ref([]);
|
||||
const checkList = ref({});
|
||||
|
||||
function updateSource(res: []) {
|
||||
dataSource.value.push(...res);
|
||||
if (res) {
|
||||
res.map((item) => {
|
||||
checkList.value[item.checkItemId] = item;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 表单提交事件
|
||||
function clearDataSource() {
|
||||
dataSource.value = [];
|
||||
checkList.value = {};
|
||||
transferTableRef.value.updateDataSource([]);
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
clearDataSource();
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const selectIds = transferTableRef.value.emitDataSource();
|
||||
// if (selectIds === '') {
|
||||
// return message.warning('请选择体检配置项');
|
||||
// }
|
||||
const params = {
|
||||
...selectIds,
|
||||
doctorId: doctorId.value,
|
||||
};
|
||||
setModalProps({ confirmLoading: true });
|
||||
// 提交
|
||||
await saveSelectHosApi(params);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
clearDataSource();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
function handleCheck(record) {
|
||||
if (!checkList.value.hasOwnProperty(record.itemId)) {
|
||||
checkList.value[record.itemId] = record;
|
||||
(dataSource.value as any).push({
|
||||
...record,
|
||||
checkItemName: record.itemName,
|
||||
checkItemId: record.itemId,
|
||||
});
|
||||
} else {
|
||||
handleRemoveCheck({ ...record, checkItemId: record.itemId });
|
||||
}
|
||||
}
|
||||
|
||||
function handleRemoveCheck(record) {
|
||||
delete checkList.value[record.checkItemId];
|
||||
dataSource.value = dataSource.value.filter((item) => item.checkItemId !== record.checkItemId);
|
||||
transferTableRef.value.updateDataSource(dataSource.value);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
updateSource,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.configuration-module {
|
||||
display: flex;
|
||||
height: 70vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.ant-table-title) {
|
||||
//display: none;
|
||||
}
|
||||
|
||||
.self-table {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.transfer-table {
|
||||
width: 30%;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
:deep(.add-row) {
|
||||
width: 100px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #1890ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:deep(.delete-row) {
|
||||
width: 100px;
|
||||
//opacity: 0; cursor: pointer;
|
||||
}
|
||||
|
||||
.title-span {
|
||||
color: red;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.operation-box {
|
||||
margin-left: 40%;
|
||||
}
|
||||
|
||||
.operation {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #d9d9d9;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="panel-header">
|
||||
<p class="panel-title"> 体检项已选 </p>
|
||||
</div>
|
||||
<a-table :dataSource="transferState.dataSource" :columns="transferState.columns">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<a @click="deleteItem(record)">删除</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record[column.key] }}
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
columns: Array,
|
||||
dataSource: Array,
|
||||
});
|
||||
const emits = defineEmits(['deleteItem']);
|
||||
const transferState = ref({
|
||||
columns: props.columns,
|
||||
// dataSource: computed(() => props.dataSource),
|
||||
dataSource: props.dataSource,
|
||||
});
|
||||
|
||||
function updateDataSource(data) {
|
||||
transferState.value.dataSource = data;
|
||||
}
|
||||
|
||||
function emitDataSource() {
|
||||
return {
|
||||
selectIds: transferState.value.dataSource?.map((item) => item?.checkItemId).join(',') || '',
|
||||
};
|
||||
}
|
||||
|
||||
function deleteItem(record) {
|
||||
emits('deleteItem', record);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
updateDataSource,
|
||||
emitDataSource,
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.panel-header {
|
||||
background-color: #fafafa;
|
||||
background-repeat: repeat-x;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 15px;
|
||||
border-bottom: 1px solid #e7eaec !important;
|
||||
border-top-right-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
|
||||
.panel-title {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button preIcon="ant-design:plus-outlined" type="primary" @click="handleCreate"> 新增</a-button>
|
||||
<a-button preIcon="ant-design:hdd-outlined" type="primary" @click="openModal(true, {})"> 回收站</a-button>
|
||||
<!-- <JThirdAppButton biz-type="user" :selected-row-keys="selectedRowKeys" syncToApp syncToLocal @sync-finally="onSyncFinally" />-->
|
||||
<!-- <a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined" />
|
||||
删除
|
||||
</a-menu-item>
|
||||
<a-menu-item key="2" @click="batchFrozen(2)">
|
||||
<Icon icon="ant-design:lock-outlined" />
|
||||
锁定
|
||||
</a-menu-item>
|
||||
<a-menu-item key="3" @click="batchFrozen(1)">
|
||||
<Icon icon="ant-design:unlock-outlined" />
|
||||
激活
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button
|
||||
>批量操作
|
||||
<Icon icon="mdi:chevron-down" />
|
||||
</a-button>
|
||||
</a-dropdown>-->
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--用户抽屉-->
|
||||
<UserDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- <!–修改密码–>
|
||||
<PasswordModal @register="registerPasswordModal" @success="reload" />-->
|
||||
<!--用户代理-->
|
||||
<UserAgentModal @register="registerAgentModal" @success="reload" />
|
||||
<!--回收站-->
|
||||
<UserRecycleBinModal @register="registerModal" @success="reload" />
|
||||
<!-- 离职受理人弹窗 -->
|
||||
<UserQuitAgentModal @register="registerQuitAgentModal" @success="reload" />
|
||||
<!-- 离职人员列弹窗 -->
|
||||
<UserQuitModal @register="registerQuitModal" @success="reload" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="system-user-old" setup>
|
||||
//ts语法
|
||||
import { ref, computed, unref } from 'vue';
|
||||
import { BasicTable, TableAction, ActionItem } from '/@/components/Table';
|
||||
import UserDrawer from './UserDrawer.vue';
|
||||
import UserRecycleBinModal from './UserRecycleBinModal.vue';
|
||||
import PasswordModal from './PasswordModal.vue';
|
||||
import UserAgentModal from './UserAgentModal.vue';
|
||||
import JThirdAppButton from '/@/components/jeecg/thirdApp/JThirdAppButton.vue';
|
||||
import UserQuitAgentModal from './UserQuitAgentModal.vue';
|
||||
import UserQuitModal from './UserQuitModal.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { columns, searchFormSchema } from './user.data';
|
||||
import { listNoCareTenant, deleteUser, batchDeleteUser, getImportUrl, getExportUrl, frozenBatch, syncUser } from './user.api';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
import RestPass from "/@/views/system/user/restPass/RestPass.vue";
|
||||
|
||||
const { createMessage, createConfirm } = useMessage();
|
||||
const { isDisabledAuth } = usePermission();
|
||||
//注册drawer
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
//回收站model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//密码model
|
||||
const [registerPasswordModal, { openModal: openPasswordModal }] = useModal();
|
||||
//代理人model
|
||||
const [registerAgentModal, { openModal: openAgentModal }] = useModal();
|
||||
//离职代理人model
|
||||
const [registerQuitAgentModal, { openModal: openQuitAgentModal }] = useModal();
|
||||
//离职用户列表model
|
||||
const [registerQuitModal, { openModal: openQuitModal }] = useModal();
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
|
||||
// 列表页面公共参数、方法
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
designScope: 'user-list',
|
||||
tableProps: {
|
||||
title: '用户列表',
|
||||
api: listNoCareTenant,
|
||||
columns: columns,
|
||||
size: 'small',
|
||||
formConfig: {
|
||||
// labelWidth: 200,
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
return Object.assign({ column: 'createTime', order: 'desc' }, params);
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '用户列表',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
},
|
||||
});
|
||||
|
||||
//注册table数据
|
||||
const [registerTable, { reload, updateTableDataRecord }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleCreate() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
async function handleDetail(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
if ('admin' == record.username) {
|
||||
createMessage.warning('管理员账号不允许此操作!');
|
||||
return;
|
||||
}
|
||||
await deleteUser({ id: record.id }, reload);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
let hasAdmin = unref(selectedRows).filter((item) => item.username == 'admin');
|
||||
if (unref(hasAdmin).length > 0) {
|
||||
createMessage.warning('管理员账号不允许此操作!');
|
||||
return;
|
||||
}
|
||||
await batchDeleteUser({ ids: selectedRowKeys.value }, () => {
|
||||
selectedRowKeys.value = [];
|
||||
reload();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开修改密码弹窗
|
||||
*/
|
||||
function handleChangePassword(username) {
|
||||
openPasswordModal(true, { username });
|
||||
}
|
||||
/**
|
||||
* 打开代理人弹窗
|
||||
*/
|
||||
function handleAgentSettings(userName) {
|
||||
openAgentModal(true, { userName });
|
||||
}
|
||||
/**
|
||||
* 冻结解冻
|
||||
*/
|
||||
async function handleFrozen(record, status) {
|
||||
if ('admin' == record.username) {
|
||||
createMessage.warning('管理员账号不允许此操作!');
|
||||
return;
|
||||
}
|
||||
await frozenBatch({ ids: record.id, status: status }, reload);
|
||||
}
|
||||
/**
|
||||
* 批量冻结解冻
|
||||
*/
|
||||
function batchFrozen(status) {
|
||||
let hasAdmin = selectedRows.value.filter((item) => item.username == 'admin');
|
||||
if (unref(hasAdmin).length > 0) {
|
||||
createMessage.warning('管理员账号不允许此操作!');
|
||||
return;
|
||||
}
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认操作',
|
||||
content: '是否' + (status == 1 ? '激活' : '锁定') + '选中账号?',
|
||||
onOk: async () => {
|
||||
await frozenBatch({ ids: unref(selectedRowKeys).join(','), status: status }, reload);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*同步流程
|
||||
*/
|
||||
function handleSyncUser() {
|
||||
syncUser();
|
||||
}
|
||||
/**
|
||||
*同步钉钉和微信回调
|
||||
*/
|
||||
function onSyncFinally({ isToLocal }) {
|
||||
// 同步到本地时刷新下数据
|
||||
if (isToLocal) {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record): ActionItem[] {
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
// 重置密码
|
||||
function restPass(record) {
|
||||
restPaddModel(true, {
|
||||
record: record.id,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record): ActionItem[] {
|
||||
return [
|
||||
|
||||
{
|
||||
label: '重置密码',
|
||||
onClick: restPass.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '锁定',
|
||||
ifShow: record.status == 1,
|
||||
popConfirm: {
|
||||
title: '确定锁定吗?',
|
||||
confirm: handleFrozen.bind(null, record, 2),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '激活',
|
||||
ifShow: record.status == 2,
|
||||
popConfirm: {
|
||||
title: '确定激活吗?',
|
||||
confirm: handleFrozen.bind(null, record, 1),
|
||||
},
|
||||
},
|
||||
/*{
|
||||
label: '代理人',
|
||||
onClick: handleAgentSettings.bind(null, record.username),
|
||||
},*/
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 离职
|
||||
* @param userName
|
||||
*/
|
||||
function handleQuit(userName) {
|
||||
//打开离职代理人弹窗
|
||||
openQuitAgentModal(true, { userName });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { dealParams } from '/@/views/system/user/user.data';
|
||||
enum Api {
|
||||
restPass = '/sys/user/adminResetPassword',
|
||||
}
|
||||
|
||||
/*
|
||||
* 重置密码
|
||||
* */
|
||||
export const restPass = (values) => {
|
||||
const params = dealParams(values, true);
|
||||
return defHttp.post({ url: Api.restPass, params });
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<BasicModal :title="title" :width="800" destroyOnClose v-bind="$attrs" @ok="handleSubmit" @register="registerModal">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, defineEmits, h } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form';
|
||||
import { restPass } from './RestPass.api';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
const title = ref('重置密码');
|
||||
import { message } from 'ant-design-vue';
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const userId = ref('');
|
||||
const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '新密码',
|
||||
field: 'newPassword',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
autocomplete: 'new-password',
|
||||
onBlur: () => {
|
||||
validate();
|
||||
},
|
||||
onInput: () => {
|
||||
// if (formModel.newPassword && (formModel.newPassword as string).indexOf('\\') !== -1) {
|
||||
// message.info('不能输入\\');
|
||||
// return (formModel.newPassword = formModel.newPassword.replaceAll(/\\/g, ''));
|
||||
// }
|
||||
if (formModel.newPassword && (formModel.newPassword as string).indexOf(' ') !== -1) {
|
||||
message.info('不能输入空格');
|
||||
return (formModel.newPassword = formModel.newPassword.replaceAll(/ /g, ''));
|
||||
}
|
||||
},
|
||||
// '必须包含至少一个小写字母\n' +
|
||||
// '必须包含至少一个大写字母\n' +
|
||||
// '必须包含至少一个数字\n' +
|
||||
// '必须包含至少一个特殊符号(可以根据需要修改特殊符号的定义)\n' +
|
||||
// '密码长度必须大于等于12',
|
||||
};
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value, true);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '确认密码',
|
||||
field: 'newPasswordConfirm',
|
||||
component: 'InputPassword',
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: validatePassword,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
];
|
||||
//表单配置
|
||||
const [registerForm, { validate, getFieldsValue }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
function validatePassword(_, value) {
|
||||
if (!value) {
|
||||
return Promise.reject('确认密码不能为空');
|
||||
}
|
||||
let values = getFieldsValue();
|
||||
if (values.newPasswordConfirm == values.newPassword) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject('两次输入的密码不一致!');
|
||||
}
|
||||
}
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner((data) => {
|
||||
userId.value = data.record;
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
values['userId'] = userId.value;
|
||||
await restPass(values);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,316 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
|
||||
enum Api {
|
||||
listNoCareTenant = '/sys/user/listAll',
|
||||
list = '/sys/user/list',
|
||||
save = '/sys/user/add',
|
||||
edit = '/sys/user/edit',
|
||||
agentSave = '/sys/sysUserAgent/add',
|
||||
agentEdit = '/sys/sysUserAgent/edit',
|
||||
getUserRole = '/sys/user/queryUserRole',
|
||||
duplicateCheck = '/sys/duplicate/check',
|
||||
deleteUser = '/sys/user/delete',
|
||||
deleteBatch = '/sys/user/deleteBatch',
|
||||
importExcel = '/sys/user/importExcel',
|
||||
exportXls = '/sys/user/exportXls',
|
||||
recycleBinList = '/sys/user/recycleBinPageList',
|
||||
putRecycleBin = '/sys/user/putRecycleBin',
|
||||
deleteRecycleBin = '/sys/user/deleteRecycleBin',
|
||||
allRolesList = '/sys/role/queryall',
|
||||
allRolesListNoByTenant = '/sys/role/queryallNoByTenant',
|
||||
allTenantList = '/sys/tenant/queryList',
|
||||
allPostList = '/sys/user/listUserByRole',
|
||||
userDepartList = '/sys/user/userDepartList',
|
||||
changePassword = '/sys/user/changePassword',
|
||||
frozenBatch = '/sys/user/frozenBatch',
|
||||
getUserAgent = '/sys/sysUserAgent/queryByUserName',
|
||||
syncUser = '/act/process/extActProcess/doSyncUser',
|
||||
userQuitAgent = '/sys/user/userQuitAgent',
|
||||
getQuitList = '/sys/user/getQuitList',
|
||||
putCancelQuit = '/sys/user/putCancelQuit',
|
||||
updateUserTenantStatus = '/sys/tenant/updateUserTenantStatus',
|
||||
getUserTenantPageList = '/sys/tenant/getUserTenantPageList',
|
||||
getHospitals = '/sys/healthConsultResource/selectConsultResourceList',
|
||||
getPhysical = '/medical/hospital/getAllHospital',
|
||||
getPhysicalAndVirtual = '/medical/hospital/getAllHospitalAndVirtual',
|
||||
getMedicalSecondDeparts = '/medical/hospital/getMedicalSecondDeparts',
|
||||
getMedicalThirdDeparts = '/medical/hospital/getMedicalThirdDeparts',
|
||||
officeApiSelect = '/sys/category/selectSysCategoryList',
|
||||
getSecondaryDepartment = '/sys/sysDepart/allSecondaryDeparts',
|
||||
getThirdDepartment = '/sys/sysDepart/getThirdDepartListBySecondDepartId',
|
||||
thirdByCode = '/sys/sysDepart/getThirdDepartListByOrgCode',
|
||||
getNewHospital = '/health-emergency/emergency/resource/listCustom',
|
||||
getThreeDepartByOrgCode = '/sys/sysDepart/getThreeDepartByOrgCode',
|
||||
}
|
||||
|
||||
export const getThreeDepartByOrgCode = (params) => {
|
||||
return defHttp.get({ url: Api.getThreeDepartByOrgCode, params });
|
||||
};
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口(查询用户,通过租户隔离)
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
/**
|
||||
* @Description:选择用户列表查询form
|
||||
* @date 2023/8/23
|
||||
* @param params
|
||||
*/
|
||||
export const checkUserList = (params) => defHttp.get({ url: Api.allPostList, params });
|
||||
|
||||
/**
|
||||
* 列表接口(查询全部用户,不通过租户隔离)
|
||||
* @param params
|
||||
*/
|
||||
export const listNoCareTenant = (params) => defHttp.get({ url: Api.listNoCareTenant, params });
|
||||
|
||||
/**
|
||||
* 用户角色接口
|
||||
* @param params
|
||||
*/
|
||||
export const getUserRoles = (params) => defHttp.get({ url: Api.getUserRole, params }, { errorMessageMode: 'none' });
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*/
|
||||
export const deleteUser = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteUser, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除用户
|
||||
* @param params
|
||||
*/
|
||||
export const batchDeleteUser = (params, handleSuccess) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 保存或者更新用户
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdateUser = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* 唯一校验
|
||||
* @param params
|
||||
*/
|
||||
export const duplicateCheck = (params) => defHttp.get({ url: Api.duplicateCheck, params }, { isTransformResponse: false });
|
||||
/**
|
||||
* 获取全部角色(租户隔离)
|
||||
* @param params
|
||||
*/
|
||||
export const getAllRolesList = (params) => defHttp.get({ url: Api.allRolesList, params });
|
||||
/**
|
||||
* 获取全部角色(不租户隔离)
|
||||
* @param params
|
||||
*/
|
||||
export const getAllRolesListNoByTenant = (params) => defHttp.get({ url: Api.allRolesListNoByTenant, params });
|
||||
/**
|
||||
* 获取全部租户
|
||||
*/
|
||||
export const getAllTenantList = (params) => defHttp.get({ url: Api.allTenantList, params });
|
||||
/**
|
||||
* 获取指定用户负责部门
|
||||
*/
|
||||
export const getUserDepartList = (params) => defHttp.get({ url: Api.userDepartList, params }, { successMessageMode: 'none' });
|
||||
/**
|
||||
* 获取全部职务
|
||||
*/
|
||||
export const getAllPostList = (params) => {
|
||||
return new Promise((resolve) => {
|
||||
defHttp.get({ url: Api.allPostList, params }).then((res) => {
|
||||
resolve(res.records);
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 回收站列表
|
||||
* @param params
|
||||
*/
|
||||
export const getRecycleBinList = (params) => defHttp.get({ url: Api.recycleBinList, params });
|
||||
/**
|
||||
* 回收站还原
|
||||
* @param params
|
||||
*/
|
||||
export const putRecycleBin = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.putRecycleBin, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 回收站删除
|
||||
* @param params
|
||||
*/
|
||||
export const deleteRecycleBin = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteRecycleBin, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 修改密码
|
||||
* @param params
|
||||
*/
|
||||
export const changePassword = (params) => {
|
||||
return defHttp.put({ url: Api.changePassword, params });
|
||||
};
|
||||
/**
|
||||
* 冻结解冻
|
||||
* @param params
|
||||
*/
|
||||
export const frozenBatch = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.frozenBatch, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取用户代理
|
||||
* @param params
|
||||
*/
|
||||
export const getUserAgent = (params) => defHttp.get({ url: Api.getUserAgent, params }, { isTransformResponse: false });
|
||||
/**
|
||||
* 保存或者更新用户代理
|
||||
* @param params
|
||||
*/
|
||||
export const saveOrUpdateAgent = (params) => {
|
||||
const url = params.id ? Api.agentEdit : Api.agentSave;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户同步流程
|
||||
* @param params
|
||||
*/
|
||||
export const syncUser = () => defHttp.put({ url: Api.syncUser });
|
||||
|
||||
/**
|
||||
* 用户离职(新增代理人和用户状态变更操作)
|
||||
* @param params
|
||||
*/
|
||||
export const userQuitAgent = (params) => {
|
||||
return defHttp.put({ url: Api.userQuitAgent, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户离职列表
|
||||
* @param params
|
||||
*/
|
||||
export const getQuitList = (params) => {
|
||||
return defHttp.get({ url: Api.getQuitList, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消离职
|
||||
* @param params
|
||||
*/
|
||||
export const putCancelQuit = (params, handleSuccess) => {
|
||||
return defHttp.put({ url: Api.putCancelQuit, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 待审批获取列表数据
|
||||
*/
|
||||
export const getUserTenantPageList = (params) => {
|
||||
return defHttp.get({ url: Api.getUserTenantPageList, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新租户状态
|
||||
* @param params
|
||||
*/
|
||||
export const updateUserTenantStatus = (params) => {
|
||||
return defHttp.put({ url: Api.updateUserTenantStatus, params }, { joinParamsToUrl: true, isTransformResponse: false });
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取医院列表 用户管理(新增专家信息、新增驻场人员)
|
||||
*/
|
||||
export const getHospitalsList = async () => {
|
||||
return await defHttp.get({ url: Api.getHospitals });
|
||||
};
|
||||
/**
|
||||
* 获取医院列表 体检管理
|
||||
*/
|
||||
export const getPhysicalHospitalsList = async () => {
|
||||
return await defHttp.get({ url: Api.getPhysical });
|
||||
};
|
||||
/**
|
||||
* 获取医院列表 体检管理(忽略权限)
|
||||
*/
|
||||
export const getPhysicalHospitalsListIgnoreAuth = async () => {
|
||||
let params = {
|
||||
authFlag: '0',
|
||||
};
|
||||
return await defHttp.get({ url: Api.getPhysical, params });
|
||||
};
|
||||
/**
|
||||
* 获取医院列表 体检管理
|
||||
*/
|
||||
export const getPhysicalHospitalsAllList = async () => {
|
||||
return await defHttp.get({ url: Api.getPhysicalAndVirtual });
|
||||
};
|
||||
/**
|
||||
* 获取体检功能中的二级单位,优先查询所管理的二级单位,再查询管理医院的签约单位
|
||||
*/
|
||||
export const getMedicalSecondDeparts = () => {
|
||||
return defHttp.get({ url: Api.getMedicalSecondDeparts });
|
||||
};
|
||||
/**
|
||||
* 获取体检功能中的三级单位,优先查询所管理的二级单位,再查询管理医院的签约单位
|
||||
*/
|
||||
export const getMedicalThirdDeparts = async (params) => {
|
||||
if (!params.secondDepartId) {
|
||||
return [];
|
||||
}
|
||||
return defHttp.get({ url: Api.getMedicalThirdDeparts, params });
|
||||
};
|
||||
/**
|
||||
* 获取二级部门 体检管理
|
||||
*/
|
||||
export const getSecondaryDepartmentList = () => {
|
||||
return defHttp.get({ url: Api.getSecondaryDepartment });
|
||||
};
|
||||
/**
|
||||
* 获取三级部门 体检管理
|
||||
*/
|
||||
export const getThirdDepartmentList = async (params) => {
|
||||
if (!params.secondDepartId) {
|
||||
return [];
|
||||
}
|
||||
return await defHttp.get({ url: Api.getThirdDepartment, params });
|
||||
};
|
||||
|
||||
export const getThirdDepartListByOrgCode = (params) => defHttp.get({ url: Api.thirdByCode, params });
|
||||
/**
|
||||
* 科室列表
|
||||
*/
|
||||
export const getOfficeList = async (params) => {
|
||||
return await defHttp.get({ url: Api.officeApiSelect, params });
|
||||
};
|
||||
export const getNewHospitalApi = (params) => {
|
||||
return defHttp.get({ url: Api.getNewHospital, params });
|
||||
};
|
||||
@@ -0,0 +1,725 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getAllRolesListNoByTenant, getAllTenantList } from './user.api';
|
||||
import { rules } from '/@/utils/helper/validator';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { Component, h } from 'vue';
|
||||
import HealthUserEmployeeEx from './HealthUserEmployeeEx/HealthUserEmployeeExList.vue';
|
||||
import healthUserOperatorEx from './healthUserOperatorEx/HealthUserOperatorExList.vue';
|
||||
import healthUserStationEx from './healthUserStationEx/HealthUserStationExList.vue';
|
||||
import healthOperatorEx from './healthOperatorEx/healthOperatorExList.vue';
|
||||
import healthExpert from '/@/views/consult/doctor/message/conDoctorList.vue';
|
||||
import healthHelper from '/@/views/consult/helper/conHelperList.vue';
|
||||
import hospitalDoctor from './hospitalDoctor/HospitalDoctorList.vue';
|
||||
import { encipher } from '/@/utils/jsencrypt';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
import { isShowIdCard } from '/@/utils/getEnv';
|
||||
import { Image } from 'ant-design-vue';
|
||||
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
dataIndex: 'username',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
dataIndex: 'realname',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '用户类型',
|
||||
dataIndex: 'personType_dictText',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
dataIndex: 'avatar',
|
||||
width: 120,
|
||||
// customRender: render.renderAvatar,
|
||||
customRender: ({ text, record }) => {
|
||||
// if (text) {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getFamaleDefaultImage(record.sex),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
dataIndex: 'sex',
|
||||
width: 80,
|
||||
sorter: true,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'sex2');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '生日',
|
||||
dataIndex: 'birthday',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
dataIndex: 'phone',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
width: 150,
|
||||
dataIndex: 'orgCodeTxt',
|
||||
},
|
||||
{
|
||||
title: '负责部门',
|
||||
width: 150,
|
||||
dataIndex: 'departIds_dictText',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status_dictText',
|
||||
width: 80,
|
||||
},
|
||||
];
|
||||
|
||||
export const recycleColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
dataIndex: 'username',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
dataIndex: 'realname',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '单位名称',
|
||||
align: 'center',
|
||||
dataIndex: ['secondDepart', 'departName'],
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
align: 'center',
|
||||
dataIndex: 'idCard',
|
||||
width: 160,
|
||||
ifShow: isShowIdCard(),
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
dataIndex: 'sex',
|
||||
width: 80,
|
||||
sorter: true,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'sex2');
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const recycleSearchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '名字',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
/*{
|
||||
label: '用户类型',
|
||||
field: 'personType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'p_type',
|
||||
placeholder: '请选择用户类型',
|
||||
stringToNumber: true,
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},*/
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '账号',
|
||||
field: 'username',
|
||||
component: 'JInput',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '名字',
|
||||
field: 'realname',
|
||||
component: 'JInput',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'sex2',
|
||||
placeholder: '请选择性别',
|
||||
stringToNumber: true,
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '用户类型',
|
||||
field: 'personType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'p_type',
|
||||
placeholder: '请选择用户类型',
|
||||
stringToNumber: true,
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '手机号码',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '用户状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'user_status',
|
||||
placeholder: '请选择状态',
|
||||
stringToNumber: true,
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
dynamicDisabled: ({ values }) => {
|
||||
return !!values.id;
|
||||
},
|
||||
dynamicRules: ({ model, schema }) => {
|
||||
if (model.id) {
|
||||
return rules.duplicateCheckRule('sys_user', 'username', model, schema, true);
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '登录密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
autocomplete: 'new-password',
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
const { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '确认密码',
|
||||
field: 'confirmPassword',
|
||||
component: 'InputPassword',
|
||||
dynamicRules: ({ values }) => rules.confirmPassword(values, true),
|
||||
},
|
||||
{
|
||||
label: '用户姓名',
|
||||
field: 'realname',
|
||||
required: true,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '员工编号', // 原来为工号
|
||||
field: 'workNo',
|
||||
required: true,
|
||||
component: 'Input',
|
||||
dynamicRules: ({ model, schema }) => rules.duplicateCheckRule('sys_user', 'work_no', model, schema, true),
|
||||
},
|
||||
{
|
||||
label: '职务',
|
||||
field: 'post',
|
||||
required: false,
|
||||
component: 'JSelectPosition',
|
||||
componentProps: {
|
||||
rowKey: 'code',
|
||||
labelKey: 'name',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '角色',
|
||||
field: 'selectedroles',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
mode: 'multiple',
|
||||
api: getAllRolesListNoByTenant,
|
||||
labelField: 'roleName',
|
||||
valueField: 'id',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '所属部门',
|
||||
field: 'selecteddeparts',
|
||||
component: 'JSelectDept',
|
||||
componentProps: ({ formActionType, formModel }) => {
|
||||
return {
|
||||
sync: false,
|
||||
checkStrictly: true,
|
||||
defaultExpandLevel: 2,
|
||||
onSelect: (options, values) => {
|
||||
const { updateSchema } = formActionType;
|
||||
//所属部门修改后更新负责部门下拉框数据
|
||||
updateSchema([
|
||||
{
|
||||
field: 'departIds',
|
||||
componentProps: { options },
|
||||
},
|
||||
]);
|
||||
//所属部门修改后更新负责部门数据
|
||||
formModel.departIds && (formModel.departIds = formModel.departIds.filter((item) => values.value.indexOf(item) > -1));
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '租户',
|
||||
field: 'relTenantIds',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
mode: 'multiple',
|
||||
api: getAllTenantList,
|
||||
numberToString: true,
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '身份',
|
||||
field: 'userIdentity',
|
||||
component: 'RadioGroup',
|
||||
defaultValue: 1,
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
options: [
|
||||
{ label: '普通用户', value: 1, key: '1' },
|
||||
{ label: '上级', value: 2, key: '2' },
|
||||
],
|
||||
onChange: () => {
|
||||
formModel.userIdentity == 1 && (formModel.departIds = []);
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '负责部门',
|
||||
field: 'departIds',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
mode: 'multiple',
|
||||
},
|
||||
ifShow: ({ values }) => values.userIdentity == 2,
|
||||
},
|
||||
{
|
||||
label: '头像',
|
||||
field: 'avatar',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
fileMax: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '生日',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'sex2',
|
||||
type: 'radio',
|
||||
placeholder: '请选择性别',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
field: 'email',
|
||||
component: 'Input',
|
||||
dynamicRules: ({ model, schema }) => {
|
||||
return [{ ...rules.duplicateCheckRule('sys_user', 'email', model, schema, true)[0] }, { ...rules.rule('email', false)[0] }];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号码',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
dynamicRules: ({ model, schema }) => {
|
||||
return [
|
||||
{ ...rules.duplicateCheckRule('sys_user', 'phone', model, schema, true)[0] },
|
||||
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '座机',
|
||||
field: 'telephone',
|
||||
component: 'Input',
|
||||
rules: [{ pattern: /^0\d{2,3}-[1-9]\d{6,7}$/, message: '请输入正确的座机号码' }],
|
||||
},
|
||||
{
|
||||
label: '工作流引擎',
|
||||
field: 'activitiSync',
|
||||
defaultValue: 1,
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'activiti_sync',
|
||||
type: 'radio',
|
||||
stringToNumber: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const formPasswordSchema: FormSchema[] = [
|
||||
{
|
||||
label: '用户账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
componentProps: { readOnly: true },
|
||||
},
|
||||
{
|
||||
label: '登录密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
placeholder: '请输入登录密码',
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '确认密码',
|
||||
field: 'confirmPassword',
|
||||
component: 'InputPassword',
|
||||
dynamicRules: ({ values }) => rules.confirmPassword(values, true),
|
||||
},
|
||||
];
|
||||
|
||||
export const formAgentSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
field: 'userName',
|
||||
label: '用户名',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
readOnly: true,
|
||||
allowClear: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'agentUserName',
|
||||
label: '代理人用户名',
|
||||
required: true,
|
||||
component: 'JSelectUser',
|
||||
componentProps: {
|
||||
rowKey: 'username',
|
||||
labelKey: 'realname',
|
||||
maxSelectCount: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'startTime',
|
||||
label: '代理开始时间',
|
||||
component: 'DatePicker',
|
||||
required: true,
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
placeholder: '请选择代理开始时间',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'endTime',
|
||||
label: '代理结束时间',
|
||||
component: 'DatePicker',
|
||||
required: true,
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
placeholder: '请选择代理结束时间',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
label: '状态',
|
||||
component: 'JDictSelectTag',
|
||||
defaultValue: '1',
|
||||
componentProps: {
|
||||
dictCode: 'valid_status',
|
||||
type: 'radioButton',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const formQuitAgentSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
field: 'userName',
|
||||
label: '用户名',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
readOnly: true,
|
||||
allowClear: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'agentUserName',
|
||||
label: '交接人员',
|
||||
required: true,
|
||||
component: 'JSelectUser',
|
||||
componentProps: {
|
||||
rowKey: 'username',
|
||||
labelKey: 'realname',
|
||||
maxSelectCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'startTime',
|
||||
label: '交接开始时间',
|
||||
component: 'DatePicker',
|
||||
required: true,
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
placeholder: '请选择交接开始时间',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'endTime',
|
||||
label: '交接结束时间',
|
||||
component: 'DatePicker',
|
||||
required: true,
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
placeholder: '请选择交接结束时间',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
label: '状态',
|
||||
component: 'JDictSelectTag',
|
||||
defaultValue: '1',
|
||||
componentProps: {
|
||||
dictCode: 'valid_status',
|
||||
type: 'radioButton',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
//租户用户列表
|
||||
export const userTenantColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
dataIndex: 'username',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
dataIndex: 'realname',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
dataIndex: 'avatar',
|
||||
width: 120,
|
||||
customRender: render.renderAvatar,
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
dataIndex: 'phone',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
width: 150,
|
||||
dataIndex: 'orgCodeTxt',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
width: 80,
|
||||
customRender: ({ text }) => {
|
||||
if (text === '1') {
|
||||
return '正常';
|
||||
} else if (text === '3') {
|
||||
return '审批中';
|
||||
} else {
|
||||
return '已拒绝';
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
//用户租户搜索表单
|
||||
export const userTenantFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '账号',
|
||||
field: 'username',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '名字',
|
||||
field: 'realname',
|
||||
component: 'Input',
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'sex2',
|
||||
placeholder: '请选择性别',
|
||||
stringToNumber: true,
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
];
|
||||
|
||||
export interface UserType {
|
||||
key: number;
|
||||
title: string;
|
||||
component: Component;
|
||||
auth?: string;
|
||||
}
|
||||
|
||||
export const typeList: UserType[] = [
|
||||
{
|
||||
key: 1,
|
||||
title: '员工',
|
||||
component: HealthUserEmployeeEx,
|
||||
auth: 'system:health_user_employee_ex:list',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
title: '专家',
|
||||
component: healthExpert,
|
||||
auth: 'system:consultation:con_doctor:list',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
title: '小助手',
|
||||
component: healthHelper,
|
||||
auth: 'system:consultation:con_helper:list',
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
title: '操作人员',
|
||||
component: healthOperatorEx,
|
||||
auth: 'system:health_operator_ex:list',
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
title: '专业人员',
|
||||
component: healthUserOperatorEx,
|
||||
auth: 'system:health_user_operator_ex:list',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
title: '驻场人员',
|
||||
component: healthUserStationEx,
|
||||
auth: 'system:health_user_station_ex:list',
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
title: '体检医院',
|
||||
component: hospitalDoctor,
|
||||
auth: 'medical:medical_hospital_user:list',
|
||||
},
|
||||
];
|
||||
/**
|
||||
* @Description:处理请求参数
|
||||
* @date 2023/8/21
|
||||
* @param values
|
||||
* @param isUpdate:是否为重新设置密码
|
||||
* */
|
||||
export function dealParams(values, isUpdate = false) {
|
||||
const cloneValues = JSON.parse(JSON.stringify(values));
|
||||
if (cloneValues?.password) {
|
||||
cloneValues.password = encipher(cloneValues.password);
|
||||
}
|
||||
if (isUpdate) {
|
||||
cloneValues.newPassword = encipher(cloneValues.newPassword);
|
||||
cloneValues.newPasswordConfirm = encipher(cloneValues.newPasswordConfirm);
|
||||
}
|
||||
return cloneValues;
|
||||
}
|
||||
|
||||
export function dealPassword(password: string) {
|
||||
if (password) {
|
||||
password = encipher(password);
|
||||
}
|
||||
return password;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<Description @register="register" class="mt-4" />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Description, DescItem, useDescription } from '/@/components/Description/index';
|
||||
const mockData = {
|
||||
username: 'test',
|
||||
nickName: 'VB',
|
||||
age: '123',
|
||||
phone: '15695909xxx',
|
||||
email: '190848757@qq.com',
|
||||
addr: '厦门市思明区',
|
||||
sex: '男',
|
||||
certy: '3504256199xxxxxxxxx',
|
||||
tag: 'orange',
|
||||
};
|
||||
const schema: DescItem[] = [
|
||||
{
|
||||
field: 'username',
|
||||
label: '用户名',
|
||||
},
|
||||
{
|
||||
field: 'nickName',
|
||||
label: '昵称',
|
||||
render: (curVal, data) => {
|
||||
return `${data.username}-${curVal}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'phone',
|
||||
label: '联系电话',
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱',
|
||||
},
|
||||
{
|
||||
field: 'addr',
|
||||
label: '地址',
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
components: { Description },
|
||||
setup() {
|
||||
const [register] = useDescription({
|
||||
title: 'useDescription',
|
||||
data: mockData,
|
||||
schema: schema,
|
||||
});
|
||||
return { mockData, schema, register };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<a-radio-group v-model:value="activeKey" button-style="solid" class="top-selector" @change="changeType">
|
||||
<a-radio-button v-for="t in showList" :key="t.key" :value="t.key">{{ t.title }}</a-radio-button>
|
||||
</a-radio-group>
|
||||
<keep-alive>
|
||||
<component :is="currentComp" />
|
||||
</keep-alive>
|
||||
</template>
|
||||
<script lang="ts" name="system-user" setup>
|
||||
import { ref, shallowRef, unref } from 'vue';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
import { typeList, UserType } from './user.data';
|
||||
|
||||
const { hasPermission } = usePermission();
|
||||
const showList = ref<UserType[]>([]);
|
||||
showList.value = typeList.filter((t) => {
|
||||
if (t.auth) {
|
||||
return hasPermission(t.auth);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const activeKey = ref(unref(showList)[0]?.key || 0);
|
||||
let currentComp = shallowRef<any>(getCurrentComp());
|
||||
function changeType() {
|
||||
currentComp.value = getCurrentComp();
|
||||
}
|
||||
function getCurrentComp() {
|
||||
return unref(showList).find((t) => t.key === unref(activeKey))?.component || '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.top-selector {
|
||||
padding: 10px 10px 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user