前言
书接上回,导师要换项目架构,选择了Jeecg,目前已经通过Jeecg的代码生成器搭建了个简单的前后端,数据库导师也搭完了,然后让我接手剩下的,完善需求。
参考链接
需求分析
为了书写方便,会简化说明项目架构
目前有三张单表:病态评估
、治疗方案
、疗效数据
。其中的物理外键关系是,病态评估
与治疗方案
一对多,病态评估
与疗效数据
一对一。
在代码生成器生成的前端代码中,这三者是独立的,现在需求是,只能从病态评估
页面中对其余两张表新增操作(需绑定病态评估信息)
可分为以下两点处理
疗效数据
,一对一,从病态评估
页面中打开原本疗效数据
页面的新增弹窗治疗方案
,一对多,从病态评估
页面中打开治疗方案
页面,需携带病态评估
单行的数据
原始数据
这里只给出需要改动的部分
病态评估SiPatientsymptom
SiPatientsymptomList.vue
<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" 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>
<!-- 高级查询 -->
<!-- <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>
</BasicTable>
<!-- 表单区域 -->
<SiPatientsymptomModal @register="registerModal" @success="handleSuccess"></SiPatientsymptomModal>
</div>
</template>
<script lang="ts" name="siPatientsymptom-siPatientsymptom" setup>
import { ref, reactive, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import SiPatientsymptomModal from './components/SiPatientsymptomModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './SiPatientsymptom.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './SiPatientsymptom.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
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: [],
},
actionColumn: {
width: 300,
fixed: 'right',
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);
},
},
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),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
},
];
}
</script>
<style scoped></style>
治疗方案SiTherapeuticschedule
SiTherapeuticscheduleList.vue
<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" 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>
<!-- 高级查询 -->
<!-- <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 v-if="column.dataIndex === 'content'">
<!--富文本件字段回显插槽-->
<div v-html="text"></div>
</template>
</template>
</BasicTable>
<!-- 表单区域 -->
<SiTherapeuticscheduleModal @register="registerModal" @success="handleSuccess"></SiTherapeuticscheduleModal>
</div>
</template>
<script lang="ts" name="siTherapeuticschedule-siTherapeuticschedule" setup>
import { ref, reactive, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import SiTherapeuticscheduleModal from './components/SiTherapeuticscheduleModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './SiTherapeuticschedule.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './SiTherapeuticschedule.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
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: [],
},
actionColumn: {
width: 120,
fixed: 'right',
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);
},
},
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),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
},
];
}
</script>
<style scoped></style>
SiTherapeuticschedule.data.ts
import { BasicColumn } from '/@/components/Table';
import { FormSchema } from '/@/components/Table';
import { rules } from '/@/utils/helper/validator';
import { render } from '/@/utils/common/renderUtils';
//列表数据
export const columns: BasicColumn[] = [
{
title: '病人',
align: 'center',
dataIndex: 'patientName',
},
{
title: '评估症状',
align: 'center',
dataIndex: 'psymptomName',
},
{
title: '方案名称',
align: 'center',
dataIndex: 'scheme_dictText',
},
{
title: '方案内容',
align: 'center',
dataIndex: 'content',
},
];
//查询数据
export const searchFormSchema: FormSchema[] = [
{
label: '病人',
field: 'patientName',
component: 'JPopup',
componentProps: ({ formActionType }) => {
const { setFieldsValue } = formActionType;
return {
setFieldsValue: setFieldsValue,
code: 'si_patientsbaseinfo',
fieldConfig: [
{ source: 'name', target: 'patientName' },
{ source: 'id', target: 'patient' },
],
multi: true,
};
},
},
{
label: '评估症状',
field: 'psymptomName',
component: 'Input',
},
{
label: '方案名称',
field: 'scheme',
component: 'JTreeSelect',
componentProps: {
dict: 'si_schemetemplate,name,id',
pidValue: '0',
},
},
];
//表单数据
export const formSchema: FormSchema[] = [
{
label: '病人',
field: 'patientName',
component: 'Input',
},
{
label: '评估症状',
field: 'psymptom',
component: 'JSearchSelect',
componentProps: {
dict: 'si_patientsymptom,name,id',
},
dynamicRules: ({ model, schema }) => {
return [{ required: true, message: '请输入评估症状!' }];
},
},
{
label: '方案名称',
field: 'scheme',
component: 'JTreeSelect',
componentProps: {
dict: 'si_schemetemplate,name,id',
pidValue: '0',
},
dynamicRules: ({ model, schema }) => {
return [{ required: true, message: '请输入方案名称!' }];
},
},
{
label: '方案内容',
field: 'content',
component: 'JEditor',
},
// TODO 主键隐藏字段,目前写死为ID
{
label: '',
field: 'id',
component: 'Input',
show: false,
},
];
// 高级查询数据
export const superQuerySchema = {
psymptom: {
title: '评估症状',
order: 0,
view: 'sel_search',
type: 'string',
dictTable: 'si_patientsymptom',
dictCode: 'id',
dictText: 'name',
},
scheme: {
title: '方案名称',
order: 1,
view: 'sel_tree',
type: 'string',
dict: 'si_schemetemplate,name,id',
pidValue: '0',
},
content: { title: '方案内容', order: 2, view: 'umeditor', type: 'string' },
};
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[] {
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
return formSchema;
}
SiTherapeuticscheduleModal.vue
<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 '../SiTherapeuticschedule.data';
import {saveOrUpdate} from '../SiTherapeuticschedule.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,
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter })
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({confirmLoading: false});
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
疗效数据SiCurativeeffect
SiCurativeeffectList.vue
<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" 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>
<!-- 高级查询 -->
<!-- <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>
</BasicTable>
<!-- 表单区域 -->
<SiCurativeeffectModal @register="registerModal" @success="handleSuccess"></SiCurativeeffectModal>
</div>
</template>
<script lang="ts" name="siCurativeeffect-siCurativeeffect" setup>
import { ref, reactive, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import SiCurativeeffectModal from './components/SiCurativeeffectModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './SiCurativeeffect.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './SiCurativeeffect.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
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: [],
},
actionColumn: {
width: 120,
fixed: 'right',
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);
},
},
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),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
},
];
}
</script>
<style scoped></style>
SiCurativeeffect.data.ts
import { BasicColumn } from '/@/components/Table';
import { FormSchema } from '/@/components/Table';
import { rules } from '/@/utils/helper/validator';
import { render } from '/@/utils/common/renderUtils';
//列表数据
export const columns: BasicColumn[] = [
{
title: '病人',
align: 'center',
dataIndex: 'patientName',
},
{
title: '症状评估依据',
align: 'center',
dataIndex: 'psymptomName',
},
{
title: '颈椎',
align: 'center',
dataIndex: 'vertebrae',
},
{
title: '双肩',
align: 'center',
dataIndex: 'bothShoulders',
},
{
title: '圆肩含胸',
align: 'center',
dataIndex: 'roundShouldersChest',
},
{
title: '驼背',
align: 'center',
dataIndex: 'hunchbacked',
},
{
title: '平背',
align: 'center',
dataIndex: 'flatback',
},
{
title: '翼状肩',
align: 'center',
dataIndex: 'wingedShoulder',
},
{
title: '肋骨外翻',
align: 'center',
dataIndex: 'costalValgus',
},
{
title: '双肘距离',
align: 'center',
dataIndex: 'elbowDistance',
},
{
title: '脊柱侧弯',
align: 'center',
dataIndex: 'scoliosis',
},
{
title: '骨盆',
align: 'center',
dataIndex: 'pelvic',
},
{
title: '腿型',
align: 'center',
dataIndex: 'legtype',
},
{
title: '足型',
align: 'center',
dataIndex: 'foottype',
},
{
title: '长短腿',
align: 'center',
dataIndex: 'unevenleg',
},
{
title: '足',
align: 'center',
dataIndex: 'foot',
},
{
title: '膝',
align: 'center',
dataIndex: 'knee',
},
{
title: '肩',
align: 'center',
dataIndex: 'shoulder',
},
{
title: 'LPHC',
align: 'center',
dataIndex: 'lphc',
},
{
title: '平均得分',
align: 'center',
dataIndex: 'avgvalue',
},
{
title: '总得分',
align: 'center',
dataIndex: 'sumvalue',
},
{
title: '备注',
align: 'center',
dataIndex: 'remarks',
},
];
//查询数据
export const searchFormSchema: FormSchema[] = [
{
label: '病人',
field: 'patientName',
component: 'JPopup',
componentProps: ({ formActionType }) => {
const { setFieldsValue } = formActionType;
return {
setFieldsValue: setFieldsValue,
code: 'si_patientsbaseinfo',
fieldConfig: [
{ source: 'name', target: 'patientName' },
{ source: 'id', target: 'patient' },
],
multi: true,
};
},
},
{
label: '症状评估依据',
field: 'psymptomName',
component: 'Input',
},
];
//表单数据
export const formSchema: FormSchema[] = [
{
label: '病人',
field: 'patientName',
component: 'Input',
},
{
label: '症状评估依据',
field: 'psymptom',
component: 'JSearchSelect',
componentProps: {
dict: 'si_patientsymptom,name,id',
},
},
{
label: '颈椎',
field: 'vertebrae',
component: 'InputNumber',
},
{
label: '双肩',
field: 'bothShoulders',
component: 'InputNumber',
},
{
label: '圆肩含胸',
field: 'roundShouldersChest',
component: 'InputNumber',
},
{
label: '驼背',
field: 'hunchbacked',
component: 'InputNumber',
},
{
label: '平背',
field: 'flatback',
component: 'InputNumber',
},
{
label: '翼状肩',
field: 'wingedShoulder',
component: 'InputNumber',
},
{
label: '肋骨外翻',
field: 'costalValgus',
component: 'InputNumber',
},
{
label: '双肘距离',
field: 'elbowDistance',
component: 'InputNumber',
},
{
label: '脊柱侧弯',
field: 'scoliosis',
component: 'InputNumber',
},
{
label: '骨盆',
field: 'pelvic',
component: 'InputNumber',
},
{
label: '腿型',
field: 'legtype',
component: 'InputNumber',
},
{
label: '足型',
field: 'foottype',
component: 'InputNumber',
},
{
label: '长短腿',
field: 'unevenleg',
component: 'InputNumber',
},
{
label: '足',
field: 'foot',
component: 'InputNumber',
},
{
label: '膝',
field: 'knee',
component: 'InputNumber',
},
{
label: '肩',
field: 'shoulder',
component: 'InputNumber',
},
{
label: 'LPHC',
field: 'lphc',
component: 'InputNumber',
},
{
label: '平均得分',
field: 'avgvalue',
component: 'InputNumber',
dynamicDisabled: true,
},
{
label: '总得分',
field: 'sumvalue',
component: 'InputNumber',
dynamicDisabled: true,
},
{
label: '备注',
field: 'remarks',
component: 'InputTextArea',
},
// TODO 主键隐藏字段,目前写死为ID
{
label: '',
field: 'id',
component: 'Input',
show: false,
},
];
// 高级查询数据
export const superQuerySchema = {
psymptom: {
title: '症状评估依据',
order: 0,
view: 'sel_search',
type: 'string',
dictTable: 'si_patientsymptom',
dictCode: 'id',
dictText: 'name',
},
vertebrae: { title: '颈椎', order: 1, view: 'number', type: 'number' },
bothShoulders: { title: '双肩', order: 2, view: 'number', type: 'number' },
roundShouldersChest: { title: '圆肩含胸', order: 3, view: 'number', type: 'number' },
hunchbacked: { title: '驼背', order: 4, view: 'number', type: 'number' },
flatback: { title: '平背', order: 5, view: 'number', type: 'number' },
wingedShoulder: { title: '翼状肩', order: 6, view: 'number', type: 'number' },
costalValgus: { title: '肋骨外翻', order: 7, view: 'number', type: 'number' },
elbowDistance: { title: '双肘距离', order: 8, view: 'number', type: 'number' },
scoliosis: { title: '脊柱侧弯', order: 9, view: 'number', type: 'number' },
pelvic: { title: '骨盆', order: 10, view: 'number', type: 'number' },
legtype: { title: '腿型', order: 11, view: 'number', type: 'number' },
foottype: { title: '足型', order: 12, view: 'number', type: 'number' },
unevenleg: { title: '长短腿', order: 13, view: 'number', type: 'number' },
foot: { title: '足', order: 14, view: 'number', type: 'number' },
knee: { title: '膝', order: 15, view: 'number', type: 'number' },
shoulder: { title: '肩', order: 16, view: 'number', type: 'number' },
lphc: { title: 'LPHC', order: 17, view: 'number', type: 'number' },
avgvalue: { title: '平均得分', order: 18, view: 'number', type: 'number' },
sumvalue: { title: '总得分', order: 19, view: 'number', type: 'number' },
remarks: { title: '备注', order: 20, view: 'textarea', type: 'string' },
};
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[] {
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
return formSchema;
}
SiCurativeeffectModal.vue
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="1024" @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 '../SiCurativeeffect.data';
import {saveOrUpdate} from '../SiCurativeeffect.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: 8}
});
//表单赋值
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter })
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({confirmLoading: false});
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
定义打开弹窗的按钮
需要在列表数据的操作栏后添加对应按钮
在SiPatientsymptomList.vue
中,找到操作栏getTableAction
函数
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '新增方案', // 一对多,页面弹窗
onClick: addTherapeuticschedule.bind(null, record),
},
{
label: '新增疗效', // 一对一,组件弹窗
onClick: addCurativeeffect.bind(null, record),
},
];
}
再定义相关函数addTherapeuticschedule
、addCurativeeffect
,目前只在控制台打印一下,不做其他操作
/**
* 新增治疗方案
*/
function addTherapeuticschedule(record: Recordable) {
console.log('新增治疗方案');
}
/**
* 新增疗效数据
*/
function addCurativeeffect(record: Recordable) {
console.log('新增疗效数据');
}
再适当调整一下操作栏的宽度,找到actionColumn
,将width
改为300
组件弹窗
先从简单的下手,疗效数据
的新增功能只需要在病态评估
页面中调用其原本的新增弹窗即可。
1. 导入注册组件弹窗
因为在SiCurativeeffectModal.vue
中调用了新增修改接口,所以确定这是我们需要的组件弹窗
![image-20240419220628740](https://img-blog.csdnimg.cn/img_convert/
.webp?x-oss-process=image/format,png)
然后可以在SiCurativeeffectList.vue
中观察如何导入使用的(爆红是我编译器问题,提示没用到变量之类的)
可分为以下三步
- 导入该组件
- 注册弹窗Modal
- 引用并绑定
所以我们也可以照搬在病态评估
页面中
也分为上面三步走,因为注册的组件不能重名,所以要修改第二步的注册信息,第三步的成功回调函数直接用原页面的即可,以下是修改后的代码
...
<!-- 表单区域 -->
<SiPatientsymptomModal @register="registerModal" @success="handleSuccess"></SiPatientsymptomModal>
<SiCurativeeffectModal @register="registerCurativeeffectModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="siPatientsymptom-siPatientsymptom" setup>
import { ref, reactive, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import SiPatientsymptomModal from './components/SiPatientsymptomModal.vue';
import SiCurativeeffectModal from '@/views/gaitsys/siCurativeeffect/vue3/components/SiCurativeeffectModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './SiPatientsymptom.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './SiPatientsymptom.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import { useUserStore } from '/@/store/modules/user';
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
const userStore = useUserStore();
//注册model
const [registerModal, { openModal }] = useModal();
const [registerCurativeeffectModal, { openModal: openCurativeeffectModal }] = useModal();
...
2. 调用并携带数据
回到SiPatientsymptomList.vue
页面中,观察原页面中的新增编辑操作。新增是直接打开弹窗,但是并不会携带数据,后台是插入;编辑是打开弹窗并携带数据,后台是修改。我们需要的是携带数据并插入,所以要改变一下
![]() | ![]() |
---|
因为要携带数据,确保映射到弹窗的表单数据中
/**
* 新增疗效数据
*/
function addCurativeeffect(record: Recordable) {
console.log('新增疗效数据');
record.psymptom = record.id; // 映射数据
openCurativeeffectModal(true, {
record,
isUpdate: false,
showFooter: true,
});
}
要确保数据能映射到弹窗,回到弹窗组件SiCurativeeffectModal.vue
,找到useModalInner
函数,将赋值setFieldsValue
函数移动到if
外,使其能接收到传入的数据
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
await setFieldsValue({
...data.record,
});
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
需求上说只能在病态评估
页面新增,所以要将疗效数据
页面的新增按钮去掉,再将弹窗中传递来的病人名称与评估数据给禁用
修改疗效数据
页面SiCurativeeffectList.vue
,注释或删除新增按钮
修改弹窗SiCurativeeffect.data.ts
数据显示,添加disabled
字段
//表单数据
export const formSchema: FormSchema[] = [
{
label: '病人',
field: 'patientName',
component: 'Input',
componentProps: {
disabled: true,
},
},
{
label: '症状评估依据',
field: 'psymptom',
component: 'JSearchSelect',
componentProps: {
dict: 'si_patientsymptom,name,id',
disabled: true,
},
},
...
]
到这一步,组件弹窗应该就可以使用了
页面弹窗
先分析一下,我们需要在病态评估
页面中打开治疗方案
页面,还需要携带病态评估
单行的数据(即弹窗只能展示出该病人的系列治疗方案),然后在打开新增弹窗时,还要显示出携带来的病人名称与评估数据
可以分为三步
- 先将
治疗方案
页面做成一个弹窗 - 再将数据携带传到该弹窗,即初始化时,携带查询参数
- 新增时携带数据(和前面的组件弹窗类似)
参考链接
jeecg-boot:将单表列表页作为弹框,并且传递参数到解决方案(场景商品到明细信息维护)_jeecg打开弹窗传参-CSDN博客
1. 将页面改为弹窗
复制SiTherapeuticscheduleList.vue
到同级的components
目录下,重命名为SiTherapeuticscheduleListModal.vue
把页面的div
标签改为弹窗BasicModal
<BasicModal v-bind="$attrs" @register="registerListModal" destroyOnClose :title="title" :width="1200" @ok="closeModal">
...
</BasicModal>
这时候会爆红,一是没导入弹窗组件,二是有些变量没创建
先导入
import { BasicModal, useModalInner } from '/@/components/Modal';
再注册,这个页面弹窗只需要展示,不需要其他操作,所以@ok
绑定的事件就直接用closeModal
。destroyOnClose
看字面意思就是关闭时销毁
//注册model
const [registerListModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({
confirmLoading: false,
showCancelBtn: !!data?.showFooter,
showOkBtn: !!data?.showFooter,
});
});
//设置标题
const title = '管理治疗方案';
2. 传参
先在SiPatientsymptomList.vue
导入该页面弹窗,和上面组件弹窗步骤一样(先导入,再注册,最后引用)
// 1.导入组件
import SiTherapeuticscheduleListModal from '@/views/gaitsys/siTherapeuticschedule/vue3/components/SiTherapeuticscheduleListModal.vue';
import SiCurativeeffectModal from '@/views/gaitsys/siCurativeeffect/vue3/components/SiCurativeeffectModal.vue';
// 2.注册model
const [registerTherapeuticscheduleListModal, { openModal: openTherapeuticscheduleListModal }] = useModal();
// 3.引用组件
<SiTherapeuticscheduleListModal @register="registerTherapeuticscheduleListModal" @success="handleSuccess" />
然后就是打开弹窗的函数,这里传了一个record
数据过去
/**
* 新增治疗方案
*/
function addTherapeuticschedule(record: Recordable) {
console.log('新增治疗方案');
record.psymptom = record.id; // 映射数据
openTherapeuticscheduleListModal(true, {
record,
isUpdate: false,
showFooter: false,
});
}
相应的,页面弹窗组件也要接收该数据
在注册页面弹窗的时候,调用了useModalInner
函数,异步传来了data
数据,就用这个获取到传入的参数
let record = reactive<any>({});
//注册model
const [registerListModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
record = data.record;
setModalProps({
confirmLoading: false,
showCancelBtn: !!data?.showFooter,
showOkBtn: !!data?.showFooter,
});
});
最后就是打开该弹窗时,只查询传入病人的信息
找到useListPage
表单注册函数,里面的beforeFetch
就是查询时的函数
可以在查询时添加对应的参数,即可达成需求(需调整对应后端接口)
beforeFetch: (params) => {
params.patientName = record.patientName;
params.psymptomName = record.psymptomName;
return Object.assign(params, queryParam);
},
3. 携带参数打开弹窗
因为上面创建了个全局的变量record
,所以在调用新增函数handleAdd
的时候传入即可
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
record,
isUpdate: false,
showFooter: true,
});
}
确保能在新增弹窗赋值成功,需要修改SiPatientsymptomModal.vue
的useModalInner
和上面组件弹窗一样
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
await setFieldsValue({
...data.record,
});
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
然后添加表单弹窗的字段禁用,修改SiTherapeuticschedule.data.ts
的表单数据formSchema
,添加disabled
字段
//表单数据
export const formSchema: FormSchema[] = [
{
label: '病人',
field: 'patientName',
component: 'Input',
componentProps: {
disabled: true,
},
},
{
label: '评估症状',
field: 'psymptom',
component: 'JSearchSelect',
componentProps: {
dict: 'si_patientsymptom,name,id',
disabled: true,
},
dynamicRules: ({ model, schema }) => {
return [{ required: true, message: '请输入评估症状!' }];
},
},
...
];
到这一步,页面弹窗应该就可以使用了