update
init
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
centerList = '/health-emergency/emergency/center/list',
|
||||
list = '/health-emergency/emergency/emergencyGrouped/list',
|
||||
save = '/health-emergency/emergency/emergencyGrouped/add',
|
||||
edit = '/health-emergency/emergency/emergencyGrouped/edit',
|
||||
deleteOne = '/health-emergency/emergency/emergencyGrouped/delete',
|
||||
callDelete = '/health-emergency/emergency/emergencyGrouped/callDelete',
|
||||
exportXls = '/health-emergency/api/qimo/exportXls',
|
||||
getCallRecordList = '/health-emergency/emergency/emergencyGrouped/callList',
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取应急中心列表
|
||||
* @param params
|
||||
*/
|
||||
export const getEmergencyList = (params: any) => defHttp.get({ url: Api.centerList, params });
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params: any) => defHttp.get({ url: Api.list, params });
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params: any, handleSuccess: Function) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () =>
|
||||
defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
|
||||
return isUpdate ? defHttp.put({ url: Api.edit, params }) : defHttp.post({ url: Api.save, params });
|
||||
};
|
||||
/**
|
||||
* @description 通话记录列表
|
||||
* @param params
|
||||
*/
|
||||
export const getCallRecordList = (params: any) => defHttp.get({ url: Api.getCallRecordList, params });
|
||||
|
||||
export const exportExcelUrl = (params: any) => defHttp.get({ url: Api.exportXls, params });
|
||||
/**
|
||||
* @description 通话记录删除
|
||||
* @param params
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const callDelete = (params: any, handleSuccess: Function) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () =>
|
||||
defHttp.delete({ url: Api.callDelete, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
}),
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { orgSearchInfoByCode } from '/@/utils/orgSearchInfo';
|
||||
import { getEmergencyList } from '/@/views/consult/agentManagement/agentManagement.api';
|
||||
import { getTimeStr } from '/@/utils/common/compUtils';
|
||||
|
||||
const SeatStatus = {
|
||||
0: '未知',
|
||||
1: '忙碌',
|
||||
2: '小休',
|
||||
3: '正在通话',
|
||||
4: '离线',
|
||||
5: '空闲',
|
||||
};
|
||||
const centerProps = {
|
||||
api: getEmergencyList,
|
||||
params: {
|
||||
pageNo: 1,
|
||||
pageSize: 200,
|
||||
},
|
||||
labelField: 'centerName',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
resultField: 'records',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input?.trim()?.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '坐席工号',
|
||||
dataIndex: 'seatId',
|
||||
},
|
||||
{
|
||||
title: '所属应急中心',
|
||||
dataIndex: 'centerName',
|
||||
},
|
||||
{
|
||||
title: '坐席状态',
|
||||
dataIndex: 'seatStatus',
|
||||
customRender: ({ text }) => {
|
||||
return SeatStatus[text] || '';
|
||||
},
|
||||
},
|
||||
];
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'centerId',
|
||||
label: '所属应急中心',
|
||||
component: 'ApiSelect',
|
||||
componentProps: () => {
|
||||
return centerProps;
|
||||
},
|
||||
},
|
||||
];
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'seatId',
|
||||
label: '坐席工号',
|
||||
component: 'InputNumber',
|
||||
componentProps: () => {
|
||||
return {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
min: 0,
|
||||
};
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'centerId',
|
||||
label: '所属应急中心',
|
||||
component: 'ApiSelect',
|
||||
required: true,
|
||||
componentProps: () => {
|
||||
return {
|
||||
...centerProps,
|
||||
getPopupContainer: () => document.body,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
label: '隐藏id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
export const recordColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '单位名称',
|
||||
dataIndex: 'orgName',
|
||||
fixed: 'left',
|
||||
customRender: ({ text }) => {
|
||||
if (!text) return '未知';
|
||||
return text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '部门名称',
|
||||
dataIndex: 'deptName',
|
||||
fixed: 'left',
|
||||
customRender: ({ text }) => {
|
||||
if (!text) return '未知';
|
||||
return text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '员工姓名',
|
||||
dataIndex: 'realName',
|
||||
fixed: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
dataIndex: 'sex_dictText',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '呼叫中心',
|
||||
dataIndex: 'centerName',
|
||||
},
|
||||
{
|
||||
title: '坐席工号',
|
||||
dataIndex: 'seatId',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '电话',
|
||||
dataIndex: 'phone',
|
||||
},
|
||||
{
|
||||
title: '通话时长',
|
||||
dataIndex: 'callDuration',
|
||||
customRender: ({ text }) => {
|
||||
return getTimeStr(text);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '通话时间',
|
||||
dataIndex: 'callTime',
|
||||
},
|
||||
];
|
||||
export const recordSearchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'realName',
|
||||
label: '员工姓名',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'centerId',
|
||||
label: '呼叫中心',
|
||||
component: 'ApiSelect',
|
||||
componentProps: () => {
|
||||
return {
|
||||
...centerProps,
|
||||
getPopupContainer: () => document.body,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'seatId',
|
||||
label: '坐席工号',
|
||||
component: 'Input',
|
||||
},
|
||||
...orgSearchInfoByCode('unit', 'department', 'orgCode'),
|
||||
];
|
||||
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined" v-auth="'emergency:emergency_grouped:add'">
|
||||
新增
|
||||
</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<CallRecordsModal @register="registerModal"></CallRecordsModal>
|
||||
<AddaAgentManagementModal @register="registerAddaAgentManagement" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns, searchFormSchema } from '/@/views/consult/agentManagement/agentManagement.data';
|
||||
import { deleteOne, list } from '/@/views/consult/agentManagement/agentManagement.api';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import CallRecordsModal from '/@/views/consult/agentManagement/components/callRecordsModal.vue';
|
||||
import AddaAgentManagementModal from '/@/views/consult/agentManagement/components/addaAgentManagementModal.vue';
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [registerAddaAgentManagement, { openModal: openAddModal }] = useModal();
|
||||
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '坐席管理-分组管理',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
useSearchForm: true,
|
||||
actionColumn: {
|
||||
width: 200,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload }] = tableContext;
|
||||
function handleAdd() {
|
||||
openAddModal(true, {
|
||||
type: '新增',
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
function handleEdit(record: Recordable) {
|
||||
openAddModal(true, {
|
||||
type: '编辑',
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
function callRecords(record: Recordable) {
|
||||
openModal(true, {
|
||||
seatId: record.seatId,
|
||||
});
|
||||
}
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '通话记录',
|
||||
onClick: callRecords.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'emergency:emergency_grouped:edit',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'emergency:emergency_grouped:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<BasicTable @register="registerTable" size="small">
|
||||
<template #tableTitle>
|
||||
<a-button-group>
|
||||
<a-button v-auth="'emergency:callLog:exportXls'" type="primary" preIcon="ant-design:export-outlined" @click="downloadExcelBtn"
|
||||
>导出</a-button
|
||||
>
|
||||
<a-button v-auth="'emergency:callLog:exportXls'" type="primary" preIcon="ant-design:search-outlined" @click="handleExportList">
|
||||
查看导出任务
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<ExportUtil task-code="emergencyCallLogCode" @register="registerExport" drawer-title="通话记录导出" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { callDelete, exportExcelUrl, getCallRecordList } from '/@/views/consult/agentManagement/agentManagement.api';
|
||||
import { recordColumns, recordSearchFormSchema } from '/@/views/consult/agentManagement/agentManagement.data';
|
||||
import ExportUtil from '/@/utils/export/exportUtil.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const [registerExport, { openDrawer }] = useDrawer();
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '坐席管理-通话记录列表',
|
||||
api: getCallRecordList,
|
||||
columns: recordColumns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
labelWidth: 80,
|
||||
schemas: recordSearchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToTime: [],
|
||||
actionColOptions: {
|
||||
style: {
|
||||
marginLeft: '80px',
|
||||
},
|
||||
},
|
||||
},
|
||||
actionColumn: {
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload, getForm }] = tableContext;
|
||||
function downloadExcelBtn() {
|
||||
exportExcelUrl(getForm().getFieldsValue());
|
||||
}
|
||||
function handleExportList() {
|
||||
openDrawer(true);
|
||||
}
|
||||
function handleDelete(record: Recordable) {
|
||||
callDelete({ id: record.id }, reload);
|
||||
}
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :showFooter="showFooter" :title="title" :width="600" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '/@/views/consult/agentManagement/agentManagement.data';
|
||||
import { saveOrUpdate } from '/@/views/consult/agentManagement/agentManagement.api';
|
||||
import { useModalInner, BasicModal } from '/@/components/Modal';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const showFooter = ref(true);
|
||||
//设置标题
|
||||
const title = ref('');
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
labelWidth: 120,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ 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 setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<BasicModal z-index="999" v-bind="$attrs" @register="registerModal" destroyOnClose :title="'通话记录'" :width="1100">
|
||||
<div style="height: 70vh">
|
||||
<BasicTable @register="registerTable" size="small">
|
||||
<template #tableTitle>
|
||||
<a-button-group>
|
||||
<a-button v-auth="'emergency:callLog:exportXls'" type="primary" preIcon="ant-design:export-outlined" @click="downloadExcelBtn"
|
||||
>导出</a-button
|
||||
>
|
||||
<a-button
|
||||
v-auth="'emergency:callLog:exportXls'"
|
||||
type="primary"
|
||||
preIcon="ant-design:search-outlined"
|
||||
@click="handleExportList"
|
||||
>
|
||||
查看导出任务
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</BasicModal>
|
||||
<ExportUtil z-index="1099" task-code="emergencyCallLogCode" @register="registerExport" drawer-title="通话记录导出" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { exportExcelUrl, getCallRecordList } from '/@/views/consult/agentManagement/agentManagement.api';
|
||||
import { recordColumns, recordSearchFormSchema } from '/@/views/consult/agentManagement/agentManagement.data';
|
||||
import ExportUtil from '/@/utils/export/exportUtil.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
const [registerExport, { openDrawer }] = useDrawer();
|
||||
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const seatId = ref('');
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
seatId.value = data.seatId;
|
||||
});
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '分组管理-通话记录',
|
||||
api: getCallRecordList,
|
||||
columns: recordColumns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
labelWidth: 80,
|
||||
schemas: recordSearchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToTime: [],
|
||||
baseColProps: {
|
||||
xs: 12, // <576px
|
||||
sm: 12, // ≥576px
|
||||
md: 12, // ≥768px
|
||||
lg: 8, // ≥992px
|
||||
xl: 8, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
},
|
||||
actionColOptions: {
|
||||
offset: 0,
|
||||
span: 24,
|
||||
xs: 12, // <576px
|
||||
sm: 12, // ≥576px
|
||||
md: 12, // ≥768px
|
||||
lg: 8, // ≥992px
|
||||
xl: 8, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
},
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
params['seatId'] = seatId.value;
|
||||
return params;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload, getForm }] = tableContext;
|
||||
function downloadExcelBtn() {
|
||||
exportExcelUrl({ ...getForm().getFieldsValue(), seatId: seatId.value });
|
||||
}
|
||||
function handleExportList() {
|
||||
openDrawer(true);
|
||||
}
|
||||
function handleDelete(record: Recordable) {}
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm">
|
||||
<template #itemOptions="{}">
|
||||
<a-form :model="innerForm" ref="optionForm">
|
||||
<a-form-item
|
||||
v-for="(item, i) in innerForm.option"
|
||||
:key="i"
|
||||
class="option-item"
|
||||
:name="['option', i, 'label']"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入选项',
|
||||
trigger: 'change',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-input v-model:value="item.label" @blur="inputBlur(item)" />
|
||||
<MinusCircleOutlined class="delete-button" @click="removeDomain(item)" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-button class="add-button" @click="addDomain">
|
||||
<PlusOutlined />
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</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 { formSchema } from '../conHealthInfo.data';
|
||||
import { saveOrUpdate } from '../conHealthInfo.api';
|
||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const optionForm = ref();
|
||||
|
||||
const isUpdate = ref(true);
|
||||
const innerForm = ref({
|
||||
option: [],
|
||||
});
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, 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;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
let options = JSON.parse(data.record.itemOptions) || {};
|
||||
const optionsArr = [];
|
||||
if (Object.keys(options).length) {
|
||||
for (const key in options) {
|
||||
optionsArr.push({ label: key, value: options[key] });
|
||||
}
|
||||
}
|
||||
innerForm.value.option = optionsArr;
|
||||
}
|
||||
// //表单赋值
|
||||
// await setFieldsValue({
|
||||
// ...data.record,
|
||||
// });
|
||||
await clearValidate();
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
function addDomain() {
|
||||
let row = { label: '', value: '0' };
|
||||
innerForm.value.option.push(row);
|
||||
}
|
||||
function inputBlur(item) {
|
||||
if (!item.value) {
|
||||
item.value = '0';
|
||||
}
|
||||
}
|
||||
function removeDomain(item) {
|
||||
let index = innerForm.value.option.indexOf(item);
|
||||
if (index !== -1) {
|
||||
innerForm.value.option.splice(index, 1);
|
||||
}
|
||||
}
|
||||
function clearData() {
|
||||
innerForm.value.option = [];
|
||||
}
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
let newValues = await optionForm.value.validate();
|
||||
let { itemType } = values;
|
||||
let itemOptions = {};
|
||||
if (['1', '2'].includes(itemType)) {
|
||||
const obj = {};
|
||||
innerForm.value.option.map((item: any) => {
|
||||
if (!item.value) item.value = '0';
|
||||
obj[item.label] = item.value;
|
||||
});
|
||||
itemOptions = obj;
|
||||
}
|
||||
const params = {
|
||||
...values,
|
||||
itemOptions: JSON.stringify(itemOptions),
|
||||
};
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(params, isUpdate.value);
|
||||
clearData();
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
:deep(.option-item) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 5px 0;
|
||||
.ant-form-item-control-input-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.delete-button {
|
||||
margin-left: 16px;
|
||||
color: red;
|
||||
}
|
||||
.add-button {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,80 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conHealthInfo/list',
|
||||
save = '/health-consultation/consultation/conHealthInfo/add',
|
||||
edit = '/health-consultation/consultation/conHealthInfo/edit',
|
||||
deleteOne = '/health-consultation/consultation/conHealthInfo/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conHealthInfo/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/conHealthInfo/importExcel',
|
||||
exportXls = '/health-consultation/consultation/conHealthInfo/exportXls',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () =>
|
||||
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 url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
const itemType = {
|
||||
'1': '单选',
|
||||
'2': '多选',
|
||||
'3': '文本',
|
||||
};
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '基本项',
|
||||
align: 'center',
|
||||
dataIndex: 'itemProblem',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status',
|
||||
customRender: ({ text }) => (text && text == '1' ? '启用' : '禁用'),
|
||||
},
|
||||
{
|
||||
title: '问题类型',
|
||||
align: 'center',
|
||||
dataIndex: 'itemType',
|
||||
customRender: ({ text }) => (text && itemType[text]) || '',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
align: 'center',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '问题名称',
|
||||
field: 'itemProblem',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '问题类型',
|
||||
field: 'itemType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '单选',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '多选',
|
||||
value: '2',
|
||||
},
|
||||
{
|
||||
label: '文本',
|
||||
value: '3',
|
||||
},
|
||||
],
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
|
||||
{
|
||||
label: '选项',
|
||||
field: 'itemOptions',
|
||||
component: 'JDictSelectTag',
|
||||
slot: 'itemOptions',
|
||||
show: ({ values }) => {
|
||||
return ['1', '2'].includes(values.itemType);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '启用',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '禁用',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<div class="con-health-info-list">
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="auth.add" type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button v-auth="auth.deleteBatch" @click="batchHandleDelete" type="primary" preIcon="ant-design:delete-outlined">批量删除</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<conHealthInfoModal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conHealthInfo" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import conHealthInfoModal from './components/conHealthInfoModal.vue';
|
||||
import { columns, searchFormSchema } from './conHealthInfo.data';
|
||||
import { list, deleteOne, batchDelete } from './conHealthInfo.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
const auth = {
|
||||
add: 'consultation:con_health_info:add',
|
||||
edit: 'consultation:con_health_info:edit',
|
||||
deleteOne: 'consultation:con_health_info:delete',
|
||||
deleteBatch: 'consultation:con_health_info:deleteBatch',
|
||||
};
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '健康信息',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
|
||||
useSearchForm: true,
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
await deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* @Description:批量删除
|
||||
* @date 2023/6/20
|
||||
* @param:
|
||||
*/
|
||||
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: auth.edit,
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: auth.deleteOne,
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.con-health-info-list {
|
||||
padding: 10px;
|
||||
}
|
||||
:deep(.ant-popover-buttons) {
|
||||
display: flex !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,259 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:showFooter="false"
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
:width="1200"
|
||||
:maskClosable="false"
|
||||
@ok="handleSubmit"
|
||||
@close="resetData"
|
||||
>
|
||||
<a-spin :spinning="spinning">
|
||||
<div class="detail-container">
|
||||
<a-tabs v-model:activeKey="state.activeKey">
|
||||
<a-tab-pane key="1" tab="个人档案">
|
||||
<CommonDesc :key="updateRes" title="基本信息" :column="3" :descList="descList1" :desc-res="resList.resList1" />
|
||||
<div>
|
||||
<div class="ant-descriptions-header ant-descriptions-title">紧急联系人</div>
|
||||
<div class="person-list">
|
||||
<a-list :data-source="resList.sysUserEmergencyContactList" bordered>
|
||||
<template #header>
|
||||
<a-row>
|
||||
<a-col flex="4" align="center">姓名</a-col>
|
||||
<a-col flex="4" align="center">与员工关系</a-col>
|
||||
<a-col flex="4" align="center">联系电话</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<template #renderItem="{ item }">
|
||||
<a-row class="row-item">
|
||||
<a-col flex="4" align="center">{{ item?.name }} </a-col>
|
||||
<a-col flex="4" align="center">{{ item?.['familyRelation_dictText'] }}</a-col>
|
||||
<a-col flex="4" align="center">{{ item?.['phone'] }}</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-list>
|
||||
</div>
|
||||
</div>
|
||||
<CommonDesc :key="updateRes" title="健康信息" :column="3" :descList="resList.descList3" :desc-res="resList.resList3" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="家庭档案">
|
||||
<template v-if="resList.conFamilyMembersVOList.length">
|
||||
<div v-for="(item, i) in resList.conFamilyMembersVOList" :key="i">
|
||||
<div class="family-name">{{ i + 1 }}. {{ item?.['conFamilyMembers']?.name || '' }}</div>
|
||||
<CommonDesc title="基本信息" :column="4" :descList="familyInfo" :desc-res="item['conFamilyMembers']" />
|
||||
<CommonDesc title="健康信息" :column="4" :descList="dealFamilyHealthInfo(item.map)" :desc-res="item.map" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-empty :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</a-spin>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import CommonDesc from '/@/views/emergency/outburst/order/components/commonDesc.vue';
|
||||
import { descList1, tableColumns, cardColumns2, familyInfo } from '../conHealthInfo.data';
|
||||
import { DescList, State, TableState } from '../types';
|
||||
import { personBasicInfo, queryById } from '../conHealthInfo.api';
|
||||
import { Empty } from 'ant-design-vue';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const updateRes = ref(true);
|
||||
const spinning = ref<boolean>(true);
|
||||
const changeSpinning = () => {
|
||||
spinning.value = !spinning.value;
|
||||
};
|
||||
//设置标题
|
||||
const title = '详情';
|
||||
const state = ref<State>({
|
||||
activeKey: '1',
|
||||
});
|
||||
const tableState = ref<TableState>({
|
||||
dataSource: [],
|
||||
columns: tableColumns,
|
||||
cardSource: [],
|
||||
cardColumns2: cardColumns2,
|
||||
});
|
||||
interface ResList {
|
||||
resList1: any;
|
||||
resList3: any;
|
||||
descList3: DescList[];
|
||||
conFamilyMembersVOList: any[];
|
||||
sysUserEmergencyContactList: any[];
|
||||
}
|
||||
let resList: ResList = reactive({
|
||||
resList1: {},
|
||||
descList3: [],
|
||||
resList3: {},
|
||||
conFamilyMembersVOList: [],
|
||||
sysUserEmergencyContactList: [],
|
||||
});
|
||||
const record = ref();
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
const { userId, id } = data.record || {};
|
||||
record.value = data.record;
|
||||
getInitData(id, userId);
|
||||
// 隐藏底部
|
||||
setDrawerProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @Description:处理个人基本信息数据
|
||||
* @date 2023/6/21
|
||||
*/
|
||||
function dealBasicInfo({ res1, res2 }) {
|
||||
let { extension, departTree } = res2 || {};
|
||||
nextTick(() => {
|
||||
resList.resList1 = {
|
||||
empSysno: res2?.workNo || '',
|
||||
realname: res2?.realname,
|
||||
age: res1?.conFamilyMembers?.age || record.value?.age || '',
|
||||
sex_dictText: res2?.sex_dictText,
|
||||
idCard: res2?.idCard,
|
||||
phone: res2?.phone,
|
||||
height: res1?.conFamilyMembers?.height,
|
||||
weight: res1?.conFamilyMembers?.weight,
|
||||
depart: (departTree && departTree[0]) || '',
|
||||
empJob_dictText: extension?.empJob_dictText,
|
||||
empPosition: extension?.empPosition,
|
||||
empLevel_dictText: extension?.empLevel_dictText || '',
|
||||
empPolitical_dictText: extension?.empPolitical_dictText,
|
||||
empDegree_dictText: extension?.empDegree_dictText,
|
||||
empMarriage_dictText: extension?.empMarriage_dictText,
|
||||
empNativeplace: extension?.empNativeplace,
|
||||
empWorktime: extension?.empWorktime,
|
||||
empType_dictText: extension?.empType_dictText,
|
||||
workSpace: extension?.workSpace,
|
||||
empStatus_dictText: extension?.empStatus_dictText,
|
||||
liveSpace: extension?.liveSpace,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description:处理个人健康信息
|
||||
* @date 2023/6/21
|
||||
*/
|
||||
function dealPersonHealInfo(mapObj) {
|
||||
let descList3: DescList[] = [];
|
||||
if (JSON.stringify(mapObj) !== '{}') {
|
||||
for (const key in mapObj) {
|
||||
descList3.push({ label: key, key });
|
||||
}
|
||||
resList.descList3 = descList3;
|
||||
resList.resList3 = mapObj;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Description:处理家庭健康信息
|
||||
* @date 2023/6/21
|
||||
* @param mapObj 数据
|
||||
*/
|
||||
function dealFamilyHealthInfo(mapObj) {
|
||||
let descList: any[] = [];
|
||||
if (JSON.stringify(mapObj) !== '{}') {
|
||||
for (const key in mapObj) {
|
||||
descList.push({ label: key, key });
|
||||
}
|
||||
}
|
||||
return descList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description:获取详情数据
|
||||
* @date 2023/6/26
|
||||
* @param id
|
||||
* @param userId
|
||||
* @return {res1,res2} res1:家庭档案、个人部分基本信息;res2:个人档案
|
||||
*/
|
||||
function getInitData(id: string, userId: string): void {
|
||||
let r1 = queryById({ userId });
|
||||
let r2 = personBasicInfo({ id: userId });
|
||||
Promise.all([r1, r2])
|
||||
.then(([res1, res2]) => {
|
||||
const { map: mapObj } = res1 || {};
|
||||
dealPersonHealInfo(mapObj);
|
||||
dealBasicInfo({ res1, res2 });
|
||||
resList.conFamilyMembersVOList = res1?.conFamilyMembersVOList || [];
|
||||
resList.sysUserEmergencyContactList = res1?.sysUserEmergencyContactList || [];
|
||||
updateRes.value = !updateRes.value;
|
||||
changeSpinning();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log('e', e);
|
||||
changeSpinning();
|
||||
});
|
||||
}
|
||||
|
||||
function resetData() {
|
||||
state.value.activeKey = '1';
|
||||
spinning.value = true;
|
||||
resList = {
|
||||
resList1: {},
|
||||
descList3: [],
|
||||
resList3: {},
|
||||
conFamilyMembersVOList: [],
|
||||
sysUserEmergencyContactList: [],
|
||||
};
|
||||
tableState.value = {
|
||||
dataSource: [],
|
||||
columns: tableColumns,
|
||||
cardSource: [],
|
||||
cardColumns2: cardColumns2,
|
||||
};
|
||||
}
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.detail-container {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.ant-descriptions-header) {
|
||||
margin: 16px 0 !important;
|
||||
}
|
||||
|
||||
.person-list {
|
||||
width: 50%;
|
||||
}
|
||||
.family-name {
|
||||
color: #000;
|
||||
font-weight: 700;
|
||||
line-height: 1.5;
|
||||
font-size: 16px;
|
||||
}
|
||||
:deep(.ant-descriptions-title) {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.row-item {
|
||||
line-height: 2.4;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,79 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conHealthInfoAnswer/list',
|
||||
save = '/health-consultation/consultation/conHealthInfo/add',
|
||||
edit = '/health-consultation/consultation/conHealthInfo/edit',
|
||||
deleteOne = '/health-consultation/consultation/conHealthInfo/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conHealthInfo/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/conHealthInfo/importExcel',
|
||||
exportXls = '/health-consultation/consultation/conHealthInfo/exportXls',
|
||||
queryById = '/health-consultation/consultation/conHealthInfoAnswer/queryByUserId',
|
||||
// personBasicInfo = '/sys/healthUserEmployeeEx/queryById',
|
||||
personBasicInfo = '/sys/healthUserEmployeeEx/queryArchivesById', //替换后
|
||||
}
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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 url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* @Description:获取详情信息
|
||||
* @date 2023/6/21
|
||||
* @param:{id}
|
||||
*/
|
||||
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
/**
|
||||
* @Description:个人基本信息
|
||||
* @date 2023/6/21
|
||||
* @param:{id}
|
||||
*/
|
||||
export const personBasicInfo = (params) => defHttp.get({ url: Api.personBasicInfo, params });
|
||||
@@ -0,0 +1,453 @@
|
||||
import { getSecondaryDepartmentList, getThirdDepartmentList } from '/@/views/system/user/user.api';
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { h } from 'vue';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
import { Image } from 'ant-design-vue';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { DescList, TableColumns } from '/@/views/consult/archives/consult/types';
|
||||
import { useDepartment } from '/@/utils/auth/formAuth';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
customRender: ({ index }) => {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
align: 'center',
|
||||
dataIndex: 'avatar',
|
||||
width: 100,
|
||||
customRender: ({ text, record }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getFamaleDefaultImage(record.sex),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '员工姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'fromName',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
align: 'center',
|
||||
dataIndex: 'sex',
|
||||
width: 60,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'gender');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
align: 'center',
|
||||
dataIndex: 'age',
|
||||
width: 60,
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
align: 'center',
|
||||
dataIndex: 'secondDepartName',
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
align: 'center',
|
||||
dataIndex: 'thirdDepartName',
|
||||
},
|
||||
{
|
||||
title: '身份证',
|
||||
align: 'center',
|
||||
dataIndex: 'idCard',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
align: 'center',
|
||||
dataIndex: 'phone',
|
||||
},
|
||||
{
|
||||
title: '员工编号', // 原来为工号
|
||||
align: 'center',
|
||||
dataIndex: 'workNo',
|
||||
},
|
||||
{
|
||||
title: '家庭成员',
|
||||
align: 'center',
|
||||
dataIndex: 'familyNum',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '员工姓名',
|
||||
field: 'fromName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '单位',
|
||||
field: 'secondDepartId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel, schema }) => {
|
||||
const { secondSelectValue, secondSelectDisabled } = useDepartment({ schema, key: 'id' });
|
||||
secondSelectValue();
|
||||
return {
|
||||
api: getSecondaryDepartmentList,
|
||||
resultField: 'list',
|
||||
labelField: 'departName',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
onChange: (val) => {
|
||||
if (val) {
|
||||
formModel.thirdDepartId = '';
|
||||
if (formModel.hasOwnProperty('thirdDepartId')) {
|
||||
formModel.thirdDepartId = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
onDeselect: () => {
|
||||
formModel.secondDepartId = '';
|
||||
if (formModel.hasOwnProperty('thirdDepartId')) {
|
||||
formModel.thirdDepartId = '';
|
||||
}
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
disabled: secondSelectDisabled,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '部门',
|
||||
field: 'thirdDepartId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel, schema }) => {
|
||||
const { thirdSelectValue, thirdSelectDisabled } = useDepartment({ schema, key: 'id' });
|
||||
thirdSelectValue();
|
||||
return {
|
||||
api: getThirdDepartmentList,
|
||||
resultField: 'list',
|
||||
labelField: 'departName',
|
||||
params: {
|
||||
secondDepartId: getSecond(formModel),
|
||||
},
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
onFocus: () => {
|
||||
if (!formModel.secondDepartId) {
|
||||
return createMessage.warn('请先选择单位!');
|
||||
}
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
disabled: thirdSelectDisabled,
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '模板id',
|
||||
field: 'templateId',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '区域[1生活习惯,2身体情况]',
|
||||
field: 'itemArea',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '问题名称',
|
||||
field: 'itemProblem',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '问题类型[1单选,2多选,3文本,4单选加文本]',
|
||||
field: 'itemType',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '选项',
|
||||
field: 'itemOptions',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '状态(1-激活,2-锁定)',
|
||||
field: 'status',
|
||||
component: 'Input',
|
||||
dynamicRules: () => {
|
||||
return [{ required: true, message: '请输入状态(1-激活,2-锁定)!' }];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '删除状态(0-正常,1-已删除)',
|
||||
field: 'delFlag',
|
||||
component: 'Input',
|
||||
dynamicRules: () => {
|
||||
return [{ required: true, message: '请输入删除状态(0-正常,1-已删除)!' }];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
field: 'memo',
|
||||
component: 'Input',
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
// 个人档案
|
||||
// 1.基本信息
|
||||
export const descList1: DescList[] = [
|
||||
{
|
||||
label: '员工编号',
|
||||
key: 'empSysno',
|
||||
spanNumber: 1,
|
||||
},
|
||||
{
|
||||
label: '员工姓名',
|
||||
key: 'realname',
|
||||
spanNumber: 1,
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
key: 'sex_dictText',
|
||||
spanNumber: 1,
|
||||
},
|
||||
{
|
||||
label: '年龄',
|
||||
key: 'age',
|
||||
},
|
||||
{
|
||||
label: '身份证',
|
||||
key: 'idCard',
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
key: 'phone',
|
||||
},
|
||||
{
|
||||
label: '身高(cm)',
|
||||
key: 'height',
|
||||
},
|
||||
{
|
||||
label: '体重(kg)',
|
||||
key: 'weight',
|
||||
},
|
||||
{
|
||||
label: '所属公司',
|
||||
key: 'depart',
|
||||
},
|
||||
{
|
||||
label: '员工职务',
|
||||
key: 'empJob_dictText',
|
||||
},
|
||||
{
|
||||
label: '员工职位',
|
||||
key: 'empPosition',
|
||||
},
|
||||
{
|
||||
label: '行政级别',
|
||||
key: 'empLevel_dictText',
|
||||
},
|
||||
{
|
||||
label: '政治面貌',
|
||||
key: 'empPolitical_dictText',
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
key: 'empDegree_dictText',
|
||||
},
|
||||
{
|
||||
label: '婚姻状况',
|
||||
key: 'empMarriage_dictText',
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
key: 'empNativeplace',
|
||||
},
|
||||
{
|
||||
label: '入职时间',
|
||||
key: 'empWorktime',
|
||||
},
|
||||
{
|
||||
label: '用工形式',
|
||||
key: 'empType_dictText',
|
||||
},
|
||||
|
||||
{
|
||||
label: '员工状态',
|
||||
key: 'empStatus_dictText',
|
||||
},
|
||||
{
|
||||
label: '居住地点',
|
||||
key: 'liveSpace',
|
||||
},
|
||||
{
|
||||
label: '工作地点',
|
||||
key: 'workSpace',
|
||||
},
|
||||
];
|
||||
// 3.健康信息
|
||||
export const descList3: DescList[] = [
|
||||
{
|
||||
label: '疾病史',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '家族史',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '既往史',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '过敏史',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '手术史',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '肝功能',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '肾功能',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '生活习惯',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '烟酒习惯',
|
||||
key: '',
|
||||
},
|
||||
{
|
||||
label: '用药史',
|
||||
key: '',
|
||||
},
|
||||
];
|
||||
// 健康记录
|
||||
export const tableColumns: TableColumns[] = [
|
||||
{
|
||||
title: '日期',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '诊断',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '机构',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '医生',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
];
|
||||
// 就诊卡号
|
||||
export const cardColumns2: TableColumns[] = [
|
||||
{
|
||||
title: '医院',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '就诊卡号',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
];
|
||||
// 家庭成员信息
|
||||
export const familyInfo: DescList[] = [
|
||||
{
|
||||
label: '与员工关系',
|
||||
key: 'familyRelation_dictText',
|
||||
},
|
||||
{
|
||||
label: '性别',
|
||||
key: 'gender',
|
||||
render: (text) => {
|
||||
if (!text) return '';
|
||||
return text == '1' ? '女' : text == '2' ? '男' : '';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '年龄',
|
||||
key: 'age',
|
||||
},
|
||||
|
||||
// {
|
||||
// label: '所处城市',
|
||||
// key: 'address',
|
||||
// },
|
||||
// {
|
||||
// label: '身份证',
|
||||
// key: 'idCard',
|
||||
// },
|
||||
{
|
||||
label: '身高(cm)',
|
||||
key: 'height',
|
||||
},
|
||||
{
|
||||
label: '体重(kg)',
|
||||
key: 'weight',
|
||||
},
|
||||
];
|
||||
const getSecond = (formModel) => {
|
||||
return formModel.hasOwnProperty('secondDepartId') && formModel.secondDepartId !== '' && formModel.secondDepartId !== undefined
|
||||
? formModel.secondDepartId
|
||||
: 'dw&*^^';
|
||||
};
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable">
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<ConHealthInfoDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConHealthInfoDrawer from './components/conHealthInfoDrawer.vue';
|
||||
import { columns, searchFormSchema } from './conHealthInfo.data';
|
||||
import { list } from './conHealthInfo.api';
|
||||
//注册Drawer
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '咨询档案',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
},
|
||||
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }] = tableContext;
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,27 @@
|
||||
interface Fn<T = any, R = T> {
|
||||
(...arg: T[]): R;
|
||||
}
|
||||
export interface TableColumns {
|
||||
title: string;
|
||||
dataIndex: string;
|
||||
key: string;
|
||||
}
|
||||
export interface DescList {
|
||||
label: string;
|
||||
key: string;
|
||||
slot?: string;
|
||||
render?: Fn;
|
||||
spanNumber?: string | number;
|
||||
}
|
||||
export interface State {
|
||||
activeKey: string;
|
||||
}
|
||||
interface DataSource {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface TableState {
|
||||
dataSource: DataSource[];
|
||||
columns: TableColumns[];
|
||||
cardSource: DataSource[];
|
||||
cardColumns2: TableColumns[];
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conKnowledge/list',
|
||||
save = '/health-consultation/consultation/conKnowledge/add',
|
||||
edit = '/health-consultation/consultation/conKnowledge/edit',
|
||||
deleteOne = '/health-consultation/consultation/conKnowledge/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conKnowledge/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/conKnowledge/importExcel',
|
||||
exportXls = '/health-consultation/consultation/conKnowledge/exportXls',
|
||||
knowledgeType = '/health-consultation/consultation/conKnowledgeCategory/getCategoryAll',
|
||||
tfTopKnow = '/health-consultation/consultation/conKnowledge/tfTopKnow',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取知识库分类
|
||||
* @param params
|
||||
*/
|
||||
export const getKnowledge = (params) => {
|
||||
return defHttp.get({ url: Api.knowledgeType, params });
|
||||
};
|
||||
|
||||
export const tfTopKnowApi = (params) => {
|
||||
return defHttp.get({ url: Api.tfTopKnow, params });
|
||||
};
|
||||
@@ -0,0 +1,200 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { h } from 'vue';
|
||||
import { Image } from 'ant-design-vue';
|
||||
import { getDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
import { getKnowledge } from '/@/views/consult/conKnowledge/ConKnowledge.api';
|
||||
//列表数据
|
||||
// @ts-ignore
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '文章标题',
|
||||
align: 'center',
|
||||
dataIndex: 'knowTitle',
|
||||
},
|
||||
{
|
||||
title: '知识类型',
|
||||
align: 'center',
|
||||
dataIndex: 'knowType',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'know_type');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '知识分类',
|
||||
align: 'center',
|
||||
dataIndex: 'knowClassName',
|
||||
},
|
||||
{
|
||||
title: '知识图片',
|
||||
align: 'center',
|
||||
dataIndex: 'knowPic',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getDefaultImage(),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '已学习次数',
|
||||
// align: 'center',
|
||||
// dataIndex: 'knowLookNumber',
|
||||
// },
|
||||
{
|
||||
title: '是否推荐',
|
||||
align: 'center',
|
||||
dataIndex: 'tfRecommend',
|
||||
customRender: ({ text }) => (text === '0' ? '否' : '是'),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'freeze_status');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
align: 'center',
|
||||
dataIndex: 'sort',
|
||||
width: '70px',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '标题',
|
||||
field: 'knowTitle',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '知识标题',
|
||||
field: 'knowTitle',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '知识类型',
|
||||
field: 'knowType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
// dictCode: 'know_type',
|
||||
options: [
|
||||
{
|
||||
label: '图文',
|
||||
value: '0',
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultValue: '0',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '知识图片',
|
||||
field: 'knowPic',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
fileMax: 1,
|
||||
},
|
||||
rules: [{ required: true, message: '请选择知识图片' }],
|
||||
},
|
||||
{
|
||||
label: '知识分类',
|
||||
field: 'knowClass',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getKnowledge,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
// {
|
||||
// label: '已学习次数',
|
||||
// field: 'knowLookNumber',
|
||||
// component: 'InputNumber',
|
||||
// required: true,
|
||||
// },
|
||||
{
|
||||
label: '是否推荐',
|
||||
field: 'tfRecommend',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
value: '1',
|
||||
label: '是',
|
||||
},
|
||||
{
|
||||
value: '0',
|
||||
label: '否',
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
type: 'radio',
|
||||
dictCode: 'freeze_status',
|
||||
},
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '知识内容',
|
||||
field: 'knowContent',
|
||||
component: 'JEditor',
|
||||
componentProps: {
|
||||
showImageUpload: true,
|
||||
},
|
||||
rules: [{ required: true, message: '请输入知识内容' }],
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'Input',
|
||||
rules: [{ required: true, message: '请输入排序' }],
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-button>
|
||||
<a-button type="primary" @click="batchHandleDelete" preIcon="ant-design:delete-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-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)" />
|
||||
</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>
|
||||
<!-- 表单区域 -->
|
||||
<ConKnowledgeModal @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="conKnowledge-conKnowledge" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConKnowledgeModal from './components/ConKnowledgeModal.vue';
|
||||
import { columns, searchFormSchema } from './ConKnowledge.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, tfTopKnowApi } from './ConKnowledge.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
//注册Drawer
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '知识库',
|
||||
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,
|
||||
type: '新增',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
type: '编辑',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openDrawer(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) {
|
||||
message.warning('未选中任何数据');
|
||||
return;
|
||||
}
|
||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
function handleTop(record: object) {
|
||||
tfTopKnowApi({ id: record.id }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: record.tfTop === '1' ? '取消置顶' : '置顶',
|
||||
onClick: handleTop.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<BasicDrawer v-bind="$attrs" @register="registerDrawer" destroyOnClose :showFooter="showFooter" :title="title" :width="800" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../ConKnowledge.data';
|
||||
import { saveOrUpdate } from '../ConKnowledge.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const showFooter = ref<boolean>(true);
|
||||
//设置标题
|
||||
const title = ref(String);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = 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 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,81 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conKnowledgeCategory/list',
|
||||
save = '/health-consultation/consultation/conKnowledgeCategory/add',
|
||||
edit = '/health-consultation/consultation/conKnowledgeCategory/edit',
|
||||
deleteOne = '/health-consultation/consultation/conKnowledgeCategory/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conKnowledgeCategory/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/conKnowledgeCategory/importExcel',
|
||||
exportXls = '/health-consultation/consultation/conKnowledgeCategory/exportXls',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '分类名称',
|
||||
align: 'center',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '分类介绍',
|
||||
align: 'center',
|
||||
dataIndex: 'memo',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '分类名称',
|
||||
field: 'name',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '分类名称',
|
||||
field: 'name',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
// {
|
||||
// label: 'sort',
|
||||
// field: 'sort',
|
||||
// component: 'Input',
|
||||
// },
|
||||
// {
|
||||
// label: '状态(1-正常,2-冻结)',
|
||||
// field: 'status',
|
||||
// component: 'Input',
|
||||
// dynamicRules: ({ model, schema }) => {
|
||||
// return [{ required: true, message: '请输入状态(1-正常,2-冻结)!' }];
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// label: '删除状态(0-正常,1-已删除)',
|
||||
// field: 'delFlag',
|
||||
// component: 'Input',
|
||||
// dynamicRules: ({ model, schema }) => {
|
||||
// return [{ required: true, message: '请输入删除状态(0-正常,1-已删除)!' }];
|
||||
// },
|
||||
// },
|
||||
{
|
||||
label: '分类介绍',
|
||||
field: 'memo',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-button>
|
||||
<a-button type="primary" @click="batchHandleDelete" preIcon="ant-design:delete-outlined"> 批量删除 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(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>
|
||||
<!-- 表单区域 -->
|
||||
<ConKnowledgeCategoryModal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="conKnowledgeCategory-conKnowledgeCategory" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConKnowledgeCategoryModal from './components/ConKnowledgeCategoryModal.vue';
|
||||
import { columns, searchFormSchema } from './ConKnowledgeCategory.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './ConKnowledgeCategory.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '知识库分类',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '知识库分类',
|
||||
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) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
message.warning('未选中任何数据');
|
||||
return;
|
||||
}
|
||||
batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @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 { formSchema } from '../ConKnowledgeCategory.data';
|
||||
import { saveOrUpdate } from '../ConKnowledgeCategory.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
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,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(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,139 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { message } from 'ant-design-vue';
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/conDepartment/list',
|
||||
save = '/health-consultation/conDepartment/add',
|
||||
edit = '/health-consultation/conDepartment/edit',
|
||||
deleteOne = '/health-consultation/conDepartment/delete',
|
||||
deleteBatch = '/health-consultation/conDepartment/deleteBatch',
|
||||
importExcel = '/health-consultation/conDepartment/importExcel',
|
||||
exportXls = '/health-consultation/conDepartment/exportXls',
|
||||
department = '/health-consultation/conDepartment/getConDepartmentAll',
|
||||
queryById = '/health-consultation/conDepartment/queryById',
|
||||
listLevelOne = '/health-consultation/conDepartment/listLevelOne',
|
||||
selectRelevancyById = '/health-consultation/conDepartment/selectRelevancyById',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params: any) => defHttp.get({ url: Api.list, params });
|
||||
/**
|
||||
* 根据id获取信息
|
||||
* @param params
|
||||
*/
|
||||
export const resEditData = (params: any) => defHttp.get({ url: Api.queryById, params });
|
||||
|
||||
/**
|
||||
* 科室列表
|
||||
* @param params
|
||||
*/
|
||||
export const getDepartment = (params: any) => defHttp.get({ url: Api.department, params });
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @date 2023/7/22
|
||||
* @param params
|
||||
* @param handleSuccess
|
||||
* @param res
|
||||
*/
|
||||
export const deleteOne = (params: any, handleSuccess: Function, res: { doctorNum: any; resourceNum: any; sickNum: any }) => {
|
||||
const { doctorNum, resourceNum, sickNum } = res;
|
||||
if (doctorNum === 0 && resourceNum === 0 && sickNum === 0) {
|
||||
return createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
let str = '该科室下';
|
||||
const list: { num: number; msg: string }[] = [
|
||||
{
|
||||
num: doctorNum,
|
||||
msg: `有${doctorNum}名医生;`,
|
||||
},
|
||||
{
|
||||
num: sickNum,
|
||||
msg: `关联${sickNum}类疾病;`,
|
||||
},
|
||||
{
|
||||
num: resourceNum,
|
||||
msg: `有${resourceNum}个医院使用该科室;`,
|
||||
},
|
||||
];
|
||||
list.forEach((item) => {
|
||||
if (item.num > 0) {
|
||||
str += item.msg;
|
||||
}
|
||||
});
|
||||
message.error(str + '禁止删除此数据!');
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const batchDelete = (params: any, handleSuccess: Function) => {
|
||||
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: any, isUpdate: boolean) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* @Description:获取一级科室列表
|
||||
* @date 2023/7/18
|
||||
* @param params
|
||||
*/
|
||||
export const listLevelOne = (params: any) => defHttp.get({ url: Api.listLevelOne, params });
|
||||
/**
|
||||
* @Description:查询该科室关联专家-疾病-医院
|
||||
* @date 2023/7/22
|
||||
* @param params 科室id
|
||||
*/
|
||||
export const selectRelevancyById = (params: any) => defHttp.get({ url: Api.selectRelevancyById, params });
|
||||
@@ -0,0 +1,162 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { h } from 'vue';
|
||||
import { Image } from 'ant-design-vue';
|
||||
import { getDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
import { listLevelOne } from '/@/views/consult/department/ConDepartment.api';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '科室名称',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '图片',
|
||||
align: 'center',
|
||||
dataIndex: 'image',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getDefaultImage(),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '医生数',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorNum',
|
||||
},
|
||||
{
|
||||
title: '简介',
|
||||
align: 'left',
|
||||
dataIndex: 'mark',
|
||||
},
|
||||
{
|
||||
title: '是否置顶',
|
||||
align: 'center',
|
||||
dataIndex: 'tfTop',
|
||||
customRender: ({ text }) => (text === 1 ? '是' : '否'),
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
align: 'center',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '科室名称',
|
||||
field: 'departmentName',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '科室名称',
|
||||
field: 'departmentName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '所属科室',
|
||||
field: 'officeparid',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: listLevelOne,
|
||||
labelField: 'departmentName',
|
||||
valueField: 'id',
|
||||
getPopupContainer: () => document.body,
|
||||
immediate: true,
|
||||
afterFetch: (res: any[]) => {
|
||||
if (formModel.id && Array.isArray(res) && res.length > 0) {
|
||||
return res?.filter((item) => item?.id !== formModel.id);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '科室图片',
|
||||
field: 'image',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
fileMax: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '科室简介',
|
||||
field: 'mark',
|
||||
component: 'InputTextArea',
|
||||
componentProps: () => {
|
||||
return {
|
||||
minRows: 4,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '是否置顶',
|
||||
field: 'tfTop',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '是',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '否',
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'value',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="null">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="'consultation:con_department:add'" type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">
|
||||
新增
|
||||
</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template #htmlSlot="{ text }">
|
||||
<div v-html="text"></div>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<ConDepartmentModal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conDepartment" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConDepartmentModal from './components/ConDepartmentModal.vue';
|
||||
import { columns, searchFormSchema } from './ConDepartment.data';
|
||||
import { list, deleteOne, resEditData, selectRelevancyById } from './ConDepartment.api';
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '医院科室',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
// size: 'small',
|
||||
isTreeTable: true,
|
||||
pagination: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 180,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
title: '新增',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
openModal(true, {
|
||||
record: res,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
title: '编辑',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
resEditData({ id: record.id }).then((res) => {
|
||||
openModal(true, {
|
||||
record: res,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
title: '详情',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
async function handleDelete(record) {
|
||||
let res = await selectRelevancyById({ id: record.id });
|
||||
// res.doctorNum = 50;
|
||||
// console.log('res', res);
|
||||
await deleteOne({ id: record.id }, handleSuccess, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
// async function batchHandleDelete() {
|
||||
// if (selectedRowKeys.value.length === 0) {
|
||||
// return message.warning('未选中任何数据');
|
||||
// }
|
||||
// await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'consultation:con_department:edit',
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'consultation:con_department:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</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 { formSchema } from '../ConDepartment.data';
|
||||
import { saveOrUpdate } from '../ConDepartment.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
//设置标题
|
||||
let title = ref<string>('');
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
title.value = data.title;
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
value: data.record.id,
|
||||
officeparid: data.record.officeparid || '',
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
const params = {
|
||||
...values,
|
||||
officeparid: values.officeparid ? values.officeparid : null,
|
||||
};
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(params, 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,117 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
export enum Api {
|
||||
list = '/health-consultation/conDoctor/accountList',
|
||||
save = '/health-consultation/conDoctor/add',
|
||||
edit = '/health-consultation/conDoctor/edit',
|
||||
deleteOne = '/health-consultation/conDoctor/delete',
|
||||
deleteBatch = '/health-consultation/conDoctor/deleteBatch',
|
||||
importExcel = '/health-consultation/conDoctor/importExcel',
|
||||
exportXls = '/health-consultation/conDoctor/exportXlsAccount',
|
||||
getCostLogByType = '/health-consultation/conDoctor/getCostLogByType',
|
||||
updateCostByTitle = '/health-consultation/conDoctor/updateCostByTitle',
|
||||
updateCostByUserId = '/health-consultation/conDoctor/updateCostByUserId',
|
||||
getDoctorCard = '/health-consultation/consultation/conDoctorCard/list',
|
||||
deleteCard = '/health-consultation/consultation/conDoctorCard/delete',
|
||||
getCostList = '/health-consultation/conCostStatistics/list',
|
||||
withdraw = '/health-consultation/conCostStatistics/payment',
|
||||
getRecordDetail1 = '/health-consultation/consultation/conSession/queryByIdDetails',
|
||||
getRecordDetail2 = '/health-consultation/conCostStatistics/queryById',
|
||||
addCard = '/health-consultation/consultation/conDoctorCard/addList',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const batchDelete = (params: any, handleSuccess: Function) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
// 账户结算/ 提现
|
||||
export const withdraw = (params) => defHttp.post({ url: Api.withdraw, params });
|
||||
// 查看历史费用
|
||||
export const getCostLogByType = (params) => {
|
||||
return defHttp.get({ url: Api.getCostLogByType, params });
|
||||
};
|
||||
// 统一设置费用
|
||||
export const updateCostByTitle = (params) => defHttp.get({ url: Api.updateCostByTitle, params });
|
||||
// 单独设置非同
|
||||
export const updateCostByUserId = (params) => defHttp.get({ url: Api.updateCostByUserId, params });
|
||||
//获取所有银行卡
|
||||
export const getDoctorCard = (params) => {
|
||||
return new Promise(async (resolve) => {
|
||||
try {
|
||||
const res = await defHttp.get({ url: Api.getDoctorCard, params });
|
||||
return resolve(res['records']);
|
||||
} catch {
|
||||
return resolve([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
// 账户历史查询
|
||||
export const getCostList = (params) => defHttp.get({ url: Api.getCostList, params });
|
||||
//获取记录详情
|
||||
export const getRecordDetail = (params) => defHttp.get({ url: Api.getRecordDetail1, params });
|
||||
// 提现详情
|
||||
export const getRecordDetail2 = (params) => defHttp.get({ url: Api.getRecordDetail2, params });
|
||||
//导出专家账户
|
||||
export const exportFile = (params) => defHttp.post({ url: Api.exportXls, params });
|
||||
// 添加专家银行卡
|
||||
export const addCard = (params) => defHttp.post({ url: Api.addCard, params });
|
||||
//删除专家银行卡
|
||||
export const deleteCard = (params) => defHttp.delete({ url: Api.deleteCard + '?id=' + params.id });
|
||||
@@ -0,0 +1,669 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { BODY_CONTAINER } from '/@/utils/domUtils';
|
||||
import { getDoctorCard } from '/@/views/consult/doctor/account/account.api';
|
||||
import { selectResourceList } from '/@/views/consult/doctor/message/conDoctor.api';
|
||||
import { h } from 'vue';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorName',
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
align: 'center',
|
||||
dataIndex: 'sex',
|
||||
width: 70,
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'sex2');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
align: 'center',
|
||||
dataIndex: 'phone',
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
align: 'center',
|
||||
dataIndex: 'idCard',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
align: 'center',
|
||||
dataIndex: 'resourceName',
|
||||
},
|
||||
{
|
||||
title: '科室',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '职称',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorTitle_dictText',
|
||||
},
|
||||
{
|
||||
title: '账户余额',
|
||||
align: 'center',
|
||||
dataIndex: 'accountMoneyToString',
|
||||
},
|
||||
{
|
||||
title: '专家银行卡',
|
||||
align: 'center',
|
||||
dataIndex: 'cardNum',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '开户行',
|
||||
align: 'center',
|
||||
dataIndex: 'cardMsg',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'hospitalName',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: selectResourceList,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '科室',
|
||||
field: 'departmentName',
|
||||
component: 'JTreeDepartment',
|
||||
componentProps: () => {
|
||||
return {
|
||||
allDep: true,
|
||||
placeholder: '请选择科室',
|
||||
showSearch: true,
|
||||
treeNodeFilterProp: 'label',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorTitle',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_lev',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误', trigger: 'blur' }],
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorJob',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '职务',
|
||||
field: 'doctorTitle',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '擅长',
|
||||
field: 'goodAt',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '执业经历',
|
||||
field: 'experience',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '所属医院id',
|
||||
field: 'resourceId',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '所属科室id',
|
||||
field: 'departmentId',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '擅长症状',
|
||||
field: 'goodAtSymptom',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '擅长疾病',
|
||||
field: 'goodAtSickness',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '值班时间',
|
||||
field: 'onDutyTime',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '是否接受咨询',
|
||||
field: 'isAccept',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '专家类型',
|
||||
field: 'type',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医生状态',
|
||||
field: 'doctorStatus',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '高德地图id',
|
||||
field: 'gdId',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '毕业时间',
|
||||
field: 'outTime',
|
||||
component: 'DatePicker',
|
||||
},
|
||||
{
|
||||
label: '住址',
|
||||
field: 'address',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '联系地址',
|
||||
field: 'contactAddress',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'nationality',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
field: 'eQ',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
field: 'nativePlace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '参加工作时间',
|
||||
field: 'joinWork',
|
||||
component: 'DatePicker',
|
||||
},
|
||||
{
|
||||
label: '健康状态',
|
||||
field: 'healthStatus',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '毕业学校',
|
||||
field: 'school',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '获奖或者论文',
|
||||
field: 'award',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '标签',
|
||||
field: 'doctorLabel',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '状态(1-激活,2-锁定)',
|
||||
field: 'status',
|
||||
component: 'InputNumber',
|
||||
dynamicRules: () => {
|
||||
return [{ required: true, message: '请输入状态(1-激活,2-锁定)!' }];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '删除状态(0-正常,1-已删除)',
|
||||
field: 'delFlag',
|
||||
component: 'InputNumber',
|
||||
dynamicRules: () => {
|
||||
return [{ required: true, message: '请输入删除状态(0-正常,1-已删除)!' }];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
field: 'memo',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医生姓名',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '综合评价 上限是5',
|
||||
field: 'overallMerit',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '回复率',
|
||||
field: 'responseRate',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '热度',
|
||||
field: 'degreeHeat',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '头像',
|
||||
field: 'photo',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '简介',
|
||||
field: 'introduction',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '用户总评分',
|
||||
field: 'userScore',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '评分用户总数',
|
||||
field: 'userScoreNum',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '回复数',
|
||||
field: 'replyNum',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '消息总数',
|
||||
field: 'messageNum',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '是否推荐 0否1是',
|
||||
field: 'tfRecommend',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '医院名称',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '科室名称',
|
||||
field: 'departmentName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '是否展示小火苗 0否1是',
|
||||
field: 'tfShowFire',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
// 账户结算form
|
||||
export const accountForm: FormSchema[] = [
|
||||
{
|
||||
label: '专家',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '所属医院',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '账户余额',
|
||||
field: 'accountMoney',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '提现方式',
|
||||
field: 'withdraw',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'withdrawal_type',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '提现银行卡',
|
||||
field: 'paymentAccount',
|
||||
component: 'ApiSelect',
|
||||
rules: [{ required: true }],
|
||||
ifShow: ({ values }) => {
|
||||
return values.withdraw == '0';
|
||||
},
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: getDoctorCard,
|
||||
resultField: 'list',
|
||||
params: { doctorId: formModel.id },
|
||||
valueField: 'cardNum',
|
||||
labelField: 'cardNum',
|
||||
immediate: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '提现金额',
|
||||
field: 'paymentMoney',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '实际结算金额',
|
||||
field: 'realityMoney',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '提现说明',
|
||||
field: 'remarks',
|
||||
component: 'InputTextArea',
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
// 咨询费用统一设置
|
||||
export const costSettingForm: FormSchema[] = [
|
||||
{
|
||||
label: '专家职称',
|
||||
required: true,
|
||||
field: 'titleId',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_lev',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '图文咨询',
|
||||
field: 'graphicCost',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
placeholder: '请输入图文咨询费用',
|
||||
},
|
||||
suffix: '元/次',
|
||||
rules: [{ required: true, trigger: 'blur', message: '请输入图文咨询费用' }],
|
||||
},
|
||||
{
|
||||
label: '视频咨询',
|
||||
field: 'videoCost',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入视频咨询费用',
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
suffix: '元/次',
|
||||
rules: [{ required: true, trigger: 'blur', message: '请输入视频咨询费用' }],
|
||||
},
|
||||
];
|
||||
// 咨询费用单个设置
|
||||
export const costSettingSelfForm: FormSchema[] = [
|
||||
{
|
||||
label: '专家',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '所属医院',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '图文咨询',
|
||||
field: 'graphicCost',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入图文咨询费用',
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
suffix: '元/次',
|
||||
rules: [{ required: true, trigger: 'blur', message: '请输入图文咨询费用' }],
|
||||
},
|
||||
{
|
||||
label: '视频咨询',
|
||||
field: 'videoCost',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入视频咨询费用',
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
suffix: '元/次',
|
||||
rules: [{ required: true, trigger: 'blur', message: '请输入视频咨询费用' }],
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
// 账户历史
|
||||
export const accountDetailForm: FormSchema[] = [
|
||||
{
|
||||
label: '专家姓名',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '所属医院',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '账单类型',
|
||||
field: 'operateType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'historical_type',
|
||||
// allowClear: false,
|
||||
showChooseOption: false,
|
||||
},
|
||||
// defaultValue: '0',
|
||||
},
|
||||
{
|
||||
label: '选择日期',
|
||||
field: 'Date',
|
||||
component: 'RangePicker',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
valueType: 'Date',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
getPopupContainer: () => BODY_CONTAINER,
|
||||
'onUpdate:value': (value) => {
|
||||
if (value) {
|
||||
formModel.startDate = value[0];
|
||||
formModel.endDate = value[1];
|
||||
} else {
|
||||
formModel.startDate = null;
|
||||
formModel.endDate = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
label: '',
|
||||
field: 'startDate',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'endDate',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
export const accountDetailColumn: BasicColumn[] = [
|
||||
{
|
||||
title: '业务时间',
|
||||
align: 'center',
|
||||
dataIndex: 'incomeTime',
|
||||
},
|
||||
{
|
||||
title: '业务',
|
||||
align: 'center',
|
||||
dataIndex: 'operateName',
|
||||
},
|
||||
{
|
||||
title: '业务金额',
|
||||
align: 'center',
|
||||
dataIndex: 'income',
|
||||
customRender: ({ text, record }) => {
|
||||
if (!text) return '';
|
||||
if (record?.operateType == '5') {
|
||||
return h('div', { style: { color: 'red' } }, `- ¥${text}`);
|
||||
}
|
||||
return h('div', { style: { color: 'green' } }, `+ ¥${text}`);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '账户余额',
|
||||
align: 'center',
|
||||
dataIndex: 'accountMoneyToString',
|
||||
},
|
||||
];
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
|
||||
export function dealResData(data) {
|
||||
const arr = [];
|
||||
data?.map((item) => {
|
||||
arr.push({ time: item.memo, ...item });
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
export function numberPrefix(number, prefix) {
|
||||
if (number || number === 0) {
|
||||
return prefix + number;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
export interface CardType {
|
||||
cardMsg: string;
|
||||
cardNum: string;
|
||||
status: boolean;
|
||||
}
|
||||
export interface FormState {
|
||||
data: CardType[];
|
||||
doctorId: string;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="accountWithdrawalBtn">账户结算</a-button>
|
||||
<a-button type="primary" @click="freeSetting">统一费用设置</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls">导出</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="exportRecord"> 查看导出任务 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<account-withdrawal @register="registerModal" @success="handleSuccess" />
|
||||
<!-- 咨询费用统一设置 -->
|
||||
<SingleCostSetting @register="singleCostModal" />
|
||||
<!-- 个人咨询费用设置 -->
|
||||
<CostSettingSelf @register="costSettingSelfModal" @success="handleSuccess" />
|
||||
<!-- 账户历史-->
|
||||
<AccountDetails @register="accountDetailModal" />
|
||||
<export-util task-code="comDoctorAccount" @register="registerExport" />
|
||||
<!--添加银行卡-->
|
||||
<BankCard @register="bankCardModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-account" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns, searchFormSchema } from './account.data';
|
||||
import { exportFile, getExportUrl, getImportUrl, list } from './account.api';
|
||||
import AccountWithdrawal from './components/accountWithdrawal.vue';
|
||||
import SingleCostSetting from '/@/views/consult/doctor/account/components/singleCostSetting.vue';
|
||||
import CostSettingSelf from './components/costSettingSelf.vue';
|
||||
import AccountDetails from './components/accountDetails.vue';
|
||||
import BankCard from '/@/views/consult/doctor/account/components/bankCard.vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import ExportUtil from '/@/utils/export/exportUtil.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [singleCostModal, { openModal: openSingleCostModal }] = useModal();
|
||||
const [costSettingSelfModal, { openModal: openCostSettingSelfModal }] = useModal();
|
||||
const [accountDetailModal, { openModal: openAccountDetailModal }] = useModal();
|
||||
const [bankCardModal, { openModal: openBankCardModalModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '专家账户',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 164,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: 'con_doctor',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload, getDataSource, getForm }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
const [registerExport, { openDrawer }] = useDrawer();
|
||||
|
||||
// 账户结算
|
||||
function accountWithdrawalBtn() {
|
||||
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
|
||||
return message.warn('请选择一位专家');
|
||||
}
|
||||
const [id] = selectedRowKeys?._rawValue;
|
||||
const data = getDataSource();
|
||||
const records = data.filter((item) => {
|
||||
if (item.id == id) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
openModal(true, {
|
||||
records: records[0],
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
// 费用设置统一费用设置
|
||||
function freeSetting() {
|
||||
openSingleCostModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openAccountDetailModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
selectedRowKeys.value = [];
|
||||
reload();
|
||||
}
|
||||
//单独咨询费用设置
|
||||
function openSettingModal(record: Recordable) {
|
||||
openCostSettingSelfModal(true, {
|
||||
record,
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @Description:导出到记录表
|
||||
* @date 2023/7/3
|
||||
*/
|
||||
async function onExportXls() {
|
||||
const form = getForm().getFieldsValue();
|
||||
await exportFile(form);
|
||||
}
|
||||
function exportRecord() {
|
||||
openDrawer(true, {});
|
||||
}
|
||||
/**
|
||||
* @Description:添加银行卡
|
||||
* @date 2023/7/19
|
||||
*/
|
||||
function addBankCard(record: Recordable) {
|
||||
openBankCardModalModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '咨询费用设置',
|
||||
onClick: openSettingModal.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
function getDropDownAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '账户历史',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '添加银行卡',
|
||||
onClick: addBankCard.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="1100" @ok="handleSubmit" @cancel="clearData">
|
||||
<div style="height: 65vh">
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<div>
|
||||
<span class="ml10"><span class="text-label">账户金额:</span>{{ numberPrefix(doctorAccount.accountMoney, '¥') }}</span>
|
||||
<span class="ml10"><span class="text-label">累计收益:</span>{{ numberPrefix(doctorAccount.accumulatedIncome, '¥') }}</span>
|
||||
<span class="ml10"><span class="text-label">提现金额:</span>{{ numberPrefix(doctorAccount.withdrawalAmount, '¥') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!--咨询详情-->
|
||||
<staffForDoctorModal @register="registerDetailModal" />
|
||||
<!--提现详情-->
|
||||
<accountWithdrawal @register="registerAccountModal" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { accountDetailForm, accountDetailColumn, numberPrefix } from '/@/views/consult/doctor/account/account.data';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { getCostList, getRecordDetail, getRecordDetail2 } from '/@/views/consult/doctor/account/account.api';
|
||||
import { ColEx } from '/@/components/Form/src/types';
|
||||
import StaffForDoctorModal from '/@/views/consult/staff/staffForDoctor/components/staffForDoctorModal.vue';
|
||||
import AccountWithdrawal from '/@/views/consult/doctor/account/components/accountWithdrawal.vue';
|
||||
const title = '账户历史';
|
||||
const record = ref({});
|
||||
const doctorAccount = ref({});
|
||||
// 自适应列配置
|
||||
const adaptiveColProps: Partial<ColEx> = {
|
||||
offset: 0,
|
||||
xs: 8, // <576px
|
||||
sm: 8, // ≥576px
|
||||
md: 8, // ≥768px
|
||||
lg: 8, // ≥992px
|
||||
xl: 8, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
};
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
record.value = data.record;
|
||||
// setForm();
|
||||
await getForm().setFieldsValue({
|
||||
...record.value,
|
||||
});
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
// // 隐藏底部时禁用整个表单
|
||||
// await getForm().setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//咨询详情
|
||||
const [registerDetailModal, { openModal: openDetailModal }] = useModal();
|
||||
//提现详情
|
||||
const [registerAccountModal, { openModal: openAccountModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '专家账户',
|
||||
api: getCostList,
|
||||
columns: accountDetailColumn,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
baseColProps: adaptiveColProps,
|
||||
schemas: accountDetailForm,
|
||||
autoSubmitOnEnter: true,
|
||||
resetFunc: () => {
|
||||
let timer = setTimeout(async () => {
|
||||
clearTimeout(timer);
|
||||
// 保留姓名和医院
|
||||
return await getForm().setFieldsValue({
|
||||
...record.value,
|
||||
});
|
||||
});
|
||||
},
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
actionColOptions: {
|
||||
offset: 1,
|
||||
span: 8,
|
||||
xs: 8, // <576px
|
||||
sm: 8, // ≥576px
|
||||
md: 8, // ≥768px
|
||||
lg: 8, // ≥992px
|
||||
xl: 8, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
},
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
// 赋值专家ID
|
||||
params.userId = record.value.id;
|
||||
return params;
|
||||
},
|
||||
afterFetch: () => {
|
||||
const dataSource = getRawDataSource();
|
||||
doctorAccount.value = {
|
||||
accountMoney: dataSource.accountMoney,
|
||||
accumulatedIncome: dataSource.accumulatedIncome,
|
||||
withdrawalAmount: dataSource.withdrawalAmount,
|
||||
};
|
||||
return dataSource.records;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { getForm, getRawDataSource }] = tableContext;
|
||||
// 咨询详情
|
||||
function openConsultModal(record: Recordable) {
|
||||
if (!record.sessionId) return;
|
||||
getRecordDetail({ id: record.sessionId }).then((res) => {
|
||||
openDetailModal(true, {
|
||||
record: res,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
//提现详情
|
||||
function openWithDrawModal(row) {
|
||||
getRecordDetail2({ id: row.id }).then((res) => {
|
||||
openAccountModal(true, {
|
||||
records: { ...res, ...res.conDoctor, accountMoney: res.accountMoney },
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
});
|
||||
|
||||
// registerAccountModal()
|
||||
}
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '咨询详情',
|
||||
ifShow: () => record.operateType !== null && record.operateType !== '5',
|
||||
onClick: openConsultModal.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '提现详情',
|
||||
ifShow: () => record.operateType == '5',
|
||||
onClick: openWithDrawModal.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
function handleSubmit() {}
|
||||
|
||||
function clearData() {}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.text-label {
|
||||
color: rgb(0, 0, 0.85);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @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 { formSchema } from '../account.data';
|
||||
import { saveOrUpdate } from '../account.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
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,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(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,56 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" @cancel="clearData">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { accountForm } from '/@/views/consult/doctor/account/account.data';
|
||||
import { withdraw } from '/@/views/consult/doctor/account/account.api';
|
||||
const emit = defineEmits(['success']);
|
||||
const title = '账户结算';
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: accountForm,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
console.log('data', data);
|
||||
//重置表单
|
||||
await resetFields();
|
||||
await setFieldsValue({
|
||||
...data.records,
|
||||
});
|
||||
await clearValidate();
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
function clearData() {}
|
||||
// withdraw
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
const json = JSON.parse(JSON.stringify(values).replace(/id/g, 'userId'));
|
||||
//提交表单
|
||||
await withdraw(json);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" @cancel="clearData">
|
||||
<a-form class="form-card-container" ref="bankForm" :model="formState.data" :rules="rules">
|
||||
<a-list :data-source="formState.data" :bordered="true">
|
||||
<template #header>
|
||||
<a-row>
|
||||
<a-col flex="4" class="text-c">开户行</a-col>
|
||||
<a-col flex="4" class="text-c">银行卡号</a-col>
|
||||
<a-col flex="3" class="text-c">状态</a-col>
|
||||
<a-col flex="2" class="text-c">
|
||||
<a-button size="small" title="添加" type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<template #renderItem="{ item, index }">
|
||||
<a-row class="row-self">
|
||||
<a-col flex="4" class="text-c">
|
||||
<a-form-item :name="[index, 'cardMsg']" :prop="`data.${index}.cardMsg`" :rules="rules.cardMsg">
|
||||
<a-input v-model:value="item.cardMsg" style="width: 80%" placeholder="请输入开户行" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col flex="4" class="text-c">
|
||||
<a-form-item :name="[index, 'cardNum']" :prop="`data.${index}.cardNum`" :rules="rules.cardNum">
|
||||
<a-input v-model:value="item.cardNum" style="width: 80%" placeholder="请输入银行卡号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col flex="3" class="text-c">
|
||||
<a-form-item :name="[index, 'status']" :prop="`data.${index}.status`" :rules="rules.status">
|
||||
<a-switch v-model:checked="item.status" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col flex="2" class="text-c">
|
||||
<a-button size="small" title="删除" preIcon="ant-design:delete-outlined" @click="handleDelete(index)" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { FormInstance } from 'ant-design-vue';
|
||||
import { addCard, getDoctorCard, deleteCard } from '/@/views/consult/doctor/account/account.api';
|
||||
import { FormState, CardType } from '/@/views/consult/doctor/account/account.data';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
const { createConfirm } = useMessage();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const title = '专家银行卡';
|
||||
const bankForm = ref<FormInstance>();
|
||||
const formState = reactive<FormState>({
|
||||
data: [],
|
||||
doctorId: '',
|
||||
});
|
||||
const rules = {
|
||||
cardMsg: [{ required: true, trigger: 'blur', pattern: /[\u4e00-\u9fa5]/, message: '请输入正确的银行卡开户行' }],
|
||||
cardNum: [{ required: true, trigger: 'blur', pattern: /^([1-9])(\d{14,18})$/, message: '银行卡号格式有误' }],
|
||||
status: [{ required: true, trigger: 'blur', message: '请选择是否启用该卡号' }],
|
||||
};
|
||||
const [registerModal, { closeModal }] = useModalInner(async (data) => {
|
||||
formState.doctorId = data.record.id;
|
||||
try {
|
||||
let res = await getDoctorCard({ doctorId: data.record.id });
|
||||
if (res && res.length) {
|
||||
formState.data = res.map((item) => ({
|
||||
cardMsg: item.cardMsg,
|
||||
cardNum: item.cardNum,
|
||||
status: item.status == '1',
|
||||
id: item.id,
|
||||
}));
|
||||
}
|
||||
} catch (e) {}
|
||||
});
|
||||
function handleAdd() {
|
||||
const item: CardType = { cardMsg: '', cardNum: '', status: true };
|
||||
formState.data.unshift(item);
|
||||
}
|
||||
function handleDelete(index) {
|
||||
let id = formState.data[index].id || '';
|
||||
if (id) {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
await deleteCard({ id: id });
|
||||
formState.data.splice(index, 1);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
formState.data.splice(index, 1);
|
||||
}
|
||||
}
|
||||
function clearData() {
|
||||
formState.data = [];
|
||||
formState.doctorId = '';
|
||||
}
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await bankForm.value?.validateFields();
|
||||
const params = formState.data.map((item) => ({ ...item, status: item?.status ? 1 : 2, doctorId: formState.doctorId }));
|
||||
await addCard(params);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
clearData();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.row-self {
|
||||
margin-top: 8px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.text-c {
|
||||
text-align: center;
|
||||
}
|
||||
.form-card-container {
|
||||
max-height: 420px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" @cancel="clearData">
|
||||
<div style="height: 60vh">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div class="time-line-container">
|
||||
<a-button type="primary" @click="openTimeLine"> 历史费用 </a-button>
|
||||
<div class="time-line-box" :class="[isShrink ? 'unfold' : 'shrink']">
|
||||
<TimeLine class="mt20" :dataList="timeLineList">
|
||||
<template #customSlot="{ data }">
|
||||
<div class="time-content mt10">
|
||||
<div class="content-item"> 图文咨询 {{ data.graphicCost || '' }} 元/次</div>
|
||||
<div class="content-item"> 视频咨询 {{ data.videoCost || '' }} 元/次 </div>
|
||||
</div>
|
||||
</template>
|
||||
</TimeLine>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { costSettingSelfForm, dealResData } from '/@/views/consult/doctor/account/account.data';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getCostLogByType, updateCostByUserId } from '/@/views/consult/doctor/account/account.api';
|
||||
import TimeLine from '/@/views/consult/doctor/account/components/timeLine.vue';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const title = '咨询费用设置';
|
||||
const isShrink = ref(false);
|
||||
const timeLineList = ref([]);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, getFieldsValue, clearValidate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: costSettingSelfForm,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await getTimeLineData();
|
||||
await clearValidate();
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
async function getTimeLineData() {
|
||||
let { id } = getFieldsValue();
|
||||
if (!id) {
|
||||
return message.warn('请先选择专家职称!');
|
||||
}
|
||||
const data = await getCostLogByType({ userId: id + '', type: 0, titleId: '' });
|
||||
await setFieldsValue({
|
||||
graphicCost: data[0]?.graphicCost,
|
||||
videoCost: data[0]?.videoCost,
|
||||
});
|
||||
timeLineList.value = dealResData(data) || [];
|
||||
}
|
||||
function openTimeLine() {
|
||||
isShrink.value = !isShrink.value;
|
||||
if (!timeLineList.value.length) {
|
||||
return message.info('暂无历史费用!');
|
||||
}
|
||||
}
|
||||
function clearData() {
|
||||
timeLineList.value = [];
|
||||
isShrink.value = false;
|
||||
}
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await updateCostByUserId({ ...values, userId: values.id });
|
||||
clearData();
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.time-line-container {
|
||||
padding: 0 20px;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.time-content {
|
||||
width: 45%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #303133;
|
||||
.content-item {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
.time-line-box {
|
||||
transition: all 0.3s linear;
|
||||
|
||||
&.shrink {
|
||||
max-height: 0;
|
||||
height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&.unfold {
|
||||
max-height: 500px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" @cancel="clearData">
|
||||
<div class="detail-container">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div class="time--line-container">
|
||||
<a-button type="primary" @click="openTimeLine"> 查看历史费用</a-button>
|
||||
<div class="time-line-box" :class="[isShrink ? 'unfold' : 'shrink']">
|
||||
<TimeLine class="mt20" :dataList="timeLineList">
|
||||
<template #customSlot="{ data }">
|
||||
<div class="time-content mt10">
|
||||
<div class="content-item"> 图文咨询 {{ data.graphicCost || '' }} 元/次</div>
|
||||
<div class="content-item"> 视频咨询 {{ data.videoCost || '' }} 元/次 </div>
|
||||
</div>
|
||||
</template>
|
||||
</TimeLine>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { costSettingForm, dealResData } from '/@/views/consult/doctor/account/account.data';
|
||||
import { getCostLogByType, updateCostByTitle } from '/@/views/consult/doctor/account/account.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
import TimeLine from '/@/views/consult/doctor/account/components/timeLine.vue';
|
||||
const title = '咨询费用统一设置';
|
||||
const isShrink = ref(false);
|
||||
const timeLineList = ref([]);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, validate, getFieldsValue }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: costSettingForm,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
async function openTimeLine() {
|
||||
isShrink.value = true;
|
||||
let { titleId } = getFieldsValue();
|
||||
if (!titleId) {
|
||||
return message.warn('请先选择专家职称!');
|
||||
}
|
||||
const data = await getCostLogByType({ titleId: titleId + '', type: 1, userId: '' });
|
||||
if (!data.length) {
|
||||
timeLineList.value = [];
|
||||
return message.info('暂无历史费用!');
|
||||
}
|
||||
timeLineList.value = dealResData(data) || [];
|
||||
}
|
||||
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
|
||||
function clearData() {
|
||||
timeLineList.value = [];
|
||||
isShrink.value = false;
|
||||
}
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await updateCostByTitle(values);
|
||||
clearData();
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.detail-container {
|
||||
height: 65vh;
|
||||
overflow: auto;
|
||||
}
|
||||
.time--line-container {
|
||||
padding: 0 20px;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.time-line-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 8px;
|
||||
|
||||
.time-title {
|
||||
color: #909399;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.time-content {
|
||||
width: 45%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.time-line-box {
|
||||
transition: all 0.3s linear;
|
||||
|
||||
&.shrink {
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
&.unfold {
|
||||
max-height: 500px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<ul class="timeline">
|
||||
<li class="timeline-item" v-for="(item, i) in list" :key="i">
|
||||
<div class="timeline-item-tail"></div>
|
||||
<div class="timeline-item-head" :class="[itemColor(item.color)]"></div>
|
||||
<div class="timeline-item-content">
|
||||
<div>{{ item.time }}</div>
|
||||
<slot name="customSlot" :data="item"></slot>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
dataList: {
|
||||
type: Array,
|
||||
},
|
||||
});
|
||||
const list = computed(() => props.dataList);
|
||||
function itemColor(color) {
|
||||
const colorType = {
|
||||
green: 'timeline-item-head-green',
|
||||
red: 'timeline-item-head-red',
|
||||
gray: 'timeline-item-head-gray',
|
||||
};
|
||||
return (color && colorType[color]) || 'timeline-item-head-blue';
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.timeline {
|
||||
box-sizing: border-box;
|
||||
color: #000000d9;
|
||||
font-size: 14px;
|
||||
font-variant: tabular-nums;
|
||||
line-height: 1.5715;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0 0 20px;
|
||||
font-size: 14px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.timeline-item-tail {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 4px;
|
||||
height: calc(100% - 10px);
|
||||
border-left: 2px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.timeline-item-pending .timeline-item-head {
|
||||
font-size: 12px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.timeline-item-pending .timeline-item-tail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.timeline-item-head {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #fff;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.timeline-item-head-blue {
|
||||
color: #1890ff;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.timeline-item-head-red {
|
||||
color: #ff4d4f;
|
||||
border-color: #ff4d4f;
|
||||
}
|
||||
|
||||
.timeline-item-head-green {
|
||||
color: #52c41a;
|
||||
border-color: #52c41a;
|
||||
}
|
||||
|
||||
.timeline-item-head-gray {
|
||||
color: #00000040;
|
||||
border-color: #00000040;
|
||||
}
|
||||
|
||||
.timeline-item-head-custom {
|
||||
position: absolute;
|
||||
top: 5.5px;
|
||||
left: 5px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin-top: 0;
|
||||
padding: 3px 1px;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.timeline-item-content {
|
||||
position: relative;
|
||||
top: -7.001px;
|
||||
margin: 0 0 0 18px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.timeline-item-last > .timeline-item-tail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.timeline-item-last > .timeline-item-content {
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.timeline.timeline-alternate .timeline-item-tail,
|
||||
.timeline.timeline-right .timeline-item-tail,
|
||||
.timeline.timeline-alternate .timeline-item-head,
|
||||
.timeline.timeline-right .timeline-item-head,
|
||||
.timeline.timeline-alternate .timeline-item-head-custom,
|
||||
.timeline.timeline-right .timeline-item-head-custom {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.timeline.timeline-alternate .timeline-item-head,
|
||||
.timeline.timeline-right .timeline-item-head {
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.timeline.timeline-alternate .timeline-item-head-custom,
|
||||
.timeline.timeline-right .timeline-item-head-custom {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.timeline.timeline-alternate .timeline-item-left .timeline-item-content,
|
||||
.timeline.timeline-right .timeline-item-left .timeline-item-content {
|
||||
left: calc(50% - 4px);
|
||||
width: calc(50% - 14px);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.timeline.timeline-alternate .timeline-item-right .timeline-item-content,
|
||||
.timeline.timeline-right .timeline-item-right .timeline-item-content {
|
||||
width: calc(50% - 12px);
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.timeline.timeline-right .timeline-item-right .timeline-item-tail,
|
||||
.timeline.timeline-right .timeline-item-right .timeline-item-head,
|
||||
.timeline.timeline-right .timeline-item-right .timeline-item-head-custom {
|
||||
left: calc(100% - 6px);
|
||||
}
|
||||
|
||||
.timeline.timeline-right .timeline-item-right .timeline-item-content {
|
||||
width: calc(100% - 18px);
|
||||
}
|
||||
|
||||
.timeline.timeline-pending .timeline-item-last .timeline-item-tail {
|
||||
display: block;
|
||||
height: calc(100% - 14px);
|
||||
border-left: 2px dotted #f0f0f0;
|
||||
}
|
||||
|
||||
.timeline.timeline-reverse .timeline-item-last .timeline-item-tail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.timeline.timeline-reverse .timeline-item-pending .timeline-item-tail {
|
||||
top: 15px;
|
||||
display: block;
|
||||
height: calc(100% - 15px);
|
||||
border-left: 2px dotted #f0f0f0;
|
||||
}
|
||||
|
||||
.timeline.timeline-reverse .timeline-item-pending .timeline-item-content {
|
||||
min-height: 48px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conDoctorChangeLog/list',
|
||||
save = '/health-consultation/consultation/conDoctorChangeLog/add',
|
||||
edit = '/health-consultation/consultation/conDoctorChangeLog/edit',
|
||||
deleteOne = '/health-consultation/consultation/conDoctorChangeLog/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conDoctorChangeLog/deleteBatch',
|
||||
updateSessionUrl = '/health-consultation/consultation/conDoctorChangeLog/updateSessionByLog',
|
||||
undoUpdateSessionUrl = '/health-consultation/consultation/conDoctorChangeLog/undoUpdateSessionByLog',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
* @param params
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const batchDelete = (params: any, handleSuccess: Function) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp
|
||||
.delete(
|
||||
{
|
||||
url: Api.deleteBatch,
|
||||
data: params,
|
||||
},
|
||||
{ joinParamsToUrl: true }
|
||||
)
|
||||
.then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 保存或者更新
|
||||
* @param params
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
export const updateSession = (params, handleSuccess) => {
|
||||
const data = { id: params.id };
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `确认更新历史咨询数据吗?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.post({ url: Api.updateSessionUrl, data }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
export const undoUpdateSession = (params, handleSuccess) => {
|
||||
const data = { id: params.id };
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `确认撤销更新历史咨询数据吗?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.post({ url: Api.undoUpdateSessionUrl, data }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,258 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: 'id',
|
||||
align: 'center',
|
||||
dataIndex: 'id',
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
title: '专家ID',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorId',
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
title: '专家名称(表单使用)',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorNameWhole',
|
||||
ifShow: false,
|
||||
customRender: ({ text, record }) => {
|
||||
let doctorNameWhole = record.doctorName + '【' + record.resourceName + '-' + record.departmentName + '】';
|
||||
record.doctorNameWhole = doctorNameWhole;
|
||||
return doctorNameWhole;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '专家名称',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorName',
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
align: 'center',
|
||||
dataIndex: 'resourceName',
|
||||
},
|
||||
{
|
||||
title: '科室',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '专家职称',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
// dataIndex: 'doctorOldJob_dictText',
|
||||
slots: { customRender: 'changeTagJob' },
|
||||
},
|
||||
{
|
||||
title: '专家类型',
|
||||
align: 'center',
|
||||
width: 250,
|
||||
// dataIndex: 'doctorOldType_dictText'
|
||||
slots: { customRender: 'changeTagType' },
|
||||
},
|
||||
{
|
||||
title: '专家状态',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
// dataIndex: 'doctorOldStatus_dictText'
|
||||
slots: { customRender: 'changeTagStatus' },
|
||||
},
|
||||
{
|
||||
title: '修改时间',
|
||||
align: 'center',
|
||||
dataIndex: 'changeDate',
|
||||
customRender: ({ text }) => {
|
||||
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
align: 'center',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '修改时间',
|
||||
align: 'center',
|
||||
dataIndex: 'updateTime',
|
||||
defaultHidden: true,
|
||||
},
|
||||
{
|
||||
title: '是否已更新咨询信息',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
dataIndex: 'updateSessionFlag_dictText',
|
||||
componentProps: {
|
||||
dictCode: 'yes_no',
|
||||
stringToNumber: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '更新咨询主表时间',
|
||||
align: 'center',
|
||||
dataIndex: 'updateSessionTime',
|
||||
defaultHidden: true,
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '专家姓名',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
//colProps: {span: 6},
|
||||
},
|
||||
{
|
||||
label: '修改时间',
|
||||
field: 'changeDate',
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
valueType: 'Date',
|
||||
},
|
||||
//colProps: {span: 6},
|
||||
},
|
||||
{
|
||||
label: '是否已更新咨询信息',
|
||||
field: 'updateSessionFlag',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'yes_no',
|
||||
// stringToNumber: true,
|
||||
},
|
||||
//colProps: {span: 6},
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '专家名称',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
placeholder: '点击选择专家',
|
||||
readOnly: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '修改时间',
|
||||
field: 'changeDate',
|
||||
required: true,
|
||||
colProps: { span: 12 },
|
||||
component: 'DatePicker',
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
dynamicDisabled: true,
|
||||
},
|
||||
{
|
||||
label: '科室',
|
||||
field: 'departmentName',
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
dynamicDisabled: true,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'doctorId',
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '原专家职称',
|
||||
field: 'doctorOldJob',
|
||||
component: 'JDictSelectTag',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_job',
|
||||
},
|
||||
dynamicDisabled: true,
|
||||
},
|
||||
{
|
||||
label: '专家职称',
|
||||
field: 'doctorJob',
|
||||
component: 'JDictSelectTag',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_job',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '原专家类型',
|
||||
field: 'doctorOldType',
|
||||
component: 'JDictSelectTag',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_typ',
|
||||
},
|
||||
dynamicDisabled: true,
|
||||
},
|
||||
{
|
||||
label: '专家类型',
|
||||
field: 'doctorType',
|
||||
component: 'JDictSelectTag',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
dictCode: 'z_doct_typ',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '原专家状态',
|
||||
field: 'doctorOldStatus',
|
||||
component: 'JDictSelectTag',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
dictCode: 'doc_status',
|
||||
},
|
||||
dynamicDisabled: true,
|
||||
},
|
||||
|
||||
{
|
||||
label: '专家状态',
|
||||
field: 'doctorStatus',
|
||||
colProps: { span: 12 },
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'doc_status',
|
||||
},
|
||||
},
|
||||
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
// 高级查询数据
|
||||
export const superQuerySchema = {
|
||||
doctorId: { title: '专家ID', order: 0, view: 'text', type: 'string' },
|
||||
doctorOldJob: { title: '原专家职称', order: 1, view: 'list', type: 'string', dictCode: 'z_doct_job' },
|
||||
doctorOldType: { title: '原专家类型', order: 2, view: 'list', type: 'string', dictCode: 'z_doct_typ' },
|
||||
doctorOldStatus: { title: '原专家状态', order: 3, view: 'list', type: 'string', dictCode: 'doc_status' },
|
||||
doctorJob: { title: '专家职称', order: 4, view: 'list', type: 'string', dictCode: 'z_doct_job' },
|
||||
doctorType: { title: '专家类型', order: 5, view: 'list', type: 'string', dictCode: 'z_doct_typ' },
|
||||
doctorStatus: { title: '专家状态', order: 6, view: 'list', type: 'string', dictCode: 'doc_status' },
|
||||
changeDate: { title: '修改时间', order: 7, view: 'date', type: 'string' },
|
||||
createTime: { title: '创建时间', order: 8, view: 'datetime', type: 'string' },
|
||||
updateTime: { title: '修改时间', order: 9, view: 'datetime', type: 'string' },
|
||||
};
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData: any): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-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"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button
|
||||
>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<!-- 高级查询 -->
|
||||
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
<!--字段回显插槽-->
|
||||
<template v-slot:bodyCell="{ column, record, index, text }"> </template>
|
||||
<template #changeTagJob="{ record }">
|
||||
<Tag color="green">
|
||||
{{ record.doctorOldJob_dictText }}
|
||||
</Tag>
|
||||
改为
|
||||
<Tag :color="record.doctorOldJob == record.doctorJob ? 'green' : 'red'">
|
||||
{{ record.doctorJob_dictText }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #changeTagType="{ record }">
|
||||
<Tag color="green">
|
||||
{{ record.doctorOldType_dictText }}
|
||||
</Tag>
|
||||
改为
|
||||
<Tag :color="record.doctorOldType == record.doctorType ? 'green' : 'red'">
|
||||
{{ record.doctorType_dictText }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #changeTagStatus="{ record }">
|
||||
<Tag color="green">
|
||||
{{ record.doctorOldStatus_dictText }}
|
||||
</Tag>
|
||||
改为
|
||||
<Tag :color="record.doctorOldStatus == record.doctorStatus ? 'green' : 'red'">
|
||||
{{ record.doctorStatus_dictText }}
|
||||
</Tag>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<ConDoctorChangeLogModal @register="registerModal" @success="handleSuccess"></ConDoctorChangeLogModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conDoctorChangeLog" setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConDoctorChangeLogModal from './components/ConDoctorChangeLogModal.vue';
|
||||
import { columns, searchFormSchema, superQuerySchema } from './ConDoctorChangeLog.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, updateSession, undoUpdateSession } from './ConDoctorChangeLog.api';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
|
||||
const queryParam = reactive<any>({});
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
const userStore = useUserStore();
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: '专家信息修改日志',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [['changeDate', ['changeDate_begin', 'changeDate_end'], 'YYYY-MM-DD']],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
return Object.assign(params, queryParam);
|
||||
},
|
||||
//自定义默认排序
|
||||
defSort: {
|
||||
column: 'createTime',
|
||||
order: 'desc',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: '专家信息修改日志',
|
||||
url: getExportUrl,
|
||||
params: queryParam,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
// 高级查询配置
|
||||
const superQueryConfig = reactive(superQuerySchema);
|
||||
|
||||
/**
|
||||
* 高级查询事件
|
||||
*/
|
||||
function handleSuperQuery(params) {
|
||||
Object.keys(params).map((k) => {
|
||||
queryParam[k] = params[k];
|
||||
});
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
function handleDetail(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
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),
|
||||
},
|
||||
{
|
||||
label: '更新数据',
|
||||
// auth: 'consultation:con_doctor_change_log:update_session',
|
||||
onClick: handleUpdateSession.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '撤销更新',
|
||||
// auth: 'consultation:con_doctor_change_log:update_session',
|
||||
onClick: handleUndoUpdateSession.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
async function handleUpdateSession(record) {
|
||||
await updateSession(record, handleSuccess);
|
||||
}
|
||||
|
||||
async function handleUndoUpdateSession(record) {
|
||||
await undoUpdateSession(record, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record) {
|
||||
return [
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
placement: 'topLeft',
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.jeecg-modal-wrapper,
|
||||
.jeecg-modal-content {
|
||||
height: 600px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div style="min-height: 800px">
|
||||
<BasicForm @register="registerForm"></BasicForm>
|
||||
<div style="width: 100%;text-align: center" v-if="!formDisabled">
|
||||
<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/index';
|
||||
import {computed, defineComponent} from 'vue';
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import {getBpmFormSchema} from '../ConDoctorChangeLog.data';
|
||||
import {saveOrUpdate} from '../ConDoctorChangeLog.api';
|
||||
|
||||
export default defineComponent({
|
||||
name: "ConDoctorChangeLogForm",
|
||||
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 = {};
|
||||
const queryByIdUrl = '/consultation/conDoctorChangeLog/queryById';
|
||||
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);
|
||||
console.log('表单数据', params)
|
||||
await saveOrUpdate(params, true)
|
||||
}
|
||||
|
||||
initFormData();
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
formDisabled,
|
||||
submitForm,
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.jeecg-modal-wrapper, .jeecg-modal-content {
|
||||
height: 600px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="1000" height="800" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
<selectdoc ref="replaceOtherRef" title="选择用户" @choose-employ="onSelectUserOk" />
|
||||
</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 { formSchema } from '../ConDoctorChangeLog.data';
|
||||
import { saveOrUpdate } from '../ConDoctorChangeLog.api';
|
||||
import selectdoc from '/@/views/emergency/communication/components/selectdoc.vue';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
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,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
|
||||
const replaceOtherRef = ref();
|
||||
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
formSchema[0].componentProps.onClick = () => {
|
||||
replaceOtherRef.value.showModal();
|
||||
};
|
||||
|
||||
//表单提交事件
|
||||
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 onSelectUserOk(e) {
|
||||
let json = JSON.parse(e);
|
||||
await setFieldsValue({
|
||||
doctorName: json.doctorName,
|
||||
resourceName: json.resourceName,
|
||||
departmentName: json.departmentName,
|
||||
doctorId: json.id,
|
||||
doctorOldJob: json.doctorJob,
|
||||
doctorOldType: json.type,
|
||||
doctorOldStatus: json.doctorStatus,
|
||||
doctorJob: json.doctorJob,
|
||||
doctorType: json.type,
|
||||
doctorStatus: json.doctorStatus,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.jeecg-modal-wrapper,
|
||||
.jeecg-modal-content {
|
||||
height: 600px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
:width="adaptiveWidth * 1.5"
|
||||
@ok="handleSubmit"
|
||||
:showFooter="showFooter"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div class="form-container">
|
||||
<div class="title"><strong>基本信息</strong></div>
|
||||
<BasicForm @register="registerForm" />
|
||||
<div class="title"><strong>扩展信息</strong></div>
|
||||
<BasicForm @register="registerFormData" />
|
||||
<div class="title"><strong>其它信息</strong></div>
|
||||
<BasicForm @register="registerFormOther" />
|
||||
</div>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema, formSchemaData, formSchemaOther } from '../conDoctor.data';
|
||||
import { saveOrUpdate } from '../conDoctor.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
import { dealPassword } from '/@/views/system/user/user.data';
|
||||
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref<boolean>(true);
|
||||
const showFooter = ref<boolean>(true);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate, updateSchema }] = useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
});
|
||||
//表单配置扩展
|
||||
const [registerFormData, { setProps: setPropsData, setFieldsValue: setFieldsValueData, validate: validateData, clearValidate: clearValidate2 }] =
|
||||
useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formSchemaData,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
});
|
||||
//表单配置其他
|
||||
const [
|
||||
registerFormOther,
|
||||
{ setProps: setPropsOther, setFieldsValue: setFieldsValueOther, validate: validateOther, clearValidate: clearValidate3 },
|
||||
] = useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formSchemaOther,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
});
|
||||
|
||||
//表单赋值
|
||||
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;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record.conDoctor,
|
||||
...data.record.sysUserModel,
|
||||
id: data?.record.conDoctor.id,
|
||||
hospitalId: data?.record.conDoctor.resourceId,
|
||||
value: data?.record.conDoctor.departmentId,
|
||||
//调整一下,这里如果是空字符串,就直接转空数组
|
||||
goodAtSickness: getSicknesses(data),
|
||||
});
|
||||
await setFieldsValueData({
|
||||
...data.record.conDoctor,
|
||||
...data.record.sysUserModel,
|
||||
});
|
||||
await setFieldsValueOther({
|
||||
...data.record.conDoctor,
|
||||
...data.record.sysUserModel,
|
||||
});
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: false,
|
||||
},
|
||||
]);
|
||||
await clearValidate();
|
||||
await clearValidate2();
|
||||
await clearValidate3();
|
||||
} else {
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
await setPropsData({ disabled: !data?.showFooter });
|
||||
await setPropsOther({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let data = {
|
||||
...(await validate()),
|
||||
...(await validateData()),
|
||||
...(await validateOther()),
|
||||
};
|
||||
let passwordObj = {};
|
||||
if (!isUpdate.value) {
|
||||
passwordObj = {
|
||||
password: dealPassword(data?.password),
|
||||
};
|
||||
}
|
||||
//调整数据参数
|
||||
let setData = {
|
||||
conDoctor: {
|
||||
id: data?.id,
|
||||
award: data?.award,
|
||||
doctorName: data?.doctorName,
|
||||
contactAddress: data?.contactAddress,
|
||||
nationality: data?.nationality,
|
||||
nativePlace: data?.nativePlace,
|
||||
email: data?.email,
|
||||
departmentId: data?.departmentId,
|
||||
doctorTitle: data?.doctorTitle,
|
||||
idCard: data?.idCard,
|
||||
eq: data?.eq,
|
||||
experience: data?.experience,
|
||||
goodAt: data?.goodAt,
|
||||
workHistory: data?.workHistory,
|
||||
introduction: data?.introduction,
|
||||
joinWork: data?.joinWork,
|
||||
phone: data?.phone,
|
||||
outTime: data?.outTime,
|
||||
resourceId: data?.resourceId,
|
||||
school: data?.school,
|
||||
sex: data?.sex,
|
||||
type: data?.type,
|
||||
doctorStatus: data?.doctorStatus, // 专家状态
|
||||
workExperience: data?.workExperience, // 工作经历
|
||||
doctorJob: data?.doctorJob,
|
||||
goodAtSickness: data?.goodAtSickness,
|
||||
doctorNo: data?.doctorNo,
|
||||
regDate: data?.regDate,
|
||||
offDate: data?.offDate,
|
||||
tfRecommend: data?.tfRecommend,
|
||||
sort: data?.sort,
|
||||
},
|
||||
sysUserModel: {
|
||||
username: data?.username,
|
||||
...passwordObj,
|
||||
avatar: data?.avatar,
|
||||
email: data?.email,
|
||||
idCard: data?.idCard,
|
||||
phone: data?.phone,
|
||||
sex: data?.sex,
|
||||
birthday: data?.birthday,
|
||||
id: data?.id,
|
||||
},
|
||||
};
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(setData, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
const getSicknesses = (data) => {
|
||||
const goodAtSickness = data?.record?.conDoctor?.goodAtSickness;
|
||||
// 明确检查 goodAtSickness 是否为有效的非空字符串
|
||||
return typeof goodAtSickness === 'string' && goodAtSickness.trim() !== '' ? goodAtSickness.split(',') : [];
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.form-container {
|
||||
//height: 65vh;
|
||||
overflow: auto;
|
||||
}
|
||||
.title {
|
||||
box-sizing: border-box;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-picker) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:maskClosable="false"
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
:showFooter="false"
|
||||
:width="adaptiveWidth"
|
||||
@close="cancel"
|
||||
>
|
||||
<div style="margin-bottom: 14px">
|
||||
<span style="margin-right: 10px">视频状态:</span>
|
||||
<a-switch v-model:checked="state.audioStatus" @change="changeStatus" />
|
||||
<span style="margin: 0 10px">是否跳过节假日:</span>
|
||||
<a-switch v-model:checked="state.tfJumpHoliday" @change="changeHolidayStatus" />
|
||||
<a-button class="ml-3a0" v-if="!isEdit" @click="editTable" type="primary">编辑 </a-button>
|
||||
<a-button class="ml-3a0" v-else type="primary" @click="handleSubmit" :loading="submitLoading">保存 </a-button>
|
||||
</div>
|
||||
<a-spin :spinning="spinning">
|
||||
<a-table :columns="schedulingColumns" :data-source="state.columnData" size="small" :pagination="false">
|
||||
<template #bodyCell="{ column, record, text }">
|
||||
<template v-if="column.dataIndex === 'count'">
|
||||
<div v-if="editableData[record.key]" class="editable-cell-input-wrapper">
|
||||
<a-input-number placeholder="请输入最多可约人数" style="width: 200px" v-model:value="record[record.type]" :min="0" />
|
||||
</div>
|
||||
<div v-else class="editable-cell-text-wrapper"> {{ text || '' }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-spin>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { schedulingColumns } from '/@/views/consult/doctor/message/conDoctor.data';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { getDoctorScheduling, updateAudioStatus, updateDoctorScheduling, updateJumpHoliday } from '/@/views/consult/doctor/message/conDoctor.api';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
import { processingData, processStatus } from '/@/views/consult/doctor/message/scheduling.data';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
//设置标题
|
||||
const title = '排班设置';
|
||||
const state = ref({
|
||||
doctorId: '',
|
||||
columnData: [],
|
||||
audioStatus: false,
|
||||
tfJumpHoliday: false,
|
||||
});
|
||||
const spinning = ref(false);
|
||||
let editableData = reactive({});
|
||||
const isEdit = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
state.value.doctorId = data.record.id;
|
||||
state.value.audioStatus = data.record.audioStatus === '1';
|
||||
state.value.tfJumpHoliday = data.record.tfJumpHoliday === '1';
|
||||
isEdit.value = false;
|
||||
await initData();
|
||||
});
|
||||
|
||||
function dealData(res) {
|
||||
return processingData(res);
|
||||
}
|
||||
|
||||
async function initData() {
|
||||
spinning.value = true;
|
||||
let res = await getDoctorScheduling({ doctorId: state.value.doctorId });
|
||||
spinning.value = false;
|
||||
state.value.columnData = dealData(res);
|
||||
clearEditData();
|
||||
}
|
||||
function clearEditData() {
|
||||
for (let key in editableData) {
|
||||
if (editableData.hasOwnProperty(key)) {
|
||||
editableData[key] = null;
|
||||
}
|
||||
}
|
||||
editableData = {};
|
||||
isEdit.value = false;
|
||||
}
|
||||
/**
|
||||
* @Description:编辑修改
|
||||
* @date 2023/7/14
|
||||
*/
|
||||
function editTable() {
|
||||
const keys = state.value.columnData.map((item) => item.key);
|
||||
keys.map((item, i) => {
|
||||
editableData[item] = state.value.columnData[i];
|
||||
});
|
||||
isEdit.value = true;
|
||||
}
|
||||
|
||||
async function changeStatus() {
|
||||
let audioStatus = state.value.audioStatus ? '1' : '0';
|
||||
const params = processStatus(state.value.doctorId, { audioStatus });
|
||||
await updateAudioStatus(params);
|
||||
// await initData();
|
||||
}
|
||||
|
||||
async function changeHolidayStatus() {
|
||||
let tfJumpHoliday = state.value.tfJumpHoliday ? '1' : '0';
|
||||
const params = processStatus(state.value.doctorId, { tfJumpHoliday });
|
||||
await updateJumpHoliday(params);
|
||||
// await initData();
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
Object.assign(editableData, {});
|
||||
state.value.audioStatus = false;
|
||||
state.value.tfJumpHoliday = false;
|
||||
emit('success');
|
||||
}
|
||||
|
||||
function submitParams() {
|
||||
const params: any = [];
|
||||
const result = state.value.columnData || [];
|
||||
for (let i = 0; i < result.length; i += 2) {
|
||||
const item_am: any = result[i];
|
||||
const item_pm: any = result[i + 1];
|
||||
const type = item_am?.amNum || item_pm?.pmNum ? 2 : 0;
|
||||
const o: any = {
|
||||
...item_am,
|
||||
amNum: item_am?.amNum || 0,
|
||||
pmNum: item_pm?.pmNum || 0,
|
||||
type: type,
|
||||
};
|
||||
params.push(o);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const params = submitParams();
|
||||
submitLoading.value = true;
|
||||
await updateDoctorScheduling(params);
|
||||
await initData();
|
||||
} catch (e: any) {
|
||||
submitLoading.value = false;
|
||||
throw new Error('请求失败', e);
|
||||
} finally {
|
||||
for (const key in editableData) {
|
||||
if (editableData[key]) {
|
||||
delete editableData[key];
|
||||
}
|
||||
}
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
submitLoading.value = false;
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
emit('success');
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(table tr, table th, table td) {
|
||||
border-right: 1px solid #f0f0f0 !important;
|
||||
border-bottom: 1px solid #f0f0f0 !important;
|
||||
}
|
||||
|
||||
.ml-3a0 {
|
||||
margin-left: 30px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="1000">
|
||||
<!--引用表格-->
|
||||
<div style="height: 60vh">
|
||||
<BasicTable @register="registerTable" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { BasicTable } from '/@/components/Table';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { suspensionColumns, suspensionForm } from '/@/views/consult/doctor/message/conDoctor.data';
|
||||
import { getServiceRecords } from '/@/views/consult/doctor/message/conDoctor.api';
|
||||
import { ColEx } from '/@/components/Form/src/types';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const title = '暂停服务';
|
||||
const record = ref({
|
||||
id: '',
|
||||
});
|
||||
// 自适应列配置
|
||||
const adaptiveColProps: Partial<ColEx> = {
|
||||
offset: 0,
|
||||
xs: 8, // <576px
|
||||
sm: 8, // ≥576px
|
||||
md: 8, // ≥768px
|
||||
lg: 8, // ≥992px
|
||||
xl: 8, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
};
|
||||
|
||||
//表单赋值
|
||||
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
const { resetFields, setFieldsValue } = getForm();
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
record.value = data.record;
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
});
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '暂停服务',
|
||||
api: getServiceRecords,
|
||||
columns: suspensionColumns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
baseColProps: adaptiveColProps,
|
||||
schemas: suspensionForm,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
showResetButton: false,
|
||||
showSubmitButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
actionColOptions: {
|
||||
offset: 0,
|
||||
span: 8,
|
||||
xs: 8, // <576px
|
||||
sm: 8, // ≥576px
|
||||
md: 8, // ≥768px
|
||||
lg: 8, // ≥992px
|
||||
xl: 8, // ≥1200px
|
||||
xxl: 8, // ≥1600px
|
||||
},
|
||||
},
|
||||
actionColumn: {
|
||||
ifShow: false,
|
||||
},
|
||||
beforeFetch: (info) => {
|
||||
info['doctorId'] = record.value?.id;
|
||||
return info;
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { getForm }] = tableContext;
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
:deep(.ant-table-title) {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,168 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
export enum Api {
|
||||
list = '/health-consultation/conDoctor/list',
|
||||
//排班
|
||||
schedulingList = '/health-consultation/consultation/conDoctorSchedulingDate/list',
|
||||
save = '/health-consultation/conDoctor/add',
|
||||
edit = '/health-consultation/conDoctor/edit',
|
||||
deleteOne = '/health-consultation/conDoctor/delete',
|
||||
deleteBatch = '/health-consultation/conDoctor/deleteBatch',
|
||||
importExcel = '/health-consultation/conDoctor/importDoctor',
|
||||
exportXls = '/health-consultation/conDoctor/exportXls',
|
||||
getServiceRecords = '/health-consultation/conDoctor/getServiceByDoctorId',
|
||||
getDoctorScheduling = '/health-consultation/consultation/conDoctorScheduling/getDoctorScheduling',
|
||||
updateDoctorScheduling = '/health-consultation/consultation/conDoctorScheduling/updateDoctorScheduling',
|
||||
queryById = '/health-consultation/conDoctor/queryById',
|
||||
selectResourceList = '/health-consultation/conResource/selectResourceList',
|
||||
updateAudioStatus = '/health-consultation/conDoctor/updateAudioStatus',
|
||||
updateJumpHoliday = '/health-consultation/conDoctor/updateJumpHoliday',
|
||||
generateScheduling = '/consultation/conDoctorSchedulingDate/generateDoctorSchedulingDate',
|
||||
exportXlsAccount = '/health-consultation/conDoctor/exportXlsAccount',
|
||||
closeStatus = '/health-consultation/conService/add',
|
||||
openStatus = '/health-consultation/conService/openDoctorStatus',
|
||||
recommend = '/health-consultation/conDoctor/recommend',
|
||||
}
|
||||
|
||||
export const recommendApi = (params) => defHttp.get({ url: Api.recommend, 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 });
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const batchDelete = (params: any, handleSuccess: Function) => {
|
||||
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: any, isUpdate: boolean) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
*@description 暂停服务记录
|
||||
* @param params 请求参数
|
||||
* */
|
||||
export const getServiceRecords = (params) => defHttp.get({ url: Api.getServiceRecords, params });
|
||||
/**
|
||||
* @description 获取专家排班
|
||||
* @param params 请求参数
|
||||
* */
|
||||
export const getDoctorScheduling = (params) => defHttp.get({ url: Api.getDoctorScheduling, params });
|
||||
/**
|
||||
* @description 修改专家排班
|
||||
* @param params 请求参数
|
||||
* */
|
||||
export const updateDoctorScheduling = (params) => defHttp.post({ url: Api.updateDoctorScheduling, params });
|
||||
/**
|
||||
* @description 获取专家信息详情
|
||||
* @param params 请求参数
|
||||
* */
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
|
||||
/**
|
||||
* @Description:查询医院列表
|
||||
* @date 2023/7/3
|
||||
* @param params
|
||||
*/
|
||||
export const selectResourceList = (params) => defHttp.get({ url: Api.selectResourceList, params });
|
||||
/**
|
||||
* @Description:导出到记录表
|
||||
* @date 2023/7/3
|
||||
*/
|
||||
export const exportFile = (params) => defHttp.post({ url: Api.exportXls, params });
|
||||
|
||||
/**
|
||||
* @Description:修改音视频状态
|
||||
* @date 2023/7/11
|
||||
* @param params
|
||||
*/
|
||||
export const updateAudioStatus = (params: any) => defHttp.post({ url: Api.updateAudioStatus, params });
|
||||
/**
|
||||
* @Description:修改是否跳过节假日状态
|
||||
* @date 2023/7/12
|
||||
* @param params
|
||||
*/
|
||||
export const updateJumpHoliday = (params: any) => defHttp.post({ url: Api.updateJumpHoliday, params });
|
||||
|
||||
/**
|
||||
* @Description:生成专家排班
|
||||
* @date 2023/7/11
|
||||
* @param params
|
||||
*/
|
||||
export const generateScheduling = (params: any) => defHttp.get({ url: Api.generateScheduling, params });
|
||||
/*
|
||||
* 开启关闭咨询
|
||||
* */
|
||||
export const getStatus = (params, handleSuccess, type) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `是否将此专家咨询置【${type ? '开启' : '关闭'}】状态?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
if (type) {
|
||||
defHttp.post({ url: Api.openStatus, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
} else {
|
||||
defHttp.post({ url: Api.closeStatus, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
// const url = type ? Api.openStatus : Api.closeStatus;
|
||||
// defHttp.post({ url, params }).then(() => {
|
||||
// handleSuccess();
|
||||
// });
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,750 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getExpertDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { h } from 'vue';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
import { Image, message } from 'ant-design-vue';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { selectResourceList } from '/@/views/consult/doctor/message/conDoctor.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getDepartmentList } from '/@/views/consult/resource/conResource.api';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
fixed: 'left',
|
||||
dataIndex: 'doctorAccount',
|
||||
},
|
||||
{
|
||||
title: '专家编号',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
fixed: 'left',
|
||||
dataIndex: 'doctorNo',
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
dataIndex: 'doctorName',
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
align: 'center',
|
||||
dataIndex: 'photo',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getExpertDefaultImage(),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
align: 'center',
|
||||
dataIndex: 'resourceName',
|
||||
},
|
||||
{
|
||||
title: '科室',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '职称',
|
||||
align: 'center',
|
||||
width: 90,
|
||||
dataIndex: 'doctorJob_dictText',
|
||||
},
|
||||
{
|
||||
title: '职务',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorTitle_dictText',
|
||||
},
|
||||
{
|
||||
title: '专家状态',
|
||||
align: 'center',
|
||||
slots: { customRender: 'doctorStatusTag' },
|
||||
// dataIndex: 'doctorStatus',
|
||||
// customRender: ({ text }) => {
|
||||
// return render.renderDict(text, 'doc_status');
|
||||
// },
|
||||
},
|
||||
{
|
||||
title: '咨询状态',
|
||||
align: 'center',
|
||||
slots: { customRender: 'doctorAcceptTag' },
|
||||
// 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: 'sort',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '是否推荐',
|
||||
align: 'center',
|
||||
dataIndex: 'tfRecommend',
|
||||
width: 80,
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'resourceId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
api: selectResourceList,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: false,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorJob',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'z_doct_job',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '专家状态',
|
||||
field: 'doctorStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'doc_status',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '收费类型',
|
||||
field: 'type',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'z_doct_typ',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '咨询状态',
|
||||
field: 'isAccept',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'doc_accept_flag',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
async function checkSick(_, value) {
|
||||
if (!value) {
|
||||
return Promise.reject('请选择疾病');
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
// 主键Id
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
show: false,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
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: {
|
||||
//@ts-ignore
|
||||
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: 'doctorName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
label: '性别',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'sex2',
|
||||
type: 'radio',
|
||||
},
|
||||
rules: [{ required: true, message: '请选择性别' }],
|
||||
},
|
||||
{
|
||||
field: 'avatar',
|
||||
label: '头像',
|
||||
component: 'JImageUpload',
|
||||
// rules: [{ required: true, message: '请选择头像' }],
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
maxCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' }],
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{
|
||||
pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
|
||||
message: '身份证号码格式有误',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱',
|
||||
component: 'Input',
|
||||
rules: [
|
||||
{
|
||||
type: 'email',
|
||||
pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
|
||||
message: '${label}格式有误',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
placeholder: '请输入邮箱',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'resourceId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
api: selectResourceList,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
onChange: () => {
|
||||
formModel.departmentId = '';
|
||||
formModel.goodAtSickness = [];
|
||||
},
|
||||
onDeselect: () => {
|
||||
if (formModel.hasOwnProperty('departmentId')) {
|
||||
formModel.departmentId = '';
|
||||
}
|
||||
},
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
rules: [{ required: true, message: '请选择医院', trigger: 'blur' }],
|
||||
},
|
||||
{
|
||||
label: '科室',
|
||||
field: 'departmentId',
|
||||
component: 'JTreeDepartment',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
hospitalId: formModel.resourceId,
|
||||
allDep: false,
|
||||
immediate: true,
|
||||
showSearch: true,
|
||||
treeNodeFilterProp: 'label',
|
||||
placeholder: '请选择科室',
|
||||
onChange: () => {
|
||||
formModel.goodAtSickness = [];
|
||||
},
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
console.log(input, option);
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
onFocus: () => {
|
||||
if (!formModel.resourceId) {
|
||||
return createMessage.warn('请先选择医院!');
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
rules: [{ required: true, message: '请选择科室', trigger: 'blur' }],
|
||||
},
|
||||
{
|
||||
label: '擅长疾病',
|
||||
field: 'goodAtSickness',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
let departmentId = '1321354';
|
||||
if (formModel?.departmentId) {
|
||||
if (Array.isArray(formModel?.departmentId)) {
|
||||
departmentId = formModel?.departmentId?.join(',');
|
||||
} else {
|
||||
departmentId = formModel?.departmentId;
|
||||
}
|
||||
}
|
||||
return {
|
||||
api: getDepartmentList,
|
||||
params: {
|
||||
departmentId: departmentId,
|
||||
isDoctor: true,
|
||||
},
|
||||
labelField: 'sicksName',
|
||||
valueField: 'id',
|
||||
resultField: 'list',
|
||||
mode: 'multiple',
|
||||
immediate: true,
|
||||
onFocus: () => {
|
||||
if (!formModel?.departmentId || formModel?.departmentId.length < 1) {
|
||||
return message.warn('请先选择科室');
|
||||
}
|
||||
},
|
||||
onChange: (val) => {
|
||||
if (val && val?.length) {
|
||||
val = val.join(',');
|
||||
formModel.goodAtSickness = val;
|
||||
}
|
||||
},
|
||||
disabledInitValue: true,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
};
|
||||
},
|
||||
rules: [{ trigger: 'blur', validator: checkSick }],
|
||||
},
|
||||
{
|
||||
label: '职称',
|
||||
field: 'doctorJob',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'z_doct_job',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '职务',
|
||||
field: 'doctorTitle',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
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;
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请选择职务' }],
|
||||
},
|
||||
{
|
||||
label: '专家类型',
|
||||
field: 'type',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'z_doct_typ',
|
||||
},
|
||||
rules: [{ required: true, message: '请选择专家类型' }],
|
||||
},
|
||||
{
|
||||
label: '专家状态',
|
||||
field: 'doctorStatus',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'z_doct_sta_orgin',
|
||||
type: 'radio',
|
||||
},
|
||||
rules: [{ required: true, message: '请选择专家状态' }],
|
||||
},
|
||||
{
|
||||
label: '专家编号',
|
||||
field: 'doctorNo',
|
||||
component: 'Input',
|
||||
dynamicRules: ({ values, model }) => {
|
||||
return [
|
||||
{
|
||||
required: model?.type == '1',
|
||||
validator: (_, value) => {
|
||||
console.log(value, values, model);
|
||||
if (model?.type !== '1' || value) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject('请输入专家编号');
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
field: 'regDate',
|
||||
label: '注册日期',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'offDate',
|
||||
label: '出库日期',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '是否推荐',
|
||||
field: 'tfRecommend',
|
||||
component: 'JDictSelectTag',
|
||||
defaultValue: '0',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
type: 'radio',
|
||||
options: [
|
||||
{ label: '是', value: '1' },
|
||||
{ label: '否', value: '0' },
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
//扩展数据
|
||||
export const formSchemaData: FormSchema[] = [
|
||||
{
|
||||
label: '学历',
|
||||
field: 'eq',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'education',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.trim().toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '出生日期',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '毕业院校',
|
||||
field: 'school',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'outTime',
|
||||
label: '毕业时间',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'nationality',
|
||||
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: 'nativePlace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '联系地址',
|
||||
field: 'contactAddress',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '简介',
|
||||
field: 'introduction',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
];
|
||||
|
||||
//扩展数据
|
||||
export const formSchemaOther: FormSchema[] = [
|
||||
{
|
||||
field: 'joinWork',
|
||||
label: '参加工作时间',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '擅长',
|
||||
field: 'goodAt',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '执业经历',
|
||||
field: 'experience',
|
||||
component: 'InputTextArea',
|
||||
/*componentProps: {
|
||||
//@ts-ignore
|
||||
rows: 5,
|
||||
},*/
|
||||
},
|
||||
{
|
||||
label: '获奖或论文',
|
||||
field: 'award',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '工作经历',
|
||||
field: 'workExperience',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'InputNumber',
|
||||
componentProps: () => ({
|
||||
min: 0,
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
// 暂停服务弹窗
|
||||
export const suspensionForm: FormSchema[] = [
|
||||
{
|
||||
label: '专家',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
readOnly: true,
|
||||
allowClear: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '医院',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
readOnly: true,
|
||||
allowClear: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'doctorId',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
const Status = {
|
||||
0: '停诊中',
|
||||
1: '结束停诊',
|
||||
};
|
||||
export const suspensionColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
customRender: ({ index }) => {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
align: 'center',
|
||||
dataIndex: 'resourceName',
|
||||
customRender: ({ record }): string => {
|
||||
const { startDay, endDay } = (record as any) || { startDay: '', endDay: '当前' };
|
||||
if (!startDay) {
|
||||
return '';
|
||||
}
|
||||
return `${startDay} 至 ${endDay}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '原因',
|
||||
align: 'center',
|
||||
dataIndex: 'stopReason',
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
align: 'center',
|
||||
dataIndex: 'memo',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
dataIndex: 'serviceStatus',
|
||||
customRender: ({ text }) => (text ? Status[text] : ''),
|
||||
},
|
||||
];
|
||||
|
||||
// 排班设置
|
||||
export const schedulingColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '星期',
|
||||
dataIndex: 'week_dictText',
|
||||
key: 'week_dictText',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
customCell: (_, index: number) => {
|
||||
if (index % 2 === 0) {
|
||||
return {
|
||||
rowSpan: 2,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '视频咨询时间',
|
||||
align: 'center',
|
||||
dataIndex: 'type_dictText',
|
||||
},
|
||||
{
|
||||
title: '最多预约人数',
|
||||
align: 'center',
|
||||
dataIndex: 'count',
|
||||
width: 220,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
*/
|
||||
export function getBpmFormSchema(): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable :rowSelection="rowSelection" @register="registerTable">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="'consultation:con_doctor:add'" preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd">
|
||||
新增专家</a-button
|
||||
>
|
||||
<a-button-group>
|
||||
<a-button type="primary" preIcon="ant-design:download-outlined" @click="downloadTemplate">导入模板下载</a-button>
|
||||
<a-upload name="file" :showUploadList="false" :customRequest="onImportXls" accept=".xlsx, .xls, application/vnd.ms-excel-=='">
|
||||
<a-button v-auth="'consultation:con_doctor:importExcel'" type="primary" preIcon="ant-design:import-outlined">导入</a-button>
|
||||
</a-upload>
|
||||
<a-button
|
||||
v-auth="'consultation:con_doctor:exportXls'"
|
||||
type="primary"
|
||||
preIcon="ant-design:import-outlined"
|
||||
@click="openRecordDrawer('comDoctorImportMsg', '查看导入记录')"
|
||||
>
|
||||
查看导入任务
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
<a-button-group>
|
||||
<a-button v-auth="'consultation:con_doctor:exportXls'" type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"
|
||||
>导出</a-button
|
||||
>
|
||||
<a-button
|
||||
v-auth="'consultation:con_doctor:exportXls'"
|
||||
type="primary"
|
||||
preIcon="ant-design:export-outlined"
|
||||
@click="openRecordDrawer('comDoctorMsg', '查看导出记录')"
|
||||
>
|
||||
查看导出任务
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
<a-button
|
||||
v-auth="'consultation:con_doctor:deleteBatch'"
|
||||
@click="batchHandleDelete"
|
||||
type="primary"
|
||||
preIcon="ant-design:delete-outlined"
|
||||
>批量删除</a-button
|
||||
>
|
||||
<a-button type="primary" @click="stopService">暂停服务记录</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
|
||||
<template #doctorStatusTag="{ record }">
|
||||
<Tag v-if="record.doctorStatus_dictText !== undefined" :color="record.doctorStatus == '1' ? 'green' : 'red'">
|
||||
{{ record.doctorStatus_dictText }}
|
||||
</Tag>
|
||||
</template>
|
||||
|
||||
<template #doctorAcceptTag="{ record }">
|
||||
<Tag v-if="record.isAccept_dictText !== undefined" :color="record.isAccept == '1' ? 'green' : 'red'">
|
||||
{{ record.isAccept_dictText }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex == 'tfRecommend'">
|
||||
<a-switch
|
||||
v-model:checked="record.tfRecommend"
|
||||
@click="changeSwitch(record)"
|
||||
checked-children="是"
|
||||
un-checked-children="否"
|
||||
checkedValue="1"
|
||||
unCheckedValue="0"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<doctor-modal @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 专家排班 -->
|
||||
<s-modal @register="sModalDrawer" @success="handleSuccess" />
|
||||
<!--暂停服务-->
|
||||
<suspension-service @register="registerService" />
|
||||
<RestPass @register="restPassModal" />
|
||||
<export-util :task-code="taskCode" :drawerTitle="drawerTitle" @register="registerExport" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conDoctor" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import DoctorModal from './components/conDoctorModal.vue';
|
||||
import SModal from './components/schedulingModal.vue';
|
||||
import { columns, searchFormSchema } from './conDoctor.data';
|
||||
import { Api, batchDelete, deleteOne, exportFile, getExportUrl, getImportUrl, getStatus, list, queryById, recommendApi } from './conDoctor.api';
|
||||
import { message, Tag } from 'ant-design-vue';
|
||||
import SuspensionService from '/@/views/consult/doctor/message/components/suspensionService.vue';
|
||||
import RestPass from '/@/views/system/user/restPass/RestPass.vue';
|
||||
import ExportUtil from '/@/utils/export/exportUtil.vue';
|
||||
import { lockUser } from '/@/views/system/user/hospitalDoctor/HospitalDoctor.api';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useMethods } from '/@/hooks/system/useMethods';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { ref } from 'vue';
|
||||
import { downloadExcel } from '/@/views/healthMonitor/healMonitorManage/monitorToll/toolManagement/toolHooks';
|
||||
|
||||
const taskCode = ref('');
|
||||
const drawerTitle = ref('');
|
||||
const { handleImportXls } = useMethods();
|
||||
const { createMessage } = useMessage();
|
||||
const [registerDrawer, { openDrawer: openFormDrawer }] = useDrawer();
|
||||
// 排班
|
||||
const [sModalDrawer, { openDrawer: openSModalDrawer }] = useDrawer();
|
||||
|
||||
//注册model
|
||||
const [registerService, { openModal: openServiceModal }] = useModal();
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
const recommend = ref(1);
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'con_doctor',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 230,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: 'con_doctor',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload, getForm, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
const [registerExport, { openDrawer }] = useDrawer();
|
||||
|
||||
//新增专家
|
||||
function handleAdd() {
|
||||
openFormDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
// 文件导入
|
||||
function onImportXls(d) {
|
||||
const size = d.file.size;
|
||||
const m10 = 1024 * 1024 * 10;
|
||||
if (size > m10) {
|
||||
console.log('文件过大');
|
||||
}
|
||||
handleImportXls(d, Api.importExcel, () => {
|
||||
reload();
|
||||
});
|
||||
}
|
||||
// 模板下载
|
||||
function downloadTemplate() {
|
||||
downloadExcel('/static/importDoctor.xlsx', '专家信息导入模板');
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
let res = await queryById({ id: record.id });
|
||||
openFormDrawer(true, {
|
||||
record: res,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 排班事件
|
||||
*/
|
||||
function handleScheduling(record: Recordable) {
|
||||
openSModalDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
function batchHandleDelete() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
message.warning('未选中任何数据');
|
||||
return;
|
||||
}
|
||||
batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
/*
|
||||
* 开启/关闭咨询
|
||||
* */
|
||||
function handleClose(record: Recordable) {
|
||||
let params = {};
|
||||
let isAccept = record.isAccept === '3';
|
||||
if (isAccept) {
|
||||
params['id'] = record.id;
|
||||
} else {
|
||||
params['doctorId'] = record.id;
|
||||
params['doctorName'] = record.doctorName;
|
||||
}
|
||||
getStatus(params, handleSuccess, isAccept);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'consultation:con_doctor:edit',
|
||||
},
|
||||
{
|
||||
label: '排班',
|
||||
onClick: handleScheduling.bind(null, record),
|
||||
},
|
||||
{
|
||||
type: record.isAccept === '1' ? 'danger' : 'primary',
|
||||
label: record.isAccept === '1' ? '关闭咨询' : '开启咨询',
|
||||
onClick: handleClose.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
async function changeSwitch(record) {
|
||||
console.log(record);
|
||||
try {
|
||||
const params = {
|
||||
id: record.id,
|
||||
type: record.tfRecommend,
|
||||
};
|
||||
await recommendApi(params);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
function restPass(record: Recordable) {
|
||||
restPaddModel(true, {
|
||||
record: record.id,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
// 1 锁定用户 2 激活用户
|
||||
function handleUserOpt(record: Recordable, type: any) {
|
||||
const params = {
|
||||
userId: record.id,
|
||||
status: type,
|
||||
};
|
||||
lockUser(params, type, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* @Description:导出到记录表
|
||||
* @date 2023/7/3
|
||||
*/
|
||||
async function onExportXls() {
|
||||
const form = getForm().getFieldsValue();
|
||||
await exportFile(form);
|
||||
}
|
||||
|
||||
function openRecordDrawer(code: string, title: string) {
|
||||
taskCode.value = code;
|
||||
drawerTitle.value = title;
|
||||
setTimeout(() => {
|
||||
openDrawer(true, {});
|
||||
}, 500);
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
function getDropDownAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'consultation:con_doctor: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),
|
||||
},
|
||||
];
|
||||
}
|
||||
function stopService() {
|
||||
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
|
||||
return message.warn('请选择一条数据!');
|
||||
}
|
||||
let id = selectedRowKeys.value[0];
|
||||
let dataSource = getDataSource();
|
||||
let record = dataSource.filter((item) => item.id === id)[0];
|
||||
openServiceModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-popover-buttons) {
|
||||
display: flex !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,64 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
//排班
|
||||
list = '/health-consultation/consultation/conDoctorSchedulingDate/list',
|
||||
save = '/health-consultation/conDoctor/add',
|
||||
edit = '/health-consultation/conDoctor/edit',
|
||||
deleteOne = '/health-consultation/conDoctor/delete',
|
||||
deleteBatch = '/health-consultation/conDoctor/deleteBatch',
|
||||
importExcel = '/health-consultation/conDoctor/importExcel',
|
||||
exportXls = '/health-consultation/conDoctor/exportXls',
|
||||
}
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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 url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '工作日',
|
||||
align: 'center',
|
||||
dataIndex: 'week',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '视频咨询时间',
|
||||
align: 'center',
|
||||
dataIndex: 'consultationTime',
|
||||
slots: { customRender: 'consultationTime' },
|
||||
},
|
||||
{
|
||||
title: '在线时间',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
];
|
||||
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [];
|
||||
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '视频咨询时间',
|
||||
field: 'scheduling_date',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '在线时间',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
|
||||
// 生成随机字符
|
||||
export function randomKey(keyLength = 18) {
|
||||
let rlt = '';
|
||||
for (let i = 0; i < keyLength; i++) {
|
||||
if (Math.round(Math.random())) {
|
||||
rlt += Math.ceil(Math.random() * 9);
|
||||
} else {
|
||||
const ranNum = Math.ceil(Math.random() * 23);
|
||||
if (Math.round(Math.random())) {
|
||||
rlt += String.fromCharCode(65 + ranNum);
|
||||
} else {
|
||||
rlt += String.fromCharCode(97 + ranNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rlt;
|
||||
}
|
||||
|
||||
export const week_text = (key) => {
|
||||
const type = {
|
||||
1: '星期一',
|
||||
2: '星期二',
|
||||
3: '星期三',
|
||||
4: '星期四',
|
||||
5: '星期五',
|
||||
6: '星期六',
|
||||
7: '星期日',
|
||||
};
|
||||
return type[key];
|
||||
};
|
||||
|
||||
export function processingData(res) {
|
||||
const arr: any[] = [];
|
||||
|
||||
function createItem(item: any, typeDictText: string, type: string): any {
|
||||
return {
|
||||
...item,
|
||||
week_dictText: week_text([item['week']]),
|
||||
type_dictText: typeDictText,
|
||||
count: item[type],
|
||||
key: randomKey(),
|
||||
type: type,
|
||||
};
|
||||
}
|
||||
|
||||
res.forEach((item) => {
|
||||
const am = createItem(item, '上午', 'amNum');
|
||||
const pm = createItem(item, '下午', 'pmNum');
|
||||
arr.push(am, pm);
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
export function processStatus(id, status) {
|
||||
return {
|
||||
id,
|
||||
...status,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
|
||||
<div class="form-container">
|
||||
<BasicForm @register="registerForm" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../statistics.data';
|
||||
import { saveOrUpdate } from '../statistics.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
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,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let data = {
|
||||
...(await validate()),
|
||||
};
|
||||
//调整数据参数
|
||||
let setData = {
|
||||
conDoctor: {
|
||||
award: data.award,
|
||||
contactAddress: data.contactAddress,
|
||||
nationality: data.nationality,
|
||||
nativePlace: data.nativePlace,
|
||||
email: data.email,
|
||||
birthDate: data.birthDate,
|
||||
departmentName: data.departmentName,
|
||||
doctorTitle: data.doctorTitle,
|
||||
idCard: data.idCard,
|
||||
eq: data.eq,
|
||||
experience: data.experience,
|
||||
goodAt: data.goodAt,
|
||||
workHistory: data.workHistory,
|
||||
isAccept: data.isAccept,
|
||||
joinWork: data.joinWork,
|
||||
phone: data.phone,
|
||||
outTime: data.outTime,
|
||||
resourceName: data.resourceName,
|
||||
school: data.school,
|
||||
sex: data.sex,
|
||||
type: data.type,
|
||||
registrationTime: data.registrationTime,
|
||||
},
|
||||
sysUserModel: {
|
||||
username: data.username,
|
||||
password: data.password,
|
||||
avatar: data.avatar,
|
||||
email: data.email,
|
||||
idCard: data.idCard,
|
||||
phone: data.phone,
|
||||
sex: data.sex,
|
||||
},
|
||||
};
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(setData, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.form-container {
|
||||
height: 65vh;
|
||||
overflow: auto;
|
||||
}
|
||||
.title {
|
||||
box-sizing: border-box;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,54 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
enum Api {
|
||||
list = '/health-consultation/conDoctor/statisticalList',
|
||||
save = '/health-consultation/conDoctor/add',
|
||||
edit = '/health-consultation/conDoctor/edit',
|
||||
deleteOne = '/health-consultation/conDoctor/delete',
|
||||
deleteBatch = '/health-consultation/conDoctor/deleteBatch',
|
||||
importExcel = '/health-consultation/conDoctor/importExcel',
|
||||
exportXls = '/health-consultation/conDoctor/exportXls',
|
||||
}
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
* @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 });
|
||||
};
|
||||
@@ -0,0 +1,148 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { BODY_CONTAINER } from '/@/utils/domUtils';
|
||||
import { selectResourceList } from '/@/views/consult/doctor/message/conDoctor.api';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
customRender: ({ index }) => {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '专家姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'doctorName',
|
||||
},
|
||||
{
|
||||
title: '所属医院',
|
||||
align: 'center',
|
||||
dataIndex: 'resourceName',
|
||||
},
|
||||
{
|
||||
title: '所属科室',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '进行中',
|
||||
align: 'center',
|
||||
dataIndex: 'ongoing',
|
||||
},
|
||||
{
|
||||
title: '咨询统计',
|
||||
align: 'center',
|
||||
dataIndex: 'total',
|
||||
},
|
||||
{
|
||||
title: '图文统计',
|
||||
align: 'center',
|
||||
dataIndex: 'graphic',
|
||||
},
|
||||
{
|
||||
title: '视频统计',
|
||||
align: 'center',
|
||||
dataIndex: 'audioVideo',
|
||||
},
|
||||
{
|
||||
title: '满意度',
|
||||
align: 'center',
|
||||
dataIndex: 'satisfaction',
|
||||
},
|
||||
{
|
||||
title: '24小时回复率',
|
||||
align: 'center',
|
||||
dataIndex: 'rate',
|
||||
},
|
||||
{
|
||||
title: '热度',
|
||||
align: 'center',
|
||||
dataIndex: 'degreeHeat',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '专家姓名',
|
||||
field: 'doctorName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '选择时间',
|
||||
field: 'date',
|
||||
component: 'RangePicker',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
valueType: 'Date',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
getPopupContainer: () => BODY_CONTAINER,
|
||||
'onUpdate:value': (value) => {
|
||||
if (value) {
|
||||
formModel.startTime = value[0];
|
||||
formModel.endTime = value[1];
|
||||
} else {
|
||||
formModel.startTime = null;
|
||||
formModel.endTime = null;
|
||||
}
|
||||
},
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '所属医院',
|
||||
field: 'resourceId',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
api: selectResourceList,
|
||||
resultField: 'list',
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
immediate: true,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.label.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '所属科室',
|
||||
field: 'departmentId',
|
||||
component: 'JTreeDepartment',
|
||||
componentProps: () => {
|
||||
return {
|
||||
allDep: true,
|
||||
placeholder: '请选择科室',
|
||||
showSearch: true,
|
||||
treeNodeFilterProp: 'label',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'startTime',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'endTime',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [];
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
*/
|
||||
export function getBpmFormSchema(): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-statistics" setup>
|
||||
import { BasicTable } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns, searchFormSchema } from './statistics.data';
|
||||
import { list } from './statistics.api';
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'con_doctor',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
showActionColumn: false,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable] = tableContext;
|
||||
</script>
|
||||
@@ -0,0 +1,50 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
export enum Api {
|
||||
list = '/health-im/sync/group/list',
|
||||
terminate = '/health-im/sync/group/terminate',
|
||||
deleteOne = '/health-im/sync/group/delete/',
|
||||
}
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params: any) => defHttp.get({ url: Api.list, params });
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params: any, handleSuccess: Function) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 终止
|
||||
* @param id
|
||||
* @param handleSuccess
|
||||
*/
|
||||
export const terminate = (id: string, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认结束',
|
||||
content: '是否强制结束同步',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.post({ url: Api.terminate + '/' + id }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
//0-未开始 1-正在同步 2-同步结束 3-同步错误
|
||||
export const stateMap = new Map([
|
||||
[0, '未开始'],
|
||||
[1, '正在同步'],
|
||||
[2, '同步结束'],
|
||||
[3, '同步错误'],
|
||||
]);
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '群组ID',
|
||||
dataIndex: 'groupId',
|
||||
},
|
||||
{
|
||||
title: '同步开始时间',
|
||||
dataIndex: 'startTime',
|
||||
},
|
||||
{
|
||||
title: '同步结束时间',
|
||||
dataIndex: 'endTime',
|
||||
},
|
||||
{
|
||||
title: '同步状态',
|
||||
dataIndex: 'syncStatus',
|
||||
customRender: ({ record }) => {
|
||||
return stateMap.get(record?.['syncStatus']) || '';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '错误信息',
|
||||
dataIndex: 'errorMsg',
|
||||
},
|
||||
{
|
||||
title: '获取总消息数',
|
||||
dataIndex: 'fetchMsgCount',
|
||||
},
|
||||
{
|
||||
title: '已存在消息数',
|
||||
dataIndex: 'existMsgCount',
|
||||
},
|
||||
{
|
||||
title: '新同步消息数',
|
||||
dataIndex: 'syncMsgCount',
|
||||
},
|
||||
];
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'groupId',
|
||||
label: '群组ID',
|
||||
component: 'Input',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'date',
|
||||
label: '同步时间',
|
||||
component: 'RangeDate',
|
||||
},
|
||||
{
|
||||
field: 'syncStatus',
|
||||
label: '同步状态',
|
||||
component: 'Select',
|
||||
componentProps: () => {
|
||||
return {
|
||||
options: Array.from(stateMap).map((item) => ({ label: item[1], value: item[0] })),
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<BasicTable :rowSelection="rowSelection" @register="registerTable">
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns, searchFormSchema } from '/@/views/consult/groupRecordSynchronization/groupRecordSynchronization.data';
|
||||
import { deleteOne, list, terminate } from '/@/views/consult/groupRecordSynchronization/groupRecordSynchronization.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '群组记录同步',
|
||||
api: list,
|
||||
columns: columns,
|
||||
canResize: false,
|
||||
showIndexColumn: true,
|
||||
formConfig: {
|
||||
labelWidth: 100,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [['date', ['startTimeStart', 'startTimeEnd'], 'YYYY-MM-DD']],
|
||||
},
|
||||
beforeFetch: (par) => {
|
||||
if (par['startTimeStart']) {
|
||||
par['startTimeStart'] = par['startTimeStart'] + ' 00:00:00';
|
||||
par['startTimeEnd'] = par['startTimeEnd'] + ' 23:59:59';
|
||||
}
|
||||
return par;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 150,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload, getForm, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
function handleClose(record: Recordable) {
|
||||
if (record?.syncStatus == '2') {
|
||||
return message.warn('当前已同步结束!');
|
||||
}
|
||||
terminate(record.id, handleSuccess);
|
||||
}
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne(record.id, handleSuccess);
|
||||
}
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '强制结束',
|
||||
onClick: handleClose.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
:showFooter="showFooter"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
:maskClosable="false"
|
||||
:width="adaptiveWidth"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<div class="form-container">
|
||||
<div class="title"><strong>基本信息</strong></div>
|
||||
<BasicForm @register="registerForm" />
|
||||
<!-- <div class="title"><strong>扩展信息</strong></div>-->
|
||||
<!-- <BasicForm @register="registerFormData" />-->
|
||||
<!-- <div class="title"><strong>其它信息</strong></div>-->
|
||||
<!-- <BasicForm @register="registerFormOther" />-->
|
||||
</div>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema, formSchemaData, formSchemaOther } from '../conHelper.data';
|
||||
import { saveOrUpdate } from '../conHelper.api';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
|
||||
import { dealPassword } from '/@/views/system/user/user.data';
|
||||
|
||||
const { adaptiveWidth } = useDrawerAdaptiveWidth();
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref<boolean>(true);
|
||||
const showFooter = ref<boolean>(true);
|
||||
const state = ref({});
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate, updateSchema }] = useForm({
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
labelWidth: 100,
|
||||
});
|
||||
//表单配置扩展
|
||||
const [
|
||||
registerFormData,
|
||||
{ setProps: setPropsData, setFieldsValue: setFieldsValueData, validate: validateData, clearValidate: clearValidateData },
|
||||
] = useForm({
|
||||
schemas: formSchemaData,
|
||||
showActionButtonGroup: false,
|
||||
labelWidth: 100,
|
||||
});
|
||||
//表单配置其他
|
||||
const [
|
||||
registerFormOther,
|
||||
{ setProps: setPropsOther, setFieldsValue: setFieldsValueOther, validate: validateOther, clearValidate: clearValidateOther },
|
||||
] = useForm({
|
||||
schemas: formSchemaOther,
|
||||
showActionButtonGroup: false,
|
||||
labelWidth: 100,
|
||||
});
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
state.value = data.record;
|
||||
showFooter.value = data.showFooter;
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setDrawerProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
await updateSchema([{ field: 'password', ifShow: false }]);
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record.conHelper,
|
||||
...data.record.sysUserModel,
|
||||
secondDepartment: data.record.conHelper.secondDepartId,
|
||||
thirdDepartment: data.record.conHelper.thirdDepartId,
|
||||
status: data.record.conHelper.status + '',
|
||||
});
|
||||
await setFieldsValueData({
|
||||
...data.record.conHelper,
|
||||
...data.record.sysUserModel,
|
||||
});
|
||||
await setFieldsValueOther({
|
||||
...data.record.conHelper,
|
||||
...data.record.sysUserModel,
|
||||
});
|
||||
await clearValidate();
|
||||
await clearValidateData();
|
||||
await clearValidateOther();
|
||||
} else {
|
||||
await updateSchema([
|
||||
{
|
||||
field: 'password',
|
||||
ifShow: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
// await setPropsData({ disabled: !data?.showFooter });
|
||||
// await setPropsOther({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let data = {
|
||||
...(await validate()),
|
||||
// ...(await validateData()),
|
||||
// ...(await validateOther()),
|
||||
};
|
||||
let passwordObj = {};
|
||||
if (!isUpdate.value) {
|
||||
passwordObj = {
|
||||
password: dealPassword(data?.password),
|
||||
};
|
||||
}
|
||||
//调整数据参数
|
||||
let setData = {
|
||||
conHelper: {
|
||||
id: data?.id,
|
||||
goodAt: data?.goodAt,
|
||||
orgCode: data?.orgCode,
|
||||
helperName: data?.helperName,
|
||||
status: data?.status || 1,
|
||||
},
|
||||
sysUserModel: {
|
||||
id: data?.id,
|
||||
avatar: data?.avatar,
|
||||
email: data?.email,
|
||||
idCard: data?.idCard,
|
||||
phone: data?.phone,
|
||||
sex: data?.sex,
|
||||
username: data?.username,
|
||||
...passwordObj,
|
||||
secondDepartment: data?.secondDepartment,
|
||||
thirdDepartment: data?.thirdDepartment,
|
||||
},
|
||||
};
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(setData, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeDrawer();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.form-container {
|
||||
overflow: auto;
|
||||
}
|
||||
.title {
|
||||
box-sizing: border-box;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800">
|
||||
<div class="history-modal">
|
||||
<BasicForm
|
||||
:labelWidth="80"
|
||||
:schemas="schedulingSearchSchema"
|
||||
:baseColProps="colOptions"
|
||||
:actionColOptions="colOptions"
|
||||
@submit="handleSubmit"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
<a-table
|
||||
:columns="schedulingColumns"
|
||||
:pagination="paginationState"
|
||||
@change="changeTable"
|
||||
:data-source="customState.customData"
|
||||
border
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicForm from '/@/components/Form/src/BasicForm.vue';
|
||||
import { schedulingColumns, schedulingSearchSchema, SchedulingState } from '/@/views/consult/helper/conHelper.data';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { schedulingRecord } from '/@/views/consult/helper/conHelper.api';
|
||||
const title = '历史排班记录';
|
||||
const colOptions = {
|
||||
offset: 0,
|
||||
span: 12,
|
||||
xs: 12, // <576px
|
||||
sm: 12, // ≥576px
|
||||
md: 12, // ≥768px
|
||||
lg: 12, // ≥992px
|
||||
xl: 12, // ≥1200px
|
||||
xxl: 12, // ≥1600px
|
||||
};
|
||||
let paginationState = ref({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showSizeChanger: false,
|
||||
total: 0,
|
||||
showQuickJumper: true,
|
||||
size: 'small',
|
||||
showTotal: (total: number) => ' 共 ' + total / 2 + ' 条数据',
|
||||
});
|
||||
const customState = reactive<SchedulingState>({
|
||||
form: {
|
||||
date: '',
|
||||
type: '',
|
||||
},
|
||||
customData: [],
|
||||
apiData: [],
|
||||
});
|
||||
const [registerModal, { setModalProps }] = useModalInner(() => {
|
||||
setModalProps({ showCancelBtn: false, showOkBtn: false });
|
||||
getCustomList();
|
||||
});
|
||||
function getCustomList(pageNo?: number) {
|
||||
const pageSize = paginationState.value.pageSize === 10 ? 5 : paginationState.value.pageSize / 2;
|
||||
const params = {
|
||||
...customState.form,
|
||||
pageNo: pageNo ?? paginationState.value.current,
|
||||
pageSize: pageSize,
|
||||
};
|
||||
schedulingRecord(params).then((res) => {
|
||||
const { current, total, records = [] } = res;
|
||||
function dealRes() {
|
||||
let arr: any[] = [];
|
||||
records?.map((item: any) => {
|
||||
let amUser = item?.detail[0].dataList?.map((p) => p.userName) || [];
|
||||
let pmUser = item?.detail[1].dataList?.map((p) => p.userName) || [];
|
||||
arr.push({ ...item?.detail[0], helper: amUser.join(', '), time: item?.time });
|
||||
arr.push({ ...item?.detail[1], helper: pmUser.join(', '), time: item?.time });
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
customState.customData = dealRes();
|
||||
customState.apiData = records;
|
||||
paginationState.value = {
|
||||
...paginationState.value,
|
||||
current,
|
||||
total: total * 2,
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @Description:页码改变事件
|
||||
* @date 2023/6/20
|
||||
* @param pagination
|
||||
*/
|
||||
const changeTable = (pagination: { current: number; pageSize: number }) => {
|
||||
paginationState.value.current = pagination.current;
|
||||
paginationState.value.pageSize = pagination.pageSize;
|
||||
getCustomList();
|
||||
};
|
||||
function handleSubmit(val) {
|
||||
customState.form = val;
|
||||
getCustomList(1);
|
||||
}
|
||||
function handleReset() {
|
||||
customState.form = {};
|
||||
getCustomList(1);
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.history-modal {
|
||||
height: 60vh;
|
||||
min-height: 60vh;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @cancel="handleCancel">
|
||||
<a-table :columns="columns" :data-source="state.columnData" :pagination="false" border size="small">
|
||||
<template #bodyCell="{ column, record, text }">
|
||||
<template v-if="column.dataIndex === 'departmentName'">
|
||||
<div class="editable-cell">
|
||||
<div v-if="editableData[record.key]" class="editable-cell-input-wrapper">
|
||||
<a-select
|
||||
v-model:value="editableData[record.key].selectVal"
|
||||
:options="selectOptions"
|
||||
mode="multiple"
|
||||
placeholder="请选择值班人员"
|
||||
:fieldNames="fieldNames"
|
||||
optionLabelProp="userName"
|
||||
style="min-width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="editable-cell-text-wrapper">
|
||||
{{ text || ' ' }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a v-if="!editableData[record.key]" @click.prevent="edit(record.key)">编辑</a>
|
||||
<span v-else>
|
||||
<a @click.prevent="save(record.key)">保存 </a>
|
||||
<a style="margin-left: 10px" @click.prevent="noSave(record.key)">取消</a>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { columns } from '../scheduling.data';
|
||||
import { getHelperIds, list, updateHelper } from '../scheduling.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
//设置标题
|
||||
const title = '排班设置';
|
||||
const fieldNames = { label: 'userName', value: 'id' };
|
||||
const state = ref({
|
||||
columnData: [],
|
||||
});
|
||||
const checkKey = ref('');
|
||||
let editableData = reactive({});
|
||||
const selectOptions = ref([]);
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
|
||||
setModalProps({ showCancelBtn: false, showOkBtn: false });
|
||||
initOption();
|
||||
initData();
|
||||
});
|
||||
|
||||
function initOption() {
|
||||
getHelperIds({}).then((res) => {
|
||||
selectOptions.value = res;
|
||||
});
|
||||
}
|
||||
|
||||
function dealData(data) {
|
||||
data.map((item, i) => {
|
||||
item.key = `${i}`;
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
async function initData() {
|
||||
let res = await list({});
|
||||
state.value.columnData = dealData(res);
|
||||
}
|
||||
|
||||
function edit(key) {
|
||||
let row = state.value.columnData.filter((item) => key === item.key)[0];
|
||||
const names = row?.departmentName.split(',');
|
||||
let values = getValues(names);
|
||||
editableData[key] = { row: row, selectVal: values };
|
||||
checkKey.value = key;
|
||||
}
|
||||
|
||||
function getLabel(selectVal) {
|
||||
let labels = [];
|
||||
selectOptions.value.forEach((item) => {
|
||||
if (selectVal.includes(item[fieldNames.value])) {
|
||||
labels.push(item[fieldNames.label]);
|
||||
}
|
||||
});
|
||||
return labels.join(',');
|
||||
}
|
||||
|
||||
function getValues(labels) {
|
||||
let values = [];
|
||||
selectOptions.value.forEach((item) => {
|
||||
if (labels.includes(item[fieldNames.label])) {
|
||||
values.push(item[fieldNames.value]);
|
||||
}
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
async function updateData(params) {
|
||||
if (params) {
|
||||
await updateHelper(params);
|
||||
}
|
||||
}
|
||||
|
||||
function save(key: string) {
|
||||
const { selectVal } = editableData[key];
|
||||
let labels = getLabel(selectVal);
|
||||
const params = {
|
||||
type: editableData[key]?.row?.type,
|
||||
week: editableData[key]?.row?.week,
|
||||
userIds: editableData[key].selectVal.join(','),
|
||||
userNames: getLabel(editableData[key].selectVal),
|
||||
};
|
||||
Object.assign(state.value.columnData.filter((item) => key === item.key)[0], {
|
||||
...editableData[key].row,
|
||||
departmentName: labels,
|
||||
});
|
||||
updateData(params);
|
||||
delete editableData[key];
|
||||
}
|
||||
|
||||
function noSave(key) {
|
||||
editableData[key].selectVal = state.value.columnData[key]?.list?.map((item) => item.userId) || [];
|
||||
delete editableData[key];
|
||||
}
|
||||
|
||||
function clearData() {
|
||||
state.value.columnData = [];
|
||||
editableData = {};
|
||||
checkKey.value = '';
|
||||
}
|
||||
|
||||
//表单提交事件
|
||||
function handleCancel() {
|
||||
try {
|
||||
if (checkKey.value !== '') {
|
||||
noSave(checkKey.value);
|
||||
}
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
clearData();
|
||||
}
|
||||
}
|
||||
defineExpose({});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(table tr, table th, table td) {
|
||||
border-right: 1px solid #f0f0f0 !important;
|
||||
border-bottom: 1px solid #f0f0f0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/conHelper/list',
|
||||
save = '/health-consultation/conHelper/add',
|
||||
edit = '/health-consultation/conHelper/edit',
|
||||
deleteOne = '/health-consultation/conHelper/delete',
|
||||
deleteBatch = '/health-consultation/conHelper/deleteBatch',
|
||||
importExcel = '/health-consultation/conHelper/importExcel',
|
||||
exportXls = '/health-consultation/conHelper/exportXls',
|
||||
queryById = '/health-consultation/conHelper/queryById',
|
||||
schedulingRecord = '/health-consultation/consultation/conHelperSchedulingHistory/list',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 获取小助手信息详情
|
||||
* @param params 请求参数
|
||||
* */
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
// 排班记录
|
||||
export const schedulingRecord = (params) => defHttp.get({ url: Api.schedulingRecord, params });
|
||||
@@ -0,0 +1,404 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { h, ref } from 'vue';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
import { Image } from 'ant-design-vue';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
dataIndex: 'userAccount',
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
dataIndex: 'userName',
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
align: 'center',
|
||||
dataIndex: 'faceUrl',
|
||||
width: 100,
|
||||
customRender: ({ text, record }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getFamaleDefaultImage(record.sex),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
align: 'center',
|
||||
dataIndex: 'idCard',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '手机号',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
dataIndex: 'phone',
|
||||
},
|
||||
{
|
||||
title: '账号状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
if (!text) return '';
|
||||
if (text == '1') {
|
||||
return '正常';
|
||||
} else {
|
||||
return '冻结';
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'userName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phoneOrIdCard',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '账号状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
// @ts-ignore//@ts-ignore
|
||||
dictCode: 'freeze_status',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
label: '',
|
||||
field: 'secondOrgId',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
const orgCode = ref('');
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
// 主键Id
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
show: false,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
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: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
// @ts-ignore//@ts-ignore
|
||||
dictCode: 'freeze_status',
|
||||
},
|
||||
show: ({ values }) => {
|
||||
return values.id;
|
||||
},
|
||||
defaultValue: '1',
|
||||
},
|
||||
{
|
||||
label: '密码',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
autocomplete: 'new-password',
|
||||
readOnly: true,
|
||||
onfocus: (field) => {
|
||||
field.target.readOnly = false;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
let { message } = checkPassword(value);
|
||||
if (message === 'ok') {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(message);
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
},
|
||||
show: ({ values }) => {
|
||||
return !values.id;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '姓名',
|
||||
field: 'helperName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
component: 'JDictSelectTag',
|
||||
label: '性别',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'sex2',
|
||||
type: 'radio',
|
||||
},
|
||||
rules: [{ required: true, message: '请选择性别' }],
|
||||
},
|
||||
{
|
||||
field: 'avatar',
|
||||
label: '头像',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
maxCount: 1,
|
||||
},
|
||||
// rules: [{ required: true, message: '请选择头像' }],
|
||||
},
|
||||
{
|
||||
label: '手机号',
|
||||
field: 'phone',
|
||||
component: 'Input',
|
||||
rules: [{ required: true, pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' }],
|
||||
},
|
||||
{
|
||||
label: '身份证号',
|
||||
field: 'idCard',
|
||||
component: 'Input',
|
||||
rules: [{ required: true, pattern: /^\d{18}$/, message: '身份证号格式有误' }],
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱',
|
||||
component: 'Input',
|
||||
rules: [{ required: false, type: 'email', message: '邮箱格式不正确', trigger: 'blur' }],
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
placeholder: '请输入邮箱',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'orgCode',
|
||||
component: 'Input',
|
||||
// @ts-ignore
|
||||
componentProps: ({ formModel }) => {
|
||||
formModel.orgCode = orgCode.value;
|
||||
},
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
//扩展数据
|
||||
export const formSchemaData: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '学历',
|
||||
field: 'qualification',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'education',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '出生年月',
|
||||
field: 'birthday',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '毕业院校',
|
||||
field: 'graduateSchool',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'graduationTime',
|
||||
label: '毕业时间',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '民族',
|
||||
field: 'nationality',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'nation',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '籍贯',
|
||||
field: 'nativePlace',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '联系地址',
|
||||
field: 'address',
|
||||
component: 'Input',
|
||||
},
|
||||
];
|
||||
|
||||
//扩展数据
|
||||
export const formSchemaOther: FormSchema[] = [
|
||||
{
|
||||
field: 'workTime',
|
||||
label: '参加工作时间',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '擅长',
|
||||
field: 'excel',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '职业经历',
|
||||
field: 'practicingExperience',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '获奖或论文',
|
||||
field: 'awardsAndPapers',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
{
|
||||
label: '工作经历',
|
||||
field: 'workHistory',
|
||||
component: 'InputTextArea',
|
||||
},
|
||||
];
|
||||
|
||||
// 排班记录
|
||||
export const schedulingSearchSchema: FormSchema[] = [
|
||||
{
|
||||
label: '排班时间',
|
||||
field: 'date',
|
||||
component: 'RangePicker',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
showTime: false,
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
getPopupContainer: () => document.body,
|
||||
onChange: ([start, end]) => {
|
||||
formModel.startTime = start;
|
||||
formModel.endTime = end;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '开始时间',
|
||||
field: 'startTime',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '结束时间',
|
||||
field: 'endTime',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
// 排班列表
|
||||
export const schedulingColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '排班时间',
|
||||
dataIndex: 'time',
|
||||
key: 'time',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
customCell: (_, index) => {
|
||||
if (index % 2 === 0) {
|
||||
return {
|
||||
rowSpan: 2,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '班次',
|
||||
width: 80,
|
||||
dataIndex: 'type',
|
||||
align: 'center',
|
||||
customRender: ({ text }) => text && render.renderDict(text, 'am_pm'),
|
||||
},
|
||||
{
|
||||
title: '值班人员',
|
||||
key: 'helper',
|
||||
dataIndex: 'helper',
|
||||
},
|
||||
];
|
||||
export interface SchedulingState {
|
||||
form: any;
|
||||
customData: any[];
|
||||
apiData: any[];
|
||||
}
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
*/
|
||||
export function getBpmFormSchema(): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="'consultation:con_helper:add'" @click="handleAdd" preIcon="ant-design:plus-outlined">
|
||||
新增
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleScheduling"> 排班设置 </a-button>
|
||||
<a-button @click="handleSchedulingRecord"> 历史排班记录 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单 -->
|
||||
<ConHelperModal @register="registerDrawer" @success="handleSuccess" />
|
||||
<!-- 排班设置 -->
|
||||
<s-modal @register="registerScheModal" @success="handleSuccess" />
|
||||
<!-- 重置密码 -->
|
||||
<RestPass @register="restPassModal" />
|
||||
<!-- 历史排班记录-->
|
||||
<historical-scheduling-records @register="registerScheduling" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conHelper" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConHelperModal from './components/conHelperModal.vue';
|
||||
import SModal from './components/schedulingModal.vue';
|
||||
import { columns, searchFormSchema } from './conHelper.data';
|
||||
import { deleteOne, list, queryById } from './conHelper.api';
|
||||
import { lockUser } from '/@/views/system/user/hospitalDoctor/HospitalDoctor.api';
|
||||
import RestPass from '/@/views/system/user/restPass/RestPass.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import HistoricalSchedulingRecords from '/@/views/consult/helper/components/historicalSchedulingRecords.vue';
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
//注册model
|
||||
const [registerScheModal, { openModal: openScheModal }] = useModal();
|
||||
const [restPassModal, { openModal: restPaddModel }] = useModal();
|
||||
const [registerScheduling, { openModal: openScheduling }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'con_helper',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 140,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
let res = await queryById({ id: record.id });
|
||||
openDrawer(true, {
|
||||
record: res,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
selectedRowKeys.value = [];
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 排班事件
|
||||
*/
|
||||
function handleScheduling() {
|
||||
openScheModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
// 历史排班记录
|
||||
function handleSchedulingRecord() {
|
||||
openScheduling(true, {
|
||||
isUpdate: false,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'consultation:con_helper:edit',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'consultation:con_helper:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
// 重置密码
|
||||
function restPass(record: Recordable) {
|
||||
restPaddModel(true, {
|
||||
record: record.id,
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
});
|
||||
}
|
||||
// 1 锁定用户 2 激活用户
|
||||
function handleUserOpt(record: Recordable, type: any) {
|
||||
const params = {
|
||||
userId: record.id,
|
||||
status: type,
|
||||
};
|
||||
lockUser(params, type, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
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),
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-popover-buttons) {
|
||||
display: flex !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,77 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
//排班
|
||||
list = '/health-consultation/conHelperScheduling/list',
|
||||
save = '/health-consultation/conHelperScheduling/add',
|
||||
edit = '/health-consultation/conHelperScheduling/edit',
|
||||
deleteOne = '/health-consultation/conHelperScheduling/delete',
|
||||
deleteBatch = '/health-consultation/conHelperScheduling/deleteBatch',
|
||||
importExcel = '/health-consultation/conHelperScheduling/importExcel',
|
||||
exportXls = '/health-consultation/conHelperScheduling/exportXls',
|
||||
getHelperIds = '/health-consultation/conHelper/getHelperIds',
|
||||
updateHelper = '/health-consultation/conHelperScheduling/updateHelperCustom',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
export const getHelperIds = (params) => defHttp.get({ url: Api.getHelperIds, 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
|
||||
* @param isUpdate
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
export const updateHelper = (params) => defHttp.post({ url: Api.updateHelper, params });
|
||||
@@ -0,0 +1,68 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '星期',
|
||||
dataIndex: 'week_dictText',
|
||||
key: 'week_dictText',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
customCell: (_, index: number) => {
|
||||
if (index % 2 === 0) {
|
||||
return {
|
||||
rowSpan: 2,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '班次',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
dataIndex: 'type_dictText',
|
||||
},
|
||||
{
|
||||
title: '值班人员',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
},
|
||||
];
|
||||
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [];
|
||||
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '视频咨询时间',
|
||||
field: 'scheduling_date',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '在线时间',
|
||||
field: 'password',
|
||||
component: 'StrengthMeter',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" :maskClosable="false">
|
||||
<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 { formSchema } from '../conNotice.data';
|
||||
import { saveOrUpdate } from '../conNotice.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, 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;
|
||||
if (unref(isUpdate)) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
await clearValidate();
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(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,98 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conNotice/list',
|
||||
save = '/health-consultation/consultation/conNotice/add',
|
||||
edit = '/health-consultation/consultation/conNotice/edit',
|
||||
deleteOne = '/health-consultation/consultation/conNotice/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conNotice/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/conNotice/importExcel',
|
||||
exportXls = '/health-consultation/consultation/conNotice/exportXls',
|
||||
queryById = '/health-consultation/consultation/conNotice/queryById',
|
||||
status = '/health-consultation/api/consult/notice/on',
|
||||
}
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
params['status'] = '2';
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* @Description:获取详情
|
||||
* @date 2023/6/19
|
||||
* @param: {id}
|
||||
*/
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
/**
|
||||
* 启用/禁用
|
||||
*/
|
||||
export const changeStatus = (params, data, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `启用将会设置其他【${data.noticeType === 0 ? '图文咨询' : '视频咨询'}】须知为禁用,是否确定启用?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.post({ url: Api.status, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
customRender: ({ index }) => {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '标题',
|
||||
align: 'center',
|
||||
dataIndex: 'title',
|
||||
},
|
||||
{
|
||||
title: '咨询类型',
|
||||
align: 'center',
|
||||
dataIndex: 'type_dictText',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
align: 'center',
|
||||
dataIndex: 'createTime',
|
||||
customRender: ({ text }): string => {
|
||||
return !text ? '' : text.length > 10 ? text.substring(0, 10) : text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status',
|
||||
customRender: ({ text }) => {
|
||||
return text && text == '1' ? '启用' : '禁用';
|
||||
},
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '标题',
|
||||
field: 'title',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
options: [
|
||||
{ label: '启用', value: '1' },
|
||||
{ label: '禁用', value: '2' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '咨询类型',
|
||||
field: 'noticeType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'notice_type',
|
||||
},
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '标题',
|
||||
field: 'title',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '咨询类型',
|
||||
field: 'noticeType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
//@ts-ignore
|
||||
dictCode: 'notice_type',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '咨询须知',
|
||||
field: 'content',
|
||||
component: 'JEditor',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
*/
|
||||
export function getBpmFormSchema(): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="null">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="auth.add" type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</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>
|
||||
<!-- 表单区域 -->
|
||||
<con-notice-modal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conNotice" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConNoticeModal from './components/conNoticeModal.vue';
|
||||
import { columns, searchFormSchema } from './conNotice.data';
|
||||
import { list, deleteOne, queryById, changeStatus } from './conNotice.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
const auth = {
|
||||
add: 'consultation:con_notice:add',
|
||||
edit: 'consultation:con_notice:edit',
|
||||
deleteOne: 'consultation:con_notice:delete',
|
||||
deleteBatch: '',
|
||||
};
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '咨询须知',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
let res = await queryById({ id: record.id });
|
||||
openModal(true, {
|
||||
record: res,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
selectedRowKeys.value = [];
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* @Description:启用
|
||||
* @date 2023/8/29
|
||||
* @param record
|
||||
*/
|
||||
function handleStatus(record: Recordable) {
|
||||
changeStatus({ id: record.id }, record, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: auth.edit,
|
||||
},
|
||||
{
|
||||
label: '启用',
|
||||
onClick: handleStatus.bind(null, record),
|
||||
disabled: record.status === '1',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: auth.deleteOne,
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-popover-buttons) {
|
||||
display: flex !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
showFooter
|
||||
destroyOnClose
|
||||
width="40%"
|
||||
:title="isUpdate ? '修改就医信息' : `新增就医信息`"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #name="{ model }">
|
||||
<div style="display: flex">
|
||||
<a-input placeholder="请选择用户" v-model:value="userItem['realName']" :disabled="true" />
|
||||
<a-button type="primary" style="margin-left: 10px" @click="choose"> 选择 </a-button>
|
||||
</div>
|
||||
<div>
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<div style="flex: 1">单位:{{ userItem?.secondName || '--' }}</div>
|
||||
<div style="flex: 1">部门:{{ userItem?.thirdName || '--' }}</div>
|
||||
</div>
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<div>工号:{{ userItem?.workNo || '--' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicDrawer>
|
||||
|
||||
<ChooseSome :width="800" @register="registerUserDrawer" @select-some="onSelectUserOk" title="选择指定员工" :tableprops="tableContext" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
|
||||
import { useDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { formSchema, tableContext } from '/@/views/consult/offlineTreatment/offlineTreatment.data';
|
||||
import ChooseSome from '/@/views/compoents/chooseSome/index.vue';
|
||||
import { ref } from 'vue';
|
||||
import { addApi, editApi } from '/@/views/consult/offlineTreatment/offlineTreatment.api';
|
||||
|
||||
const userItem = ref<object>({});
|
||||
const isUpdate = ref<boolean>(false);
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const [registerForm, { setFieldsValue, validate, resetFields, clearValidate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 24 },
|
||||
});
|
||||
|
||||
const [registerUserDrawer, { openDrawer: openChooseDrawer }] = useDrawer();
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
await resetFields();
|
||||
isUpdate.value = data?.isUpdate;
|
||||
if (isUpdate.value) {
|
||||
userItem.value = {
|
||||
id: data?.record.userId,
|
||||
realName: data?.record.realName,
|
||||
secondName: data?.record?.secondDeptName,
|
||||
thirdName: data?.record?.thirdDeptName,
|
||||
workNo: data?.record?.workNo,
|
||||
orgCode: data?.record?.orgCode,
|
||||
};
|
||||
await setFieldsValue(data?.record);
|
||||
await clearValidate();
|
||||
}
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const val = await validate();
|
||||
if (isUpdate.value) {
|
||||
await editApi(val);
|
||||
} else {
|
||||
await addApi(val);
|
||||
}
|
||||
userItem.value = {};
|
||||
closeDrawer();
|
||||
emit('success');
|
||||
} catch (err: any) {
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
function choose() {
|
||||
openChooseDrawer(true, {
|
||||
selectedRowKeys: [JSON.stringify(userItem.value)],
|
||||
});
|
||||
}
|
||||
|
||||
function onSelectUserOk(e: any) {
|
||||
try {
|
||||
e = JSON.parse(e);
|
||||
} catch (err: any) {
|
||||
e = {};
|
||||
}
|
||||
userItem.value = e;
|
||||
setFieldsValue({
|
||||
userId: e?.id,
|
||||
realName: e?.realName,
|
||||
orgCode: e?.orgCode,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,35 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/emergency/treatment/list',
|
||||
add = '/health-consultation/emergency/treatment/add',
|
||||
edit = '/health-consultation/emergency/treatment/edit',
|
||||
delB = '/health-consultation/emergency/treatment/deleteBatch',
|
||||
del = '/health-consultation/emergency/treatment/delete',
|
||||
}
|
||||
|
||||
export const listApi = (params: any) => defHttp.get({ url: Api.list, params });
|
||||
export const addApi = (params: any) => defHttp.post({ url: Api.add, params });
|
||||
export const editApi = (params: any) => defHttp.post({ url: Api.edit, params });
|
||||
export const delApi = (params: any, handleSuccess: any, type: any) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
if (type === '0') {
|
||||
return defHttp.delete({ url: Api.del, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
return defHttp.post({ url: Api.delB, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,202 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { orgSearchInfo } from '/@/utils/orgSearchInfo';
|
||||
import { ref } from 'vue';
|
||||
import { employListApi } from '/@/views/emergency/communication/components/commApi';
|
||||
import { mColumns } from '/@/views/healthMonitor/healMonitorManage/monitorToll/toolManagement/toolManagement.data';
|
||||
import { userFormSchema } from '/@/views/interveneNew/diabetes/intervene/terminalManagement/terminalManagement.data';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '单位名称',
|
||||
dataIndex: 'secondDeptName',
|
||||
},
|
||||
{
|
||||
title: '部门名称',
|
||||
dataIndex: 'thirdDeptName',
|
||||
},
|
||||
{
|
||||
title: '员工姓名',
|
||||
dataIndex: 'realName',
|
||||
},
|
||||
{
|
||||
title: '员工工号',
|
||||
dataIndex: 'workNo',
|
||||
},
|
||||
{
|
||||
title: '就诊医院',
|
||||
dataIndex: 'hospital',
|
||||
},
|
||||
{
|
||||
title: '就诊医生',
|
||||
dataIndex: 'doctor',
|
||||
},
|
||||
{
|
||||
title: '疾病名称',
|
||||
dataIndex: 'disease',
|
||||
},
|
||||
{
|
||||
title: '患病程度',
|
||||
dataIndex: 'diseaseLevel',
|
||||
},
|
||||
{
|
||||
title: '就医日期',
|
||||
dataIndex: 'treatmentDate',
|
||||
},
|
||||
];
|
||||
|
||||
export const searchForm: FormSchema[] = [
|
||||
...orgSearchInfo(),
|
||||
{
|
||||
field: 'realName',
|
||||
label: '员工姓名',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'workNo',
|
||||
label: '员工工号',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'disease',
|
||||
label: '疾病名称',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'diseaseLevel',
|
||||
label: '患病程度',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'rangeDate',
|
||||
label: '就医日期',
|
||||
component: 'RangeDate',
|
||||
componentProps: () => {
|
||||
return {
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
format: 'YYYY-MM-DD',
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'realName',
|
||||
label: '员工信息',
|
||||
component: 'Input',
|
||||
slot: 'name',
|
||||
},
|
||||
{
|
||||
field: 'hospital',
|
||||
label: '就诊医院',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'doctor',
|
||||
label: '就诊医生',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'disease',
|
||||
label: '疾病名称',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'diseaseLevel',
|
||||
label: '患病程度',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'treatmentDate',
|
||||
label: '就医日期',
|
||||
component: 'DatePicker',
|
||||
componentProps: () => ({ valueFormat: 'YYYY-MM-DD', format: 'YYYY-MM-DD', style: { width: '100%' } }),
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'memo',
|
||||
label: '备注',
|
||||
component: 'InputTextArea',
|
||||
componentProps: () => ({ rows: 5 }),
|
||||
},
|
||||
{
|
||||
field: 'orgCode',
|
||||
label: '',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
field: 'userId',
|
||||
label: '',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
label: '',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
export const tableContext = ref({
|
||||
tableProps: {
|
||||
title: '选择指定员工',
|
||||
api: employListApi,
|
||||
columns: [
|
||||
...mColumns.slice(0, 2),
|
||||
{
|
||||
title: '员工工号',
|
||||
dataIndex: ['extension', 'empNo'],
|
||||
align: 'center',
|
||||
},
|
||||
],
|
||||
canResize: false,
|
||||
clearSelectOnPageChange: false,
|
||||
formConfig: {
|
||||
labelWidth: 63,
|
||||
schemas: userFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
baseColProps: {
|
||||
xs: 8,
|
||||
sm: 8,
|
||||
md: 8,
|
||||
lg: 8,
|
||||
xl: 12,
|
||||
xxl: 12,
|
||||
},
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
xs: 8,
|
||||
sm: 8,
|
||||
md: 8,
|
||||
lg: 8,
|
||||
xl: 12,
|
||||
xxl: 12,
|
||||
},
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
// params['orgCode'] = user?.userInfo?.orgCode?.substring(0, 6);
|
||||
return params;
|
||||
},
|
||||
showActionColumn: false,
|
||||
rowKey: (record: Recordable) =>
|
||||
JSON.stringify({
|
||||
id: record.id,
|
||||
realName: record.realname,
|
||||
secondName: record?.secondDepart?.departName,
|
||||
thirdName: record?.threeDepart?.departName,
|
||||
workNo: record?.workNo,
|
||||
orgCode: record?.orgCode,
|
||||
}),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" :row-selection="rowSelection">
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="`offline-treatment:add-button`" type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">
|
||||
新增
|
||||
</a-button>
|
||||
<a-button v-auth="`offline-treatment:add-button`" type="primary" @click="handleDeleteB" preIcon="ant-design:plus-outlined">
|
||||
批量删除
|
||||
</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
|
||||
<add-drawer @register="registerDrawer" @success="handleSuccess" />
|
||||
</template>
|
||||
<script setup lang="ts" name="consult-offlineTreatment-offlineTreatment">
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns, searchForm } from '/@/views/consult/offlineTreatment/offlineTreatment.data';
|
||||
import { delApi, listApi } from '/@/views/consult/offlineTreatment/offlineTreatment.api';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import AddDrawer from '/@/views/consult/offlineTreatment/components/addDrawer.vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '就医记录',
|
||||
api: listApi,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchForm,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [['rangeDate', ['startDate', 'endDate']]],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { selectedRowKeys, rowSelection }] = tableContext;
|
||||
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
isUpdate: true,
|
||||
record,
|
||||
});
|
||||
}
|
||||
function handleDelete(record: Recordable) {
|
||||
try {
|
||||
delApi({ id: record?.id }, handleSuccess, '0');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
function handleDeleteB() {
|
||||
if (selectedRowKeys.value.length === 0) return message.warn('请至少选择一条数据');
|
||||
try {
|
||||
delApi({ ids: selectedRowKeys.value }, handleSuccess, '1');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @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 { formSchema } from '../conPhrases.data';
|
||||
import { saveOrUpdate } from '../conPhrases.api';
|
||||
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
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,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(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,71 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/phrases/list',
|
||||
save = '/health-consultation/consultation/phrases/add',
|
||||
edit = '/health-consultation/consultation/phrases/edit',
|
||||
deleteOne = '/health-consultation/consultation/phrases/delete',
|
||||
deleteBatch = '/health-consultation/consultation/phrases/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/phrases/importExcel',
|
||||
exportXls = '/health-consultation/consultation/phrases/exportXls',
|
||||
}
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () =>
|
||||
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 url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { useUserStoreWithOut } from '/@/store/modules/user';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
dataIndex: 'number',
|
||||
width: 70,
|
||||
},
|
||||
{
|
||||
title: '常用语内容',
|
||||
align: 'center',
|
||||
dataIndex: 'content',
|
||||
},
|
||||
{
|
||||
title: '所属角色',
|
||||
align: 'center',
|
||||
dataIndex: 'personType',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'p_type');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '所属用户',
|
||||
align: 'center',
|
||||
dataIndex: 'userName',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status',
|
||||
customRender: ({ text }) => {
|
||||
if (text == '0') {
|
||||
return '启用';
|
||||
} else {
|
||||
return '禁用';
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '常用语',
|
||||
field: 'content',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '角色',
|
||||
field: 'personType',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
options: [
|
||||
{
|
||||
label: '员工',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '小助手',
|
||||
value: '2',
|
||||
},
|
||||
{
|
||||
label: '专家',
|
||||
value: '3',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
dictCode: 'switch_status',
|
||||
},
|
||||
},
|
||||
];
|
||||
const userId = useUserStoreWithOut().getUserInfo.id;
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '所属角色',
|
||||
field: 'personType',
|
||||
component: 'JDictSelectTag',
|
||||
rules: [{ required: true, message: '请选择人员类型' }],
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
options: [
|
||||
{
|
||||
label: '员工',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '小助手',
|
||||
value: '2',
|
||||
},
|
||||
{
|
||||
label: '专家',
|
||||
value: '3',
|
||||
},
|
||||
],
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '常用语内容',
|
||||
field: 'content',
|
||||
component: 'InputTextArea',
|
||||
rules: [{ required: true, message: '请输入常用语内容' }],
|
||||
},
|
||||
{
|
||||
label: '所属用户',
|
||||
field: 'userId',
|
||||
component: 'Input',
|
||||
show: (formSchema) => formSchema.field === userId,
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
// @ts-ignore
|
||||
dictCode: 'switch_status',
|
||||
getPopupContainer: () => document.body,
|
||||
},
|
||||
defaultValue: '0',
|
||||
rules: [{ required: true, message: '请选择状态' }],
|
||||
},
|
||||
{
|
||||
label: '序号',
|
||||
field: 'number',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
{
|
||||
label: '主键隐藏字段,目前写死为ID',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
*/
|
||||
export function getBpmFormSchema(): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="null">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-auth="auth.add" type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<con-phrases-modal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conPhrases" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConPhrasesModal from './components/conPhrasesModal.vue';
|
||||
import { columns, searchFormSchema } from './conPhrases.data';
|
||||
import { list, deleteOne } from './conPhrases.api';
|
||||
const auth = {
|
||||
add: 'consultation:con_phrases:add',
|
||||
edit: 'consultation:con_phrases:edit',
|
||||
deleteOne: 'consultation:con_phrases:delete',
|
||||
};
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'con_phrases',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
selectedRowKeys.value = [];
|
||||
reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: auth.edit,
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: auth.deleteOne,
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface Position {
|
||||
lng: string | number;
|
||||
lat: string | number;
|
||||
[k: string]: any;
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
@register="registerModal"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
:width="1000"
|
||||
@ok="handleSubmit"
|
||||
@cancel="clearData"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div class="map-search-box">
|
||||
<a-select
|
||||
v-model:value="intValue"
|
||||
allow-clear
|
||||
show-search
|
||||
id="tipinput"
|
||||
placeholder="请输入地点"
|
||||
style="width: 400px"
|
||||
:default-active-first-option="false"
|
||||
:show-arrow="true"
|
||||
:filter-option="false"
|
||||
:not-found-content="null"
|
||||
@search="onSearch"
|
||||
:options="panelList"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<a-button type="primary" @click="onButtonSearch"> 搜索 </a-button>
|
||||
</div>
|
||||
<div id="panel" style="display: none"></div>
|
||||
<!--查询列表,高德地图api绑定id-->
|
||||
<div class="list" id="list"> </div>
|
||||
<div style="height: 62vh" id="container"></div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import positionIcon from '/@/assets/images/position.png';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { Position } from '/@/views/consult/resource/components/Map';
|
||||
import mapKey from '/@/utils/mapKey';
|
||||
import { message } from 'ant-design-vue';
|
||||
let geocoder = ref();
|
||||
const emit = defineEmits(['getPosition']);
|
||||
let BasicMap = null;
|
||||
let SelfMap = null;
|
||||
const isCLickMap = ref(false);
|
||||
let positionRef = ref({
|
||||
lng: '',
|
||||
lat: '',
|
||||
handleItem: {
|
||||
pname: '',
|
||||
},
|
||||
});
|
||||
let mapState = reactive({
|
||||
marker: null,
|
||||
});
|
||||
let adr = ref('');
|
||||
let position: Position = positionRef.value;
|
||||
const title = '地图选点';
|
||||
const intValue = ref('');
|
||||
let placeSearch = ref();
|
||||
let panelList = ref([]);
|
||||
//表单赋值
|
||||
const [registerModal, { closeModal }] = useModalInner(async (data) => {
|
||||
let { longitude: lng, latitude: lat, address } = data?.record || {};
|
||||
position.lng = lng;
|
||||
position.lat = lat;
|
||||
intValue.value = address || '';
|
||||
adr.value = address || '';
|
||||
isCLickMap.value = false;
|
||||
initMap();
|
||||
});
|
||||
|
||||
function initMap() {
|
||||
AMapLoader.load({
|
||||
key: mapKey, // 申请好的Web端开发者Key,首次调用 load 时必填
|
||||
// version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
||||
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
||||
plugins: ['AMap.Geocoder'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
||||
})
|
||||
.then((AMap) => {
|
||||
SelfMap = AMap;
|
||||
//设置地图容器id
|
||||
BasicMap = new AMap.Map('container', {
|
||||
viewMode: '3D', //是否为3D地图模式
|
||||
zoom: 12, //初始化地图级别
|
||||
center: [108.95, 34.33], //初始化地图中心点位置
|
||||
resizeEnable: true,
|
||||
});
|
||||
// 注册搜索插件
|
||||
bindSearch(AMap);
|
||||
bindEvent();
|
||||
// 注册坐标转地址
|
||||
geocoder.value = new AMap.Geocoder({
|
||||
city: '', //城市设为北京,默认:“全国”
|
||||
radius: 1000, //范围,默认:500
|
||||
});
|
||||
if (position.lng) {
|
||||
panTo(position);
|
||||
addMarker(position);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @Description:输入框查询位置
|
||||
* @date 2023/7/8
|
||||
*/
|
||||
function onSearch(value: string) {
|
||||
//关键字查询
|
||||
if (value) {
|
||||
intValue.value = value;
|
||||
searchRes(value);
|
||||
}
|
||||
}
|
||||
const searchRes = debounce((value) => {
|
||||
placeSearch.value.search(value, (status: string, result: any) => {
|
||||
console.log(result);
|
||||
if (status === 'complete') {
|
||||
panelList.value = result.poiList.pois.map((item) => ({ label: item.name, value: item.name, ...item }));
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
function onButtonSearch() {
|
||||
onSearch(intValue.value);
|
||||
}
|
||||
/**
|
||||
* @Description下拉框选择事件
|
||||
* @date 2023/8/30
|
||||
*/
|
||||
function handleChange(value: any, option: any) {
|
||||
panTo(option.location);
|
||||
setMapZoom(15);
|
||||
let { lng, lat } = option.location;
|
||||
let handleItem = panelList.value?.find((item) => item['id'] === intValue.value) ?? { pname: '' };
|
||||
// adr.value = value;
|
||||
positionRef.value = { lng, lat, handleItem };
|
||||
addMarker(option.location);
|
||||
}
|
||||
function addMarker(position: Position) {
|
||||
if (!position.lng) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
removeMarker();
|
||||
mapState.marker = new SelfMap.Marker({
|
||||
icon: positionIcon,
|
||||
position: [position.lng, position.lat],
|
||||
offset: [-18, -32],
|
||||
maxZoom: 14,
|
||||
});
|
||||
mapState && (mapState.marker as any).setMap(BasicMap);
|
||||
} catch {}
|
||||
}
|
||||
function panTo(position: Position) {
|
||||
if (!position.lng) {
|
||||
return;
|
||||
}
|
||||
BasicMap && (BasicMap as any).panTo([position.lng, position.lat]);
|
||||
}
|
||||
function setMapZoom(zoom: number) {
|
||||
if (zoom) BasicMap && (BasicMap as any).setZoom(zoom);
|
||||
}
|
||||
function removeMarker() {
|
||||
if (mapState.marker) {
|
||||
(mapState.marker as any).setMap(null);
|
||||
mapState.marker = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Description:经纬度转地址文本信息
|
||||
* @date 2023/8/30
|
||||
*/
|
||||
function lngLatToAddress({ lng, lat }) {
|
||||
if (!lng) return '';
|
||||
return new Promise((resolve, reject) => {
|
||||
let str = [lng, lat];
|
||||
geocoder.value?.getAddress(str, function (status, result) {
|
||||
if (status === 'complete' && result?.regeocode) {
|
||||
let address = result?.regeocode?.formattedAddress;
|
||||
return resolve(address);
|
||||
} else {
|
||||
return reject(new Error('Address not found'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// 地图点击事件添加marker 更新地址
|
||||
async function mapClick(e: any) {
|
||||
let { lng, lat } = e['lnglat'];
|
||||
position.lng = lng;
|
||||
position.lat = lat;
|
||||
try {
|
||||
addMarker(e['lnglat']);
|
||||
let res = await lngLatToAddress(e['lnglat']);
|
||||
await nextTick(() => {
|
||||
intValue.value = res as string;
|
||||
adr.value = res as string;
|
||||
positionRef.value = {
|
||||
lng,
|
||||
lat,
|
||||
handleItem: {
|
||||
pname: res as string,
|
||||
},
|
||||
};
|
||||
isCLickMap.value = true;
|
||||
});
|
||||
} catch {}
|
||||
}
|
||||
function bindEvent() {
|
||||
BasicMap && (BasicMap as any).on('click', mapClick);
|
||||
}
|
||||
// 搜索插件
|
||||
function bindSearch(AMap) {
|
||||
AMap.plugin(['AMap.PlaceSearch'], function () {
|
||||
//构造地点查询类
|
||||
placeSearch.value = new AMap.PlaceSearch({
|
||||
pageSize: 20, // 单页显示结果条数
|
||||
pageIndex: 1, // 页码
|
||||
map: BasicMap, // 展现结果的地图实例
|
||||
// citylimit: false, //是否强制限制在设置的城市内搜索
|
||||
panel: 'panel', // 结果列表将在此容器中进行展示。
|
||||
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
|
||||
});
|
||||
// 为marker注册点击事件
|
||||
placeSearch.value.on('markerClick', function (e: any) {
|
||||
mapClick(e.event);
|
||||
});
|
||||
});
|
||||
}
|
||||
async function handleSubmit() {
|
||||
console.log(getPosition());
|
||||
const { lat, lng } = getPosition();
|
||||
if (!lat && !lng) return message.warning('尚未选点');
|
||||
if (!isCLickMap.value && !lat && !lng) return message.warning('尚未选点');
|
||||
emit('getPosition', getPosition());
|
||||
clearData();
|
||||
closeModal();
|
||||
}
|
||||
function clearData() {
|
||||
intValue.value = '';
|
||||
}
|
||||
function getPosition() {
|
||||
return {
|
||||
...positionRef.value,
|
||||
handleItem: {
|
||||
pname: adr.value,
|
||||
},
|
||||
};
|
||||
}
|
||||
defineExpose({
|
||||
getPosition,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.amap-icon) {
|
||||
img {
|
||||
width: 34px !important;
|
||||
height: 34px !important;
|
||||
}
|
||||
}
|
||||
.map-search-box {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
z-index: 10;
|
||||
box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.panel-list {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
max-height: 90%;
|
||||
overflow-y: auto;
|
||||
top: 70px;
|
||||
left: 13px;
|
||||
width: 280px;
|
||||
z-index: 9;
|
||||
.panel-item {
|
||||
padding: 10px 5px;
|
||||
color: #999;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<BasicDrawer
|
||||
:showFooter="showFooter"
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
:width="800"
|
||||
@ok="handleSubmit"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div style="height: 65vh">
|
||||
<BasicForm @register="registerForm">
|
||||
<template #address="{ model }">
|
||||
<a-input style="width: 82%" v-model:value="model['address']" :disabled="true" />
|
||||
<a-button style="margin-left: 10px" @click="viewMap" :disabled="!showFooter">查看地图</a-button>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</div>
|
||||
<Map @register="registerMap" :state="state" ref="map" @get-position="getPosition" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema } from '../conResource.data';
|
||||
import { saveOrUpdate } from '../conResource.api';
|
||||
import Map from '/@/views/consult/resource/components/Map.vue';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
const state = ref();
|
||||
const showFooter = ref(false);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//设置标题
|
||||
const title = ref<string>('');
|
||||
//表单赋值
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
showFooter.value = data.showFooter;
|
||||
title.value = data.title;
|
||||
//重置表单
|
||||
await resetFields();
|
||||
setDrawerProps({
|
||||
confirmLoading: false,
|
||||
showCancelBtn: !!data?.showFooter,
|
||||
showOkBtn: !!data?.showFooter,
|
||||
});
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
if (unref(isUpdate)) {
|
||||
let customAddress = `${data.record?.longitude},${data.record?.latitude}`;
|
||||
//表单赋值
|
||||
let { conDepartmentList, conDoctorList, conSicksList } = data.record;
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
customAddress,
|
||||
conDepartmentList: conDepartmentList && conDepartmentList.split(','),
|
||||
conDoctorList: conDoctorList && conDoctorList.split(','),
|
||||
conSicksList: conSicksList && conSicksList.split(','),
|
||||
});
|
||||
state.value = data.record;
|
||||
} else {
|
||||
state.value = {};
|
||||
}
|
||||
await clearValidate();
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
const [registerMap, { openModal }] = useModal();
|
||||
function viewMap() {
|
||||
openModal(true, {
|
||||
record: state.value,
|
||||
});
|
||||
}
|
||||
async function getPosition(val) {
|
||||
let { pname, cityname, adname, address, name } = val.handleItem || '';
|
||||
let nameList = [pname, cityname, adname, address, name];
|
||||
let str = '';
|
||||
nameList.map((item) => {
|
||||
if (item !== undefined) {
|
||||
str += item;
|
||||
}
|
||||
});
|
||||
await setFieldsValue({
|
||||
latitude: val.lat,
|
||||
longitude: val.lng,
|
||||
customAddress: `${val.lng},${val.lat}`,
|
||||
address: str,
|
||||
});
|
||||
state.value = {
|
||||
...state.value,
|
||||
latitude: val.lat,
|
||||
longitude: val.lng,
|
||||
};
|
||||
}
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
const params = {
|
||||
...state.value,
|
||||
...values,
|
||||
// type: values.type,
|
||||
level: values.level,
|
||||
conDepartmentList: values.conDepartmentList,
|
||||
conSicksList: values.conSicksList,
|
||||
conDoctorList: values.conDoctorList,
|
||||
};
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(params, 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,117 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/conResource/list',
|
||||
save = '/health-consultation/conResource/add',
|
||||
edit = '/health-consultation/conResource/edit',
|
||||
deleteOne = '/health-consultation/conResource/delete',
|
||||
deleteBatch = '/health-consultation/conResource/deleteBatch',
|
||||
importExcel = '/health-consultation/conResource/importExcel',
|
||||
exportXls = '/health-consultation/conResource/exportXls',
|
||||
departmentList = '/health-consultation/conSicks/listByDept',
|
||||
doctor = '/health-consultation/conDoctor/getFreeDoctorByDept',
|
||||
detail = '/health-consultation/conResource/queryById',
|
||||
selectDepartmentList = '/health-consultation/conResource/selectDepartmentList',
|
||||
topping = '/health-consultation/conResource/updateTop',
|
||||
selectSickListByDepartmentId = '/health-consultation/conSicks/selectSickListByDepartmentId',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
const url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
//根据科室获取所有闲置专家
|
||||
export const getDoctor = (params) => defHttp.post({ url: Api.doctor, params });
|
||||
// 根据科室list查询疾病
|
||||
export const getDepartmentList = (params) => defHttp.post({ url: Api.departmentList, params });
|
||||
//获取详情数据
|
||||
export const getDetail = (params) => defHttp.get({ url: Api.detail, params });
|
||||
/**
|
||||
* @Description:
|
||||
* @date 2023/6/19
|
||||
* @param:
|
||||
*/
|
||||
export const selectDepartmentList = (params) => defHttp.post({ url: Api.selectDepartmentList, params });
|
||||
|
||||
export const selectSickListByDepartmentId = (params) => defHttp.get({ url: Api.selectSickListByDepartmentId, params });
|
||||
|
||||
// 是否置顶
|
||||
export const getTopping = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `是否将该条数据${params.type === '0' ? '取消置顶' : '置顶'}?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.get({ url: Api.topping, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,363 @@
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { getDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { h } from 'vue';
|
||||
import { EyeOutlined } from '@ant-design/icons-vue';
|
||||
import { Image } from 'ant-design-vue';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { getDoctor } from '/@/views/consult/resource/conResource.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
customRender: ({ index }) => {
|
||||
return index + 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '医院名称',
|
||||
align: 'center',
|
||||
dataIndex: 'resourceName',
|
||||
},
|
||||
{
|
||||
title: '主图',
|
||||
align: 'center',
|
||||
dataIndex: 'img',
|
||||
width: 100,
|
||||
customRender: ({ text }) => {
|
||||
return h(Image, {
|
||||
placeholder: true,
|
||||
src: getFileAccessHttpUrl(text),
|
||||
height: 50,
|
||||
width: 50,
|
||||
fallback: getDefaultImage(),
|
||||
previewMask: () => {
|
||||
return h(EyeOutlined, {
|
||||
style: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '详细地址',
|
||||
align: 'center',
|
||||
dataIndex: 'address',
|
||||
},
|
||||
// {
|
||||
// title: '医院类型',
|
||||
// align: 'center',
|
||||
// dataIndex: 'type',
|
||||
// customRender: ({ text }) => {
|
||||
// return render.renderDict(text, 'h_type');
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '医院级别',
|
||||
align: 'center',
|
||||
dataIndex: 'level',
|
||||
customRender: ({ text }) => {
|
||||
return render.renderDict(text, 'hospital_level');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '是否置顶',
|
||||
align: 'center',
|
||||
dataIndex: 'tfTop',
|
||||
customRender: ({ text }) => (text === 1 ? '是' : '否'),
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
align: 'center',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: 'center',
|
||||
dataIndex: 'status',
|
||||
customRender: ({ text }) => {
|
||||
if (text == '1') {
|
||||
return '正常';
|
||||
} else {
|
||||
return '冻结';
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '医院名称',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '地址',
|
||||
field: 'province',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '医院级别',
|
||||
field: 'level',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'hospital_level',
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: '医院类型',
|
||||
// field: 'type',
|
||||
// component: 'JDictSelectTag',
|
||||
// componentProps: {
|
||||
// dictCode: 'h_type',
|
||||
// },
|
||||
// },
|
||||
];
|
||||
const validate = async (_rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.reject('请选择状态');
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
const departmentValidator = async (_rule, value) => {
|
||||
if (!value || !value.length) {
|
||||
return Promise.reject('请选择院内科室');
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '医院名称',
|
||||
field: 'resourceName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
rules: [{ required: true, message: '请输入医院名称!' }],
|
||||
},
|
||||
// {
|
||||
// label: '医院类型',
|
||||
// field: 'type',
|
||||
// component: 'JDictSelectTag',
|
||||
// componentProps: {
|
||||
// dictCode: 'h_type',
|
||||
// },
|
||||
// rules: [{ required: true }],
|
||||
// },
|
||||
{
|
||||
label: '医院级别',
|
||||
field: 'level',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
dictCode: 'hospital_level',
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '医院主图',
|
||||
field: 'img',
|
||||
component: 'JImageUpload',
|
||||
componentProps: {
|
||||
fileMax: 1,
|
||||
},
|
||||
rules: [{ required: false }],
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
field: 'status',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
value: 1,
|
||||
label: '正常',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '冻结',
|
||||
},
|
||||
],
|
||||
type: 'radio',
|
||||
},
|
||||
rules: [{ required: true, validator: validate, trigger: 'blur' }],
|
||||
},
|
||||
{
|
||||
label: '医院简介',
|
||||
field: 'synopsis',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
showCount: true,
|
||||
rows: 4,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '医院介绍',
|
||||
field: 'resourceDetail',
|
||||
component: 'JEditor',
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '地址',
|
||||
field: 'customAddress',
|
||||
component: 'Input',
|
||||
slot: 'customAddress',
|
||||
rules: [{ required: true }],
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
label: '详细地址',
|
||||
field: 'address',
|
||||
component: 'Input',
|
||||
slot: 'address',
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'longitude',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'latitude',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '院内科室',
|
||||
field: 'conDepartmentList',
|
||||
component: 'JTreeDepartment',
|
||||
componentProps: ({ formModel }) => {
|
||||
return {
|
||||
valueField: 'departmentId',
|
||||
field: 'departmentId',
|
||||
allDep: true,
|
||||
multiple: true,
|
||||
immediate: true,
|
||||
treeCheckable: true,
|
||||
treeCheckStrictly: true,
|
||||
showCheckedStrategy: 'SHOW_ALL',
|
||||
checkFather: true,
|
||||
onChange: (val) => {
|
||||
if (!val) {
|
||||
formModel.conSicksList = [];
|
||||
formModel.conDoctorList = [];
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
rules: [{ required: true, trigger: 'blur', validator: departmentValidator }],
|
||||
},
|
||||
{
|
||||
label: '主治疾病',
|
||||
field: 'conSicksList',
|
||||
component: 'ApiSelect',
|
||||
show: false,
|
||||
// componentProps: ({ formModel }) => {
|
||||
// let departmentId = '1321354';
|
||||
// if (formModel?.conDepartmentList) {
|
||||
// if (Array.isArray(formModel?.conDepartmentList)) {
|
||||
// departmentId = formModel?.conDepartmentList?.join(',');
|
||||
// } else {
|
||||
// departmentId = formModel?.conDepartmentList;
|
||||
// }
|
||||
// }
|
||||
// return {
|
||||
// api: getDepartmentList,
|
||||
// params: {
|
||||
// departmentId: departmentId,
|
||||
// isDoctor: false, //通用接口标识 是否是医生的情况下查询疾病
|
||||
// },
|
||||
// labelField: 'sicksName',
|
||||
// valueField: 'id',
|
||||
// mode: 'multiple',
|
||||
// immediate: true,
|
||||
// onFocus: () => {
|
||||
// if (!formModel?.conDepartmentList || formModel?.conDepartmentList.length < 1) {
|
||||
// return message.warn('请先选择院内科室');
|
||||
// }
|
||||
// },
|
||||
// disabledInitValue: true,
|
||||
// getPopupContainer: () => document.body,
|
||||
// };
|
||||
// },
|
||||
},
|
||||
{
|
||||
label: '院内专家',
|
||||
field: 'conDoctorList',
|
||||
component: 'ApiSelect',
|
||||
componentProps: ({ formModel }) => {
|
||||
let departmentId = '1321354';
|
||||
if (formModel?.conDepartmentList) {
|
||||
if (Array.isArray(formModel?.conDepartmentList)) {
|
||||
departmentId = formModel?.conDepartmentList?.join(',');
|
||||
} else {
|
||||
departmentId = formModel?.conDepartmentList;
|
||||
}
|
||||
}
|
||||
return {
|
||||
api: getDoctor,
|
||||
params: {
|
||||
departmentId: departmentId,
|
||||
isAdd: !formModel.id,
|
||||
},
|
||||
labelField: 'doctorName',
|
||||
valueField: 'id',
|
||||
mode: 'multiple',
|
||||
immediate: true,
|
||||
onFocus: () => {
|
||||
if (!formModel?.conDepartmentList || formModel?.conDepartmentList.length < 1) {
|
||||
return message.warn('请先选择院内科室');
|
||||
}
|
||||
},
|
||||
// disabledInitValue: true,
|
||||
getPopupContainer: () => document.body,
|
||||
disabled: true,
|
||||
};
|
||||
},
|
||||
ifShow: ({ values }) => values?.id,
|
||||
},
|
||||
{
|
||||
label: '是否置顶',
|
||||
field: 'tfTop',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '是',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '否',
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param _formData
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="auth.add" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
|
||||
<a-button v-auth="auth.deleteBatch" type="primary" preIcon="ant-design:delete-outlined" @click="batchHandleDelete">
|
||||
批量删除</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-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="1" @click="batchHandleDelete">
|
||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
||||
删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
<a-button>批量操作
|
||||
<Icon icon="mdi:chevron-down"></Icon>
|
||||
</a-button>
|
||||
</a-dropdown> -->
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(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>
|
||||
<!-- 表单区域 -->
|
||||
<ConResourceModal @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conResource" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConResourceModal from './components/conResourceModal.vue';
|
||||
import { columns, searchFormSchema } from './conResource.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, getDetail, getTopping } from './conResource.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
import { message } from 'ant-design-vue';
|
||||
//注册model
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const auth = {
|
||||
deleteBatch: 'consultation:con_resource:deleteBatch',
|
||||
add: 'consultation:con_resource:add',
|
||||
};
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'con_resource',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: false,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: 'con_resource',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
title: '新增',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
async function handleEdit(record: Recordable) {
|
||||
let data = await getDetail({ id: record.id });
|
||||
openDrawer(true, {
|
||||
record: { ...data, ...record },
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
title: '编辑',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
async function handleDetail(record: Recordable) {
|
||||
let data = await getDetail({ id: record.id });
|
||||
|
||||
openDrawer(true, {
|
||||
record: { ...data, ...record },
|
||||
isUpdate: true,
|
||||
showFooter: false,
|
||||
title: '详情',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
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);
|
||||
}
|
||||
/*
|
||||
* 置顶 1置顶 0 取消置顶
|
||||
* */
|
||||
async function handleTopping(record) {
|
||||
await getTopping({ type: record.tfTop === 0 ? '1' : '0', id: record.id }, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
{
|
||||
label: `${record.tfTop === 0 ? '置顶' : '取消置顶'}`,
|
||||
onClick: handleTopping.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '详情',
|
||||
onClick: handleDetail.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'consultation:con_resource:edit',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'consultation:con_resource:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
/**
|
||||
* 下拉操作栏
|
||||
*/
|
||||
// function getDropDownAction(record){
|
||||
// return [
|
||||
// {
|
||||
// label: '详情',
|
||||
// onClick: handleDetail.bind(null, record),
|
||||
// }, {
|
||||
// label: '删除',
|
||||
// popConfirm: {
|
||||
// title: '是否确认删除',
|
||||
// confirm: handleDelete.bind(null, record),
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-popover-buttons) {
|
||||
display: flex !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<BasicModal @register="registerModal" :title="isUpdate ? '修改休息时间' : '新增休息时间'" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicModal from '/@/components/Modal/src/BasicModal.vue';
|
||||
import BasicForm from '/@/components/Form/src/BasicForm.vue';
|
||||
import { useModalInner } from '/@/components/Modal';
|
||||
import { ref } from 'vue';
|
||||
import { useForm } from '/@/components/Form';
|
||||
import { schema } from '/@/views/consult/restTime/restTime.data';
|
||||
import { addApi, editApi } from '/@/views/consult/restTime/restTime.api';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const isUpdate = ref(false);
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
isUpdate.value = data?.isUpdate;
|
||||
await resetFields();
|
||||
if (data?.isUpdate) {
|
||||
await setFieldsValue({ ...data?.record });
|
||||
}
|
||||
await clearValidate();
|
||||
});
|
||||
const [registerForm, { setFieldsValue, clearValidate, resetFields, validate }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: schema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const value = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
if (isUpdate.value) {
|
||||
await editApi(value);
|
||||
} else {
|
||||
await addApi(value);
|
||||
}
|
||||
closeModal();
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,45 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conHelperRest/list',
|
||||
add = '/health-consultation/consultation/conHelperRest/add',
|
||||
edit = '/health-consultation/consultation/conHelperRest/edit',
|
||||
delete = '/health-consultation/consultation/conHelperRest/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conHelperRest/deleteBatch',
|
||||
}
|
||||
|
||||
export const listApi = (params = {}) => defHttp.get({ url: Api.list, params });
|
||||
export const addApi = (params = {}) => defHttp.post({ url: Api.add, params });
|
||||
export const editApi = (params = {}) => defHttp.put({ url: Api.edit, params });
|
||||
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
await defHttp.delete({ url: Api.delete, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
export const deleteB = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
await defHttp.delete({ url: Api.deleteBatch, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
import { FormSchema } from '/@/components/Form';
|
||||
import { BasicColumn } from '/@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '开始时间',
|
||||
dataIndex: 'startTime',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '结束时间',
|
||||
dataIndex: 'endTime',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '自动回复内容',
|
||||
dataIndex: 'replyContent',
|
||||
},
|
||||
];
|
||||
export const schema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '休息开始时间',
|
||||
field: 'startTime',
|
||||
component: 'TimePicker',
|
||||
componentProps: () => {
|
||||
return {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
format: 'HH:mm',
|
||||
valueFormat: 'HH:mm',
|
||||
getPopupContainer: () => document.body,
|
||||
};
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '休息结束时间',
|
||||
field: 'endTime',
|
||||
component: 'TimePicker',
|
||||
componentProps: () => {
|
||||
return {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
format: 'HH:mm',
|
||||
valueFormat: 'HH:mm',
|
||||
getPopupContainer: () => document.body,
|
||||
};
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '自动回复内容',
|
||||
field: 'replyContent',
|
||||
component: 'InputTextArea',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div class="outer-d">
|
||||
<BasicTable @register="registerTable" :row-selection="rowSelection">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="'consultation:con_helper_rest:add'" @click="handleAdd" preIcon="ant-design:plus-outlined">
|
||||
新增
|
||||
</a-button>
|
||||
<a-button type="primary" v-auth="" @click="deleteBatch" preIcon="ant-design:delete-outlined"> 批量删除 </a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(record)" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<rest-time-modal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicTable from '/@/components/Table/src/BasicTable.vue';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { deleteB, deleteOne, listApi } from '/@/views/consult/restTime/restTime.api';
|
||||
import { columns } from '/@/views/consult/restTime/restTime.data';
|
||||
import RestTimeModal from '/@/views/consult/restTime/component/restTimeModal.vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { TableAction } from '/@/components/Table';
|
||||
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: '小助手休息时间',
|
||||
api: listApi,
|
||||
columns,
|
||||
tableSetting: {
|
||||
redo: true,
|
||||
},
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { selectedRowKeys, rowSelection }] = tableContext;
|
||||
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
|
||||
function deleteBatch() {
|
||||
deleteB({ ids: selectedRowKeys.value }, handleSuccess);
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: 'consultation:con_helper_rest:edit',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: 'consultation:con_helper_rest:delete',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
isUpdate: true,
|
||||
record,
|
||||
});
|
||||
}
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.outer-d {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<BasicDrawer @register="registerDrawer" width="60%" @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm" />
|
||||
<div class="line-d">
|
||||
<div style="font-size: 16px; font-weight: bold">结算费用设置</div>
|
||||
<a-button type="primary" @click="addCostList">添加</a-button>
|
||||
</div>
|
||||
|
||||
<div class="list-d">
|
||||
<div class="list-line-d" style="border: none; font-weight: bold; margin: 0">
|
||||
<div class="item-d">费用类型</div>
|
||||
<div class="item-d">结算对象</div>
|
||||
<div class="item-d">图文咨询费用</div>
|
||||
<div class="item-d">音视频咨询费用</div>
|
||||
<div class="item-d-s"></div>
|
||||
</div>
|
||||
<template v-for="(item, index) in costList">
|
||||
<div class="list-line-d" :style="{ marginTop: index === 0 ? 0 : '10px' }">
|
||||
<div class="item-d">
|
||||
<a-select
|
||||
:disabled="index < 2"
|
||||
v-model:value="item['costType']"
|
||||
:options="[
|
||||
{
|
||||
label: '职称',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '单独设置',
|
||||
value: 2,
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="item-d">
|
||||
<JDictSelectTag
|
||||
placeholder="请选择结算对象"
|
||||
:disabled="index < 2"
|
||||
:show-choose-option="false"
|
||||
dict-code="z_doct_lev"
|
||||
v-model:value="item['titleId']"
|
||||
/>
|
||||
</div>
|
||||
<div class="item-d"> <a-input placeholder="请输入" v-model:value="item['textFee']" /> 元 </div>
|
||||
<div class="item-d"> <a-input placeholder="请输入" v-model:value="item['videoFee']" /> 元 </div>
|
||||
<div class="item-d-s">
|
||||
<delete-outlined v-if="index > 1" style="cursor: pointer" @click="() => costList.splice(index, 1)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="line-d">
|
||||
<div style="font-size: 16px; font-weight: bold">结算周期设置</div>
|
||||
</div>
|
||||
|
||||
<div class="range-date-d">
|
||||
<a-range-picker
|
||||
v-model:value="settingDate"
|
||||
picker="month"
|
||||
fotmat="YYYY-MM"
|
||||
valueFormat="YYYY-MM"
|
||||
style="width: 50%"
|
||||
@change="changeRangeDate"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="list-d">
|
||||
<div class="list-line-d-b" style="border: none; font-weight: bold; margin: 0">
|
||||
<div class="item-d">月份</div>
|
||||
<div class="item-d">范围类型</div>
|
||||
<div class="item-d">自定义范围</div>
|
||||
</div>
|
||||
<template v-for="(item, index) in settingList">
|
||||
<div class="list-line-d-b" :style="{ marginTop: index === 0 ? 0 : '10px' }">
|
||||
<div class="item-d"> {{ item?.yearValue }}-{{ item?.monthValue }} </div>
|
||||
<div class="item-d">
|
||||
<JDictSelectTag
|
||||
placeholder="请选择结范围"
|
||||
:show-choose-option="false"
|
||||
:string-to-number="true"
|
||||
:options="[
|
||||
{
|
||||
label: '自然月',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '自定义起止时间',
|
||||
value: 2,
|
||||
},
|
||||
]"
|
||||
v-model:value="item['periodType']"
|
||||
/>
|
||||
</div>
|
||||
<div class="item-d">
|
||||
<a-range-picker
|
||||
v-if="item['periodType'] !== 1"
|
||||
v-model:value="item['settingDate']"
|
||||
fotmat="YYYY-MM-DD"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
style="width: 70%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { useDrawerInner } from '/@/components/Drawer';
|
||||
import { schemas } from '/@/views/consult/settlement/settlement.data';
|
||||
import { DeleteOutlined } from '@ant-design/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { addApi, editApi } from '/@/views/consult/settlement/settlement.api';
|
||||
|
||||
const isUpdate = ref(false);
|
||||
|
||||
const costList = ref<any[]>([]);
|
||||
|
||||
const settingDate = ref(null);
|
||||
const settingList = ref<any[]>([]);
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
settingDate.value = null;
|
||||
await resetFields();
|
||||
setDrawerProps({
|
||||
title: data.isUpdate ? '编辑结算配置' : '新增结算配置',
|
||||
showFooter: true,
|
||||
});
|
||||
costList.value = [
|
||||
{
|
||||
costType: 1,
|
||||
titleId: '2',
|
||||
textFee: '',
|
||||
videoFee: '',
|
||||
},
|
||||
{
|
||||
costType: 1,
|
||||
titleId: '4',
|
||||
textFee: '',
|
||||
videoFee: '',
|
||||
},
|
||||
];
|
||||
|
||||
settingList.value = [];
|
||||
|
||||
isUpdate.value = data.isUpdate;
|
||||
|
||||
console.log(data.record);
|
||||
|
||||
if (data.isUpdate) {
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
|
||||
costList.value = JSON.parse(JSON.stringify(data?.record?.configCosts)) || [];
|
||||
settingList.value = data?.record?.configPeriods
|
||||
? data?.record?.configPeriods.map((item) => {
|
||||
item['settingDate'] = [item.startDate, item.endDate];
|
||||
return item;
|
||||
})
|
||||
: [];
|
||||
if (settingList.value.length > 0) {
|
||||
console.log(settingList.value);
|
||||
settingDate.value = [
|
||||
dayjs(settingList.value[0].startDate).format('YYYY-MM'),
|
||||
dayjs(settingList.value[settingList.value.length - 1].startDate).format('YYYY-MM'),
|
||||
];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function addCostList() {
|
||||
costList.value.push({
|
||||
costType: 1,
|
||||
titleId: undefined,
|
||||
textFee: '',
|
||||
videoFee: '',
|
||||
});
|
||||
}
|
||||
|
||||
function changeRangeDate(v) {
|
||||
settingList.value = [];
|
||||
let c = dayjs(v[1]).diff(dayjs(v[0]), 'month');
|
||||
let d = null;
|
||||
for (let i = 0; i <= c; i++) {
|
||||
d = dayjs(v[0]).add(i, 'month');
|
||||
settingList.value.push({
|
||||
periodType: 1,
|
||||
settleId: '',
|
||||
yearValue: d.format('YYYY') * 1,
|
||||
monthValue: d.format('MM') * 1,
|
||||
settingDate: [d.startOf('month'), d.endOf('month')],
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
});
|
||||
}
|
||||
|
||||
console.log(settingList.value);
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await setDrawerProps({
|
||||
confirmLoading: true,
|
||||
});
|
||||
|
||||
let values = await validate();
|
||||
|
||||
let params = {
|
||||
...values,
|
||||
configCosts: costList.value,
|
||||
configPeriods: settingList.value.map((item) => {
|
||||
item.startDate = dayjs(item.settingDate[0]).format('YYYY-MM-DD');
|
||||
item.endDate = dayjs(item.settingDate[1]).format('YYYY-MM-DD');
|
||||
return item;
|
||||
}),
|
||||
};
|
||||
|
||||
if (isUpdate.value) {
|
||||
await editApi(params);
|
||||
} else {
|
||||
await addApi(params);
|
||||
}
|
||||
closeDrawer();
|
||||
emit('success');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await setDrawerProps({
|
||||
confirmLoading: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const [registerForm, { setFieldsValue, validate, resetFields }] = useForm({
|
||||
schemas,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.line-d {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.list-line-d,
|
||||
.list-line-d-b {
|
||||
display: flex;
|
||||
border: 1px solid #eaeaea;
|
||||
padding: 5px;
|
||||
margin-top: 10px;
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px 0;
|
||||
}
|
||||
.item-d {
|
||||
width: calc((100% - 50px) / 4);
|
||||
}
|
||||
.item-d-s {
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-line-d-b {
|
||||
> :nth-child(1) {
|
||||
width: 100px;
|
||||
}
|
||||
> :nth-child(2) {
|
||||
width: 180px;
|
||||
}
|
||||
> :nth-child(3) {
|
||||
width: calc(100% - 280px);
|
||||
}
|
||||
}
|
||||
|
||||
.list-d {
|
||||
:deep(.ant-select) {
|
||||
width: 90%;
|
||||
}
|
||||
:deep(.ant-input) {
|
||||
width: 80%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
.range-date-d {
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-button
|
||||
style="margin-bottom: 10px"
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
emit('toOtherPages', props.commeStatus);
|
||||
console.log(props.commeStatus);
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #icon><left-outlined /></template>
|
||||
返回
|
||||
</a-button>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary">下载</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicTable from '/@/components/Table/src/BasicTable.vue';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { consultColumn } from '/@/views/consult/settlement/settlement.data';
|
||||
import { watch } from 'vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { itemApi } from '/@/views/consult/settlement/settlement.api';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
detailId: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
monthId: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
commeStatus: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
(v) => {
|
||||
reload({ page: 1 });
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => props.monthId,
|
||||
(v) => {
|
||||
if (v) {
|
||||
reload({ page: 1 });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits(['toOtherPages']);
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
api: itemApi,
|
||||
columns: consultColumn,
|
||||
tableSetting: {
|
||||
redo: true,
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
params['settleId'] = props.detailId;
|
||||
params['resultId'] = props.monthId;
|
||||
if (props.id) params['periodId'] = props.id;
|
||||
return params;
|
||||
},
|
||||
showActionColumn: false,
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
immediate: false,
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function toConsult() {
|
||||
emit('toOtherPages', 'consult');
|
||||
}
|
||||
|
||||
const [registerTable, { reload }, {}] = tableContext;
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-button style="margin-bottom: 10px" type="primary" @click="() => emit('toOtherPages', 'settlement')">
|
||||
<template #icon><left-outlined /></template>
|
||||
返回
|
||||
</a-button>
|
||||
<BasicTable @register="registerTable">
|
||||
<!-- <template #tableTitle>-->
|
||||
<!-- <a-button type="primary">下载</a-button>-->
|
||||
<!-- </template>-->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'a'">
|
||||
<a-button class="list-button" type="link" @click="toMonth(record)">月详情</a-button>
|
||||
<a-button class="list-button" type="link" @click="toConsult(record)">咨询详情</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicTable from '/@/components/Table/src/BasicTable.vue';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { detailColumn } from '/@/views/consult/settlement/settlement.data';
|
||||
import { watch } from 'vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { resultApi } from '/@/views/consult/settlement/settlement.api';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
(v) => {
|
||||
if (v) {
|
||||
reload({ page: 1 });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits(['toOtherPages', 'toConsult']);
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
api: resultApi,
|
||||
columns: detailColumn,
|
||||
beforeFetch: (params) => {
|
||||
params['settleId'] = props.id;
|
||||
return params;
|
||||
},
|
||||
tableSetting: {
|
||||
redo: true,
|
||||
},
|
||||
showActionColumn: false,
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
immediate: false,
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function toMonth(record: Recordable) {
|
||||
emit('toOtherPages', 'month', record?.id);
|
||||
}
|
||||
function toConsult(record: Recordable) {
|
||||
emit('toOtherPages', 'consult', record?.id);
|
||||
emit('toConsult', 'detail', record?.id);
|
||||
}
|
||||
|
||||
const [registerTable, { reload }, {}] = tableContext;
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.list-button {
|
||||
padding: 0 3px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-button style="margin-bottom: 10px" type="primary" @click="() => emit('toOtherPages', 'detail')">
|
||||
<template #icon><left-outlined /></template>
|
||||
返回
|
||||
</a-button>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary">下载</a-button>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'a'">
|
||||
<a-button class="list-button" type="link" @click="toConsult(record)">咨询详情</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicTable from '/@/components/Table/src/BasicTable.vue';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { monthColumn } from '/@/views/consult/settlement/settlement.data';
|
||||
import { watch } from 'vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { itemApi, periodApi } from '/@/views/consult/settlement/settlement.api';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
detailId: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
(v) => {
|
||||
if (v) {
|
||||
reload({ page: 1 });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits(['toOtherPages', 'toConsult']);
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
api: periodApi,
|
||||
columns: monthColumn,
|
||||
tableSetting: {
|
||||
redo: true,
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
params['settleId'] = props.detailId;
|
||||
params['resultId'] = props.id;
|
||||
return params;
|
||||
},
|
||||
showActionColumn: false,
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
immediate: false,
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function toConsult(record: Recordable) {
|
||||
emit('toConsult', 'month');
|
||||
emit('toOtherPages', 'consult', record?.id);
|
||||
}
|
||||
|
||||
const [registerTable, { reload }, {}] = tableContext;
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,21 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/settle/config/list',
|
||||
detail = '/health-consultation/settle/config',
|
||||
result = '/health-consultation/settle/result',
|
||||
item = '/health-consultation/settle/result/item',
|
||||
period = '/health-consultation/settle/result/period',
|
||||
generate = '/health-consultation/settle/generate/',
|
||||
add = '/health-consultation/settle/config/add',
|
||||
edit = '/health-consultation/settle/config/edit',
|
||||
}
|
||||
|
||||
export const listApi = (params = {}) => defHttp.get({ url: Api.list, params });
|
||||
export const resultApi = (params = {}) => defHttp.get({ url: Api.result, params });
|
||||
export const itemApi = (params = {}) => defHttp.get({ url: Api.item, params });
|
||||
export const periodApi = (params = {}) => defHttp.get({ url: Api.period, params });
|
||||
export const generateApi = (id) => defHttp.post({ url: Api.generate + id }, { isReturnNativeResponse: true });
|
||||
export const addApi = (params = {}) => defHttp.post({ url: Api.add, params });
|
||||
export const editApi = (params = {}) => defHttp.post({ url: Api.edit, params });
|
||||
export const detailApi = (params = {}) => defHttp.get({ url: Api.detail + `/${params.id}` });
|
||||
@@ -0,0 +1,267 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
import { getName } from '/@/views/interveneNew/compoents/utils';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const status = [
|
||||
{
|
||||
label: '待开始',
|
||||
value: '0',
|
||||
},
|
||||
{
|
||||
label: '结算中',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '已完成',
|
||||
value: '2',
|
||||
},
|
||||
{
|
||||
label: '结算异常',
|
||||
value: '3',
|
||||
},
|
||||
{
|
||||
label: '队列中',
|
||||
value: '5',
|
||||
},
|
||||
];
|
||||
|
||||
export const schemas: FormSchema[] = [
|
||||
{
|
||||
label: '结算名称',
|
||||
field: 'settleName',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '是否产生通讯费用',
|
||||
field: 'hasComFee',
|
||||
component: 'RadioGroup',
|
||||
defaultValue: true,
|
||||
componentProps: () => {
|
||||
return {
|
||||
options: [
|
||||
{
|
||||
label: '是',
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
label: '否',
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '通讯费',
|
||||
field: 'comFeePerMonth',
|
||||
component: 'Input',
|
||||
componentProps: () => {
|
||||
return {
|
||||
suffix: '元',
|
||||
};
|
||||
},
|
||||
ifShow: ({ values }) => values.hasComFee,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '结算名称',
|
||||
dataIndex: 'settleName',
|
||||
},
|
||||
{
|
||||
title: '结算起始月份',
|
||||
dataIndex: '2',
|
||||
customRender: ({ record }) => {
|
||||
return (
|
||||
record?.configPeriods &&
|
||||
record?.configPeriods.length > 0 &&
|
||||
record?.configPeriods[0]?.yearValue + '-' + record?.configPeriods[0]?.monthValue
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '结算结束月份',
|
||||
dataIndex: '3',
|
||||
customRender: ({ record }) => {
|
||||
return (
|
||||
record?.configPeriods &&
|
||||
record?.configPeriods.length > 0 &&
|
||||
record?.configPeriods[record?.configPeriods.length - 1]?.yearValue +
|
||||
'-' +
|
||||
record?.configPeriods[record?.configPeriods.length - 1]?.monthValue
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '结算状态',
|
||||
dataIndex: 'settleStatus',
|
||||
customRender: ({ text }) => {
|
||||
return getName(text, status);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '结算开始时间',
|
||||
dataIndex: 'lastGenerateTime',
|
||||
},
|
||||
{
|
||||
title: '结算完成时间',
|
||||
dataIndex: 'lastFinishedTime',
|
||||
},
|
||||
{
|
||||
title: '错误信息',
|
||||
dataIndex: 'errorMsg',
|
||||
defaultHidden: true,
|
||||
},
|
||||
{
|
||||
title: '结算操作',
|
||||
dataIndex: 'a',
|
||||
fixed: 'right',
|
||||
width: 220,
|
||||
},
|
||||
{
|
||||
title: '配置操作',
|
||||
dataIndex: 'b',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
|
||||
export const detailColumn: BasicColumn[] = [
|
||||
{
|
||||
title: '专家编号',
|
||||
dataIndex: 'doctorNo',
|
||||
},
|
||||
{
|
||||
title: '专家名称',
|
||||
dataIndex: 'doctorName',
|
||||
},
|
||||
{
|
||||
title: '专家职称',
|
||||
dataIndex: 'doctorTitle_dictText',
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
dataIndex: 'hospitalName',
|
||||
},
|
||||
{
|
||||
title: '单价(元)',
|
||||
dataIndex: 'doctorPrice',
|
||||
},
|
||||
{
|
||||
title: '回复次数',
|
||||
dataIndex: 'consultCount',
|
||||
},
|
||||
{
|
||||
title: '通讯费(元)',
|
||||
dataIndex: 'comFee',
|
||||
},
|
||||
{
|
||||
title: '咨询费(元)',
|
||||
dataIndex: 'consultFee',
|
||||
},
|
||||
{
|
||||
title: '结算费(元)',
|
||||
dataIndex: 'settleInvoice',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'a',
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
|
||||
export const monthColumn: BasicColumn[] = [
|
||||
...detailColumn.slice(0, 5),
|
||||
{
|
||||
title: '结算年份',
|
||||
dataIndex: 'yearValue',
|
||||
},
|
||||
{
|
||||
title: '结算月份',
|
||||
dataIndex: 'monthValue',
|
||||
},
|
||||
...detailColumn.slice(5),
|
||||
];
|
||||
|
||||
export const consultColumn: BasicColumn[] = [
|
||||
{
|
||||
title: '专家编号',
|
||||
dataIndex: 'doctorNo',
|
||||
},
|
||||
{
|
||||
title: '专家名称',
|
||||
dataIndex: 'doctorName',
|
||||
},
|
||||
{
|
||||
title: '专家职称',
|
||||
dataIndex: 'doctorTitle_dictText',
|
||||
},
|
||||
{
|
||||
title: '医院',
|
||||
dataIndex: 'hospitalName',
|
||||
},
|
||||
{
|
||||
title: '科室',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'secondDepartName',
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
dataIndex: 'userDepartName',
|
||||
},
|
||||
{
|
||||
title: '员工名称',
|
||||
dataIndex: 'userName',
|
||||
},
|
||||
{
|
||||
title: '身份证号',
|
||||
dataIndex: 'userIdCard',
|
||||
},
|
||||
{
|
||||
title: '生日',
|
||||
dataIndex: 'userBirthday',
|
||||
customRender: ({ text }) => {
|
||||
return text && dayjs(text).format('YYYY-MM-DD');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
dataIndex: 'userAge',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
dataIndex: 'userSex_dictText',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '用户咨询时间',
|
||||
dataIndex: 'userConsultTime',
|
||||
},
|
||||
{
|
||||
title: '专家首次回复时间',
|
||||
dataIndex: 'doctorFirstReplyTime',
|
||||
},
|
||||
{
|
||||
title: '订单状态',
|
||||
dataIndex: 'sessionStatus_dictText',
|
||||
},
|
||||
];
|
||||
|
||||
export const pageStatus = [{}];
|
||||
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div style="padding: 10px">
|
||||
<BasicTable v-show="pageStatus === 'settlement'" @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" @click="addD">新增</a-button>
|
||||
<a-button type="primary" @click="() => reload({ page: 1 })">刷新</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'a'">
|
||||
<a-button class="list-button" type="link" @click="generate(record)">生成结算</a-button>
|
||||
<a-button class="list-button" type="link" @click="toPage('detail', record)">查看报表</a-button>
|
||||
<a-button class="list-button" type="link" @click="downLoadReport(record)">报表下载</a-button>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'b'">
|
||||
<a-button class="list-button" type="link" @click="updateSetting(record)">编辑配置</a-button>
|
||||
<a-button class="list-button" type="link">删除</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
<settlement-detail
|
||||
v-show="pageStatus === 'detail'"
|
||||
@to-other-pages="detailPage"
|
||||
:id="detailId"
|
||||
@to-consult="
|
||||
(path, id) => {
|
||||
toConsult = path;
|
||||
consultId = '';
|
||||
monthId = id;
|
||||
}
|
||||
"
|
||||
/>
|
||||
<settlement-moth
|
||||
v-show="pageStatus === 'month'"
|
||||
@to-other-pages="MonthPage"
|
||||
:id="monthId"
|
||||
:detailId="detailId"
|
||||
@to-consult="(path) => (toConsult = path)"
|
||||
/>
|
||||
<settlement-consult
|
||||
v-show="pageStatus === 'consult'"
|
||||
:comme-status="toConsult"
|
||||
:monthId="monthId"
|
||||
:detailId="detailId"
|
||||
:id="consultId"
|
||||
@to-other-pages="(path) => (pageStatus = path)"
|
||||
/>
|
||||
<add-drawer @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import BasicTable from '/@/components/Table/src/BasicTable.vue';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns } from '/@/views/consult/settlement/settlement.data';
|
||||
import { ref } from 'vue';
|
||||
import SettlementDetail from '/@/views/consult/settlement/components/settlementDetail.vue';
|
||||
import SettlementMoth from '/@/views/consult/settlement/components/settlementMoth.vue';
|
||||
import SettlementConsult from '/@/views/consult/settlement/components/settlementConsult.vue';
|
||||
import AddDrawer from '/@/views/consult/settlement/components/addDrawer.vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { generateApi, listApi } from '/@/views/consult/settlement/settlement.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getFileAccessHttpUrlDown } from '/@/utils/common/compUtils';
|
||||
|
||||
const pageStatus = ref('settlement'); // 当前页面是哪个 settlement为list页 detail为详情页 month为月明细页 consult为咨询明细页
|
||||
|
||||
const detailId = ref('');
|
||||
const monthId = ref('');
|
||||
const consultId = ref('');
|
||||
|
||||
const toConsult = ref('');
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
api: listApi,
|
||||
columns,
|
||||
tableSetting: {
|
||||
redo: true,
|
||||
},
|
||||
showActionColumn: false,
|
||||
canResize: false,
|
||||
useSearchForm: false,
|
||||
actionColumn: {
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function toPage(path, record) {
|
||||
if (!record?.statementFile) {
|
||||
return message.warn('当前未生成报表,请先生成报表');
|
||||
}
|
||||
pageStatus.value = path;
|
||||
detailId.value = record.id;
|
||||
}
|
||||
function downLoadReport(record: Recordable) {
|
||||
if (!record?.statementFile) {
|
||||
return message.warn('当前未生成报表,请先生成报表');
|
||||
}
|
||||
window.open(getFileAccessHttpUrlDown(record?.statementFile));
|
||||
}
|
||||
|
||||
function updateSetting(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
isUpdate: true,
|
||||
record,
|
||||
});
|
||||
}
|
||||
|
||||
function MonthPage(path, id) {
|
||||
pageStatus.value = path;
|
||||
if (path === 'consult') consultId.value = id;
|
||||
}
|
||||
|
||||
function detailPage(path, id) {
|
||||
pageStatus.value = path;
|
||||
if (path === 'settlement') {
|
||||
return;
|
||||
} else {
|
||||
consultId.value = '';
|
||||
monthId.value = '';
|
||||
}
|
||||
if (path === 'month') {
|
||||
monthId.value = id;
|
||||
} else {
|
||||
consultId.value = id;
|
||||
}
|
||||
}
|
||||
|
||||
function addD() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
|
||||
async function generate(record: Recordable) {
|
||||
const { data } = await generateApi(record?.id);
|
||||
if (data.code === 200) {
|
||||
message.info('结算生成中,请稍后刷新');
|
||||
} else {
|
||||
message.warn(data.message);
|
||||
}
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
const [registerTable, { reload }, {}] = tableContext;
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.list-button {
|
||||
padding: 0 3px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @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 { formSchema } from '../conSicks.data';
|
||||
import { saveOrUpdate } from '../conSicks.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate, clearValidate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
//表单赋值
|
||||
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)) {
|
||||
if (!data.record.departmentId) {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
} else {
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
value: data.record.departmentId,
|
||||
status: data.record.status + '',
|
||||
});
|
||||
}
|
||||
|
||||
await clearValidate();
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params = {
|
||||
...values,
|
||||
// departmentId: values.departmentId.split(','),
|
||||
};
|
||||
//提交表单
|
||||
await saveOrUpdate(params, 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,103 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/conSicks/list',
|
||||
save = '/health-consultation/conSicks/add',
|
||||
edit = '/health-consultation/conSicks/edit',
|
||||
deleteOne = '/health-consultation/conSicks/delete',
|
||||
deleteBatch = '/health-consultation/conSicks/deleteBatch',
|
||||
importExcel = '/health-consultation/conSicks/importExcel',
|
||||
exportXls = '/health-consultation/conSicks/exportXls',
|
||||
toTop = '/health-consultation/conSicks/updateTop',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出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 });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
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
|
||||
* @param handleSuccess
|
||||
*/
|
||||
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;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
/**
|
||||
* @Description:置顶
|
||||
* @date 2023/7/7
|
||||
* @param:
|
||||
*/
|
||||
export const toTop = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '提示',
|
||||
content: `是否将该条数据${params.type === '0' ? '取消置顶' : '置顶'}?`,
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.get({ url: Api.toTop, params }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,130 @@
|
||||
import { BasicColumn, FormSchema } from '/@/components/Table';
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '疾病名称',
|
||||
align: 'center',
|
||||
dataIndex: 'sicksName',
|
||||
},
|
||||
{
|
||||
title: '关联科室',
|
||||
align: 'center',
|
||||
dataIndex: 'departmentName',
|
||||
},
|
||||
{
|
||||
title: '是否置顶',
|
||||
align: 'center',
|
||||
dataIndex: 'tfTop',
|
||||
customRender: ({ text }) => (text === 1 ? '是' : '否'),
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
align: 'center',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
];
|
||||
//查询数据
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '疾病名称',
|
||||
field: 'sicksName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: '科室名称',
|
||||
field: 'departmentId',
|
||||
component: 'JTreeDepartment',
|
||||
componentProps: {
|
||||
// api: getOfficeList,
|
||||
// resultField: 'list',
|
||||
// labelField: 'name',
|
||||
// valueField: 'id',
|
||||
// immediate: false,
|
||||
// onChange: (e) => {
|
||||
// // console.log('selected:', e);
|
||||
// },
|
||||
placeholder: '请选择科室',
|
||||
allDep: true,
|
||||
getPopupContainer: () => document.body,
|
||||
showSearch: true,
|
||||
treeNodeFilterProp: 'label',
|
||||
},
|
||||
},
|
||||
];
|
||||
//表单数据
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '疾病名称',
|
||||
field: 'sicksName',
|
||||
component: 'Input',
|
||||
rules: [{ required: true, message: '请输入疾病名称' }],
|
||||
},
|
||||
{
|
||||
label: '关联科室',
|
||||
field: 'departmentId',
|
||||
component: 'JTreeDepartment',
|
||||
componentProps: {
|
||||
valueField: 'departmentId',
|
||||
field: 'departmentId',
|
||||
allDep: true,
|
||||
immediate: true,
|
||||
getPopupContainer: () => document.body,
|
||||
showSearch: true,
|
||||
filterTreeNode: (input: string, option: any): boolean => {
|
||||
const str: string = input.toLowerCase();
|
||||
return option.departmentName.toLowerCase().indexOf(str) >= 0;
|
||||
},
|
||||
},
|
||||
dynamicRules: () => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator: (value) => {
|
||||
if (!value) {
|
||||
return Promise.reject('请选择科室');
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '是否置顶',
|
||||
field: 'tfTop',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '是',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '否',
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
field: 'sort',
|
||||
component: 'InputNumber',
|
||||
},
|
||||
// TODO 主键隐藏字段,目前写死为ID
|
||||
{
|
||||
label: '',
|
||||
field: 'id',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 流程表单调用这个方法获取formSchema
|
||||
* @param param
|
||||
*/
|
||||
export function getBpmFormSchema(_formData): FormSchema[] {
|
||||
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
|
||||
return formSchema;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="null">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" v-auth="auth.add" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增 </a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="getTableAction(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>
|
||||
<!-- 表单区域 -->
|
||||
<ConSicksModal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="consultation-conSicks" setup>
|
||||
import { BasicTable, TableAction } from '/@/components/Table';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import ConSicksModal from './components/conSicksModal.vue';
|
||||
import { columns, searchFormSchema } from './conSicks.data';
|
||||
import { list, deleteOne, getImportUrl, getExportUrl, toTop } from './conSicks.api';
|
||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||
const auth = {
|
||||
add: 'consultation:con_sicks:add',
|
||||
edit: 'consultation:con_sicks:edit',
|
||||
deleteOne: 'consultation:con_sicks:delete',
|
||||
};
|
||||
//注册model
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
//注册table数据
|
||||
const { tableContext } = useListPage({
|
||||
tableProps: {
|
||||
title: 'con_sicks',
|
||||
api: list,
|
||||
columns,
|
||||
canResize: false,
|
||||
formConfig: {
|
||||
//labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
showAdvancedButton: true,
|
||||
fieldMapToNumber: [],
|
||||
fieldMapToTime: [],
|
||||
},
|
||||
actionColumn: {
|
||||
width: 170,
|
||||
fixed: 'right',
|
||||
},
|
||||
},
|
||||
exportConfig: {
|
||||
name: 'con_sicks',
|
||||
url: getExportUrl,
|
||||
},
|
||||
importConfig: {
|
||||
url: getImportUrl,
|
||||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
|
||||
const [registerTable, { reload }, { selectedRowKeys }] = tableContext;
|
||||
|
||||
/**
|
||||
* 新增事件
|
||||
*/
|
||||
function handleAdd() {
|
||||
openModal(true, {
|
||||
isUpdate: false,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事件
|
||||
*/
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteOne({ id: record.id }, handleSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
(selectedRowKeys.value = []) && reload();
|
||||
}
|
||||
/**
|
||||
* @Description:置顶
|
||||
* @date 2023/7/8
|
||||
*/
|
||||
async function moveTop(record: Recordable) {
|
||||
toTop({ type: record.tfTop === 0 ? '1' : '0', id: record.id }, handleSuccess);
|
||||
}
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record: Recordable) {
|
||||
return [
|
||||
{
|
||||
label: `${record.tfTop === 0 ? '置顶' : '取消置顶'}`,
|
||||
onClick: moveTop.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
auth: auth.edit,
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
auth: auth.deleteOne,
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
|
||||
<div class="title"><strong>咨询信息</strong></div>
|
||||
<BasicForm @register="registerForm" />
|
||||
<div class="title"><strong>订单信息</strong></div>
|
||||
<BasicForm @register="registerFormOrder" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineExpose, ref, unref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { formSchema, formSchemaOrder } from '../doctorForHelper.data';
|
||||
import { saveOrUpdate } from '../doctorForHelper.api';
|
||||
// Emits声明
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
const isUpdate = ref(true);
|
||||
//表单配置
|
||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
});
|
||||
|
||||
//表单配置
|
||||
const [registerFormOrder, { setProps: setPropsOrder, setFieldsValue: setFieldsValueOrder }] = useForm({
|
||||
//labelWidth: 150,
|
||||
schemas: formSchemaOrder,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { span: 12 },
|
||||
});
|
||||
|
||||
//表单赋值
|
||||
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,
|
||||
});
|
||||
await setFieldsValueOrder({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
// 隐藏底部时禁用整个表单
|
||||
await setProps({ disabled: !data?.showFooter });
|
||||
await setPropsOrder({ disabled: !data?.showFooter });
|
||||
});
|
||||
//设置标题
|
||||
const title = computed(() => (!unref(isUpdate) ? '编辑' : '咨询详情'));
|
||||
//表单提交事件
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
let values = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
//提交表单
|
||||
await saveOrUpdate(values, isUpdate.value);
|
||||
//关闭弹窗
|
||||
closeModal();
|
||||
//刷新列表
|
||||
emit('success');
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
function handleRecordTable(record) {
|
||||
console.log(record);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
handleRecordTable,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/** 时间和数字输入框样式 */
|
||||
:deep(.ant-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-calendar-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,67 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/health-consultation/consultation/conSession/list',
|
||||
save = '/health-consultation/consultation/conSession/add',
|
||||
edit = '/health-consultation/consultation/conSession/edit',
|
||||
deleteOne = '/health-consultation/consultation/conSession/delete',
|
||||
deleteBatch = '/health-consultation/consultation/conSession/deleteBatch',
|
||||
importExcel = '/health-consultation/consultation/conSession/importExcel',
|
||||
exportXls = '/health-consultation/consultation/conSession/exportXls',
|
||||
}
|
||||
/**
|
||||
* 导出api
|
||||
* @param params
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => {
|
||||
params.sessionType = '3';
|
||||
// params.fromType = '1';
|
||||
return defHttp.get({ url: Api.list, 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 url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user