Commit bddff9b2 authored by 孙浩然's avatar 孙浩然

报表管理--完

parent 17855e64
......@@ -22,3 +22,11 @@ export const getDictDetailDataRequest = (data: DictionaryDetailParams) =>
export const getDictsDataByCodeArrary = (data: string[]) =>
request<DictCodeDataItem[]>('/portal/public/api/web/getDict', 'post', data);
/**
* 根据类型获取字典项
* @param data
* @returns
*/
export const getClassify = (data) =>
request<string>('/bi-manager/dict/getClassify', 'post', data);
\ No newline at end of file
......@@ -17,14 +17,15 @@ export async function uploadFile(
const formData = new FormData();
formData.append('file', file, fileName);
const res = await request<ApiResult<FileRecord>>(
'/file/upload',
'/bi-manager/uploadFile/upload',
'POST',
config
formData
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
console.log("🚀 ~ res:", res)
if (res.code === 200 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.data.message));
return Promise.reject(new Error(res.message));
}
/**
......
......@@ -167,7 +167,7 @@
.then((res) => {
item.progress = 100;
item.status = 'done';
item.url = res.url;
item.url = res.imgUrl;
})
.catch((e) => {
item.status = 'exception';
......
......@@ -1135,6 +1135,7 @@
<ImageUpload
v-else-if="item.type === 'imageUpload'"
v-bind="item.props || {}"
:limit="item?.limit || 9"
ref="imageUploadRef"
:modelValue="model[item.prop]"
@update:modelValue="updateValue"
......
......@@ -11,6 +11,7 @@ declare module 'vue' {
AddExpert: typeof import('./../components/TaskAllocation/AddExpert.vue')['default']
AddMenu: typeof import('./../views/web/components/AddMenu.vue')['default']
AddReport: typeof import('./../views/report/components/AddReport.vue')['default']
AddReportDetail: typeof import('./../views/report/components/AddReportDetail.vue')['default']
AddRole: typeof import('./../views/role/components/AddRole.vue')['default']
AddSys: typeof import('./../views/report/components/AddSys.vue')['default']
AddTheme: typeof import('./../views/theme/components/AddTheme.vue')['default']
......
......@@ -4,6 +4,8 @@
:title="modalTitle"
width="600px"
position="center"
:close-on-click-modal="false"
@close="handleClose"
>
<ele-loading :loading="pageLoading">
<ele-card>
......@@ -19,7 +21,7 @@
</ele-card>
</ele-loading>
<template #footer>
<el-button type="primary" plain @click="handleCancel">取消</el-button>
<el-button type="primary" plain @click="handleClose">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</ele-modal>
......@@ -36,6 +38,8 @@
import { EleMessage } from 'ele-admin-plus';
// apis
import reportApi from '@/api/reportApi';
import sysApi from '@/api/sysApi';
import { getClassify } from '@/api/common/dictionary';
const props = defineProps<{
curSelectSys: any;
......@@ -48,17 +52,24 @@
return useType.value === 'add' ? '添加报表' : '编辑报表';
});
onMounted(() => {
getClassifyList(); // 获取报表分类
});
// 打开
const curInfo = ref<addReportDto>();
const open = (type: 'add' | 'edit' = 'add', info?: addReportDto) => {
useType.value = type;
modalVisible.value = true;
getSysList(); // 获取系统列表
if (type === 'edit') {
curInfo.value = info;
Object.assign(form, info);
}
console.log(props.curSelectSys);
form.reportCategory = info.dictDataValue.split(',');
} else {
form.sysId = [props.curSelectSys.sysId];
}
};
defineExpose({
open: open as (type: 'add' | 'edit', info?: addReportDto) => void
......@@ -69,17 +80,70 @@
reportStyleUrl: '',
reportName: '',
reportCategory: [],
sysId: [],
reportType: 1
reportType: 1,
sysId: [] // 系统id
});
const sysList = ref([]); // 系统列表
/** 获取系统列表 */
const getSysList = async () => {
let params = {
pageNum: 1,
pageSize: 99999
};
const [error, ret] = await tryit(sysApi.getSysList)(params);
if (error) {
console.error(error);
return;
}
if (ret.code === 200) {
sysList.value = ret.data.list.map((item) => {
return {
label: item.sysName,
value: item.sysId
};
});
}
};
const classifyList = ref([]); // 报表类型
// 获取报表分类
const getClassifyList = async () => {
let params = {
typeId: 'MEDICAL_ROLE'
};
const [error, ret] = await tryit(getClassify)(params);
if (error) {
console.error(error);
return;
}
if (ret.code === 200) {
classifyList.value = ret.data.map((item) => {
return {
label: item.dataLabel,
value: item.dataValue
};
});
}
};
/** 表单项 */
const items = computed<Array<ProFormItemProps>>(() => [
{
label: '所属系统',
prop: 'sysId',
type: 'multipleSelect',
options: sysList.value,
required: true
},
{ label: '报表名称', prop: 'reportName', type: 'input', required: true },
{
label: '报表样式图片地址',
prop: 'reportStyleUrl',
type: 'input',
label: '报表分类',
prop: 'reportCategory',
type: 'multipleSelect',
multiple: true,
options: classifyList.value,
required: true
},
{
......@@ -99,12 +163,12 @@
required: true
},
{
label: '报表分类',
prop: ' reportCategory',
type: 'select',
multiple: true,
options: [],
required: false
label: '报表样式图片地址',
prop: 'reportStyleUrl',
// type: 'input',
type: 'imageUpload',
limit: 1,
required: true
}
]);
......
<template>
<ele-modal
v-model="modalVisible"
:title="modalTitle"
width="600px"
position="center"
:close-on-click-modal="false"
@close="handleClose"
>
<ele-loading :loading="pageLoading">
<ele-card>
<pro-form
ref="ProFormRef"
label-width="auto"
:model="form"
:items="items"
:footer="false"
:grid="{ span: 24 }"
@updateValue="setFieldValue"
/>
</ele-card>
</ele-loading>
<template #footer>
<el-button type="primary" plain @click="handleClose">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</ele-modal>
</template>
<script lang="ts" setup>
// tools
import { useFormData } from '@/utils/use-form-data';
import { tryit } from 'radash';
// types
import type { addReportDetailDto } from '@/types/BiReport';
import type { ProFormItemProps } from '@/components/ProForm/types';
import type { FormInstance } from 'element-plus';
import { EleMessage } from 'ele-admin-plus';
// apis
import reportApi from '@/api/reportApi';
const props = defineProps<{
curSelectReport: any;
}>();
const useType = ref<'add' | 'edit'>('add');
const modalVisible = ref(false);
const modalTitle = computed(() => {
return useType.value === 'add' ? '添加详情' : '编辑详情';
});
// 打开
const curInfo = ref<addReportDetailDto>();
const open = (type: 'add' | 'edit' = 'add', info?: addReportDetailDto) => {
useType.value = type;
modalVisible.value = true;
if (type === 'edit') {
curInfo.value = info;
Object.assign(form, info);
} else {
form.reportId = props.curSelectReport.reportId;
}
};
defineExpose({
open: open as (type: 'add' | 'edit', info?: addReportDetailDto) => void
});
/** 表单数据 */
const [form, resetFields, , setFieldValue] = useFormData<addReportDetailDto>({
calculationFormula: '', // 计算公式
fieldName: '', // 字段名称
remark: '', // 备注信息
reportId: '' // 绑定报表id
// detailId: '' //
});
/** 表单项 */
const items = computed<Array<ProFormItemProps>>(() => [
{
label: '字段名',
prop: 'fieldName',
type: 'input',
required: true
},
{
label: '公式',
prop: 'calculationFormula',
type: 'input',
required: true
},
{
label: '备注',
prop: 'remark',
type: 'textarea'
}
]);
/** 提交 */
const ProFormRef = ref<FormInstance>();
const pageLoading = ref(false);
const emits = defineEmits(['reload']);
const onSubmit = () => {
ProFormRef.value?.validate(async (valid) => {
if (!valid) {
EleMessage.warning('请填写必填项');
return;
}
ElMessageBox.confirm(
`确定要${useType.value === 'add' ? '保存' : '修改'}?`,
'提示',
{
type: 'warning'
}
).then(async () => {
pageLoading.value = true;
const apiObj = {
add: reportApi.addReportDetail,
edit: reportApi.editReportDetail
};
const [, ret] = await tryit(apiObj[useType.value!])(form);
if (ret?.code === 200) {
EleMessage.success(useType.value === 'add' ? '添加成功' : '修改成功');
emits('reload');
handleClose();
}
pageLoading.value = false;
});
});
};
// 关闭
const handleClose = () => {
modalVisible.value = false;
resetFields();
};
// 点击取消
const handleCancel = () => {
modalVisible.value = false;
};
</script>
......@@ -4,6 +4,8 @@
:title="modalTitle"
width="600px"
position="center"
:close-on-click-modal="false"
@close="handleClose"
>
<ele-loading :loading="pageLoading">
<ele-card>
......@@ -19,7 +21,7 @@
</ele-card>
</ele-loading>
<template #footer>
<el-button type="primary" plain @click="handleCancel">取消</el-button>
<el-button type="primary" plain @click="handleClose">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</ele-modal>
......
<template>
<div class="page-wrapper">
<div class="page-wrapper-left">
<!-- 系统列表 -->
<div class="page-wrapper-left-item">
<div class="p-10px flex w-full overflow-hidden">
<FcCardTip title="搜索系统" />
......@@ -9,6 +10,7 @@
v-model="params.name"
@change="fetchSysList"
placeholder="搜索系统名称"
clearable
/>
</div>
<el-button
......@@ -18,7 +20,11 @@
>新增系统</el-button
>
</div>
<vxe-grid v-bind="leftTOptions" @cell-click="handleCellClickTopGrid">
<vxe-grid
ref="leftTRef"
v-bind="leftTOptions"
@cell-click="handleCellClickTopGrid"
>
<template #option_slot="{ row }">
<el-link type="success" @click="AddSysRef.open('edit', row)">
编辑
......@@ -28,6 +34,7 @@
</template>
</vxe-grid>
</div>
<!-- 报表列表 -->
<div class="page-wrapper-left-item">
<div class="p-10px flex w-full overflow-hidden">
<FcCardTip title="搜索报表" />
......@@ -36,13 +43,27 @@
v-model="reportParams.name"
@change="fetchReportList"
placeholder="搜索报表名称"
clearable
/>
</div>
<el-button class="m-r-15px" type="primary" @click="handleAddReport"
>新增报表</el-button
>
</div>
<vxe-grid v-bind="leftBOptions">
<vxe-grid
ref="leftBRef"
v-bind="leftBOptions"
@cell-click="handleCellClickBottomGrid"
>
<!-- 报表样式 -->
<template #reportStyleUrl="{ row }">
<el-image
:src="row.reportStyleUrl"
style="width: 50px; height: 50px"
fit="cover"
/>
</template>
<!-- 操作列 -->
<template #option_slot="{ row }">
<el-link type="success" @click="AddReportRef.open('edit', row)">
编辑
......@@ -54,6 +75,7 @@
</div>
</div>
<!-- 报表详情 -->
<div>
<vxe-grid v-bind="centerOptions">
<template #buttons_slot>
......@@ -61,18 +83,50 @@
<FcCardTip title="报表详情" />
</div>
</template>
<!-- 右上角按钮 -->
<template #tools_slot>
<div class="p-r-6px">
<el-button type="primary">新增明细</el-button>
<el-button type="primary" @click="() => AddReportDetailRef.open()"
>新增明细</el-button
>
</div>
</template>
<!-- 操作列 -->
<template #option_slot="{ row }">
<el-link type="success" @click="AddReportDetailRef.open('edit', row)">
编辑
</el-link>
<el-divider direction="vertical" />
<el-link type="danger" @click="handleDelReportDetail(row)"
>删除</el-link
>
</template>
</vxe-grid>
</div>
<div class="page-wrapper-item"> 报表样式 </div>
<div class="page-wrapper-item">
<div class="page-wrapper-title">报表样式</div>
<div>
<img
v-if="curSelectReport?.reportStyleUrl"
class="page-wrapper-img"
:src="curSelectReport.reportStyleUrl"
alt=""
mode="widthFix"
/>
</div>
</div>
<!-- 新增/编辑系统 -->
<AddSys ref="AddSysRef" @reload="fetchSysList" />
<!-- 新增/编辑报表 -->
<AddReport ref="AddReportRef" :curSelectSys @reload="fetchReportList" />
<!-- 新增/编辑 报表明细 -->
<AddReportDetail
ref="AddReportDetailRef"
:curSelectReport
@reload="fetchReportDetail"
></AddReportDetail>
</div>
</template>
......@@ -87,15 +141,39 @@
// coms
import AddSys from './components/AddSys.vue';
import AddReport from './components/AddReport.vue';
import AddReportDetail from './components/AddReportDetail.vue';
// apis
import reportApi from '@/api/reportApi';
import sysApi from '@/api/sysApi';
const AddSysRef = ref();
const AddReportRef = ref();
const AddReportDetailRef = ref();
// 删除报表详情
const handleDelReportDetail = (row) => {
ElMessageBox.confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
leftBOptions.loading = true;
const [error, ret] = await tryit(reportApi.deleteReportDetail)({
id: row.detailId
});
if (error) {
console.error(error);
return;
}
if (ret?.code === 200) {
ElMessage.success('删除成功');
fetchReportDetail();
}
});
};
// 删除报表
const handleDelReport = ({ row }) => {
const handleDelReport = (row) => {
ElMessageBox.confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
......@@ -103,7 +181,7 @@
}).then(async () => {
leftBOptions.loading = true;
const [error, ret] = await tryit(reportApi.deleteReport)({
id: row.id
id: row.reportId
});
if (error) {
console.error(error);
......@@ -149,13 +227,27 @@
ElMessage.warning('请选择系统');
return;
}
AddReportRef.value.open();
};
// 点击上方报表表格
// 点击上方系统表格
const curSelectSys = ref();
const handleCellClickTopGrid = ({ row }) => {
curSelectSys.value = row;
fetchReportList();
};
// 点击下方报表表格
const curSelectReport = ref(); // 当前选中的报表
const handleCellClickBottomGrid = ({ row }) => {
curSelectReport.value = row;
// 将下级一个联动表格的数据清空
centerOptions.value.data = [];
fetchReportDetail();
};
// 获取系统
......@@ -171,16 +263,53 @@
pageSize: 100,
name: ''
});
const leftTRef = ref();
const leftBRef = ref();
// 获取报表详情
const fetchReportDetail = async () => {
centerOptions.value.loading = true;
let params = {
id: curSelectReport.value.reportId,
pageNum: 1,
pageSize: 100
};
const [error, ret] = await tryit(reportApi.getReportDetail)(params);
if (error) {
console.error(error);
return;
}
if (ret.code === 200) {
centerOptions.value.data = ret.data.list || [];
}
centerOptions.value.loading = false;
};
// 获取报表列表
const fetchReportList = async () => {
leftTOptions.value.loading = true;
const [err, ret] = await tryit(reportApi.getReportList)(reportParams.value);
leftBOptions.value.loading = true;
let params = {
...reportParams.value,
sysId: curSelectSys.value?.sysId
};
const [err, ret] = await tryit(reportApi.getReportList)(params);
if (err) {
console.error(err);
return;
}
if (ret.code === 200) {
leftTOptions.value.data = ret.data.list;
leftBOptions.value.data = ret.data.list || [];
// 将下级一个联动表格的数据清空
centerOptions.value.data = [];
curSelectReport.value = null;
if (leftBOptions.value.data.length) {
leftBRef.value.setCurrentRow(leftBOptions.value.data[0]);
curSelectReport.value = leftBOptions.value.data[0];
fetchReportDetail();
}
}
leftBOptions.value.loading = false;
};
// 获取系统列表
......@@ -192,15 +321,26 @@
return;
}
if (ret.code === 200) {
leftTOptions.value.data = ret.data.list;
leftTOptions.value.data = ret.data.list || [];
// 将下级联动表格的数据清空
leftBOptions.value.data = [];
curSelectSys.value = null;
if (leftTOptions.value.data.length) {
leftTRef.value.setCurrentRow(leftTOptions.value.data[0]);
curSelectSys.value = leftTOptions.value.data[0];
fetchReportList();
}
}
leftTOptions.value.loading = false;
};
onMounted(() => {
fetchSysList();
fetchReportList();
// fetchReportList();
});
// 系统表格配置
const leftTOptions = ref<VxeGridProps<getSysListDto>>({
loading: false,
border: true,
......@@ -226,6 +366,8 @@
},
{
title: '操作',
width: 100,
fixed: 'right',
slots: {
default: 'option_slot'
}
......@@ -233,26 +375,53 @@
],
data: []
});
const leftBOptions: VxeGridProps = {
// 报表表格配置
const leftBOptions = ref<VxeGridProps<getReportListDto>>({
loading: false,
border: true,
showHeaderOverflow: true,
showOverflow: true,
height: '100%',
rowConfig: {
isCurrent: true,
isHover: true
},
columns: [
{
field: 'reportName',
title: '报表名称',
width: 120,
align: 'center',
headerAlign: 'center'
},
{
field: 'sex'
field: 'dictDataName',
title: '报表分类',
align: 'center',
headerAlign: 'center'
},
{
field: 'reportType',
title: '报表分类',
align: 'center',
headerAlign: 'center',
formatter: (row) => {
return row.cellValue === 1 ? '帆软' : '自建';
}
]
};
const centerOptions: VxeGridProps = {
},
{
title: '操作',
width: 100,
fixed: 'right',
slots: {
default: 'option_slot'
}
}
],
data: []
});
// 报表详情配置
const centerOptions = ref<VxeGridProps>({
loading: false,
round: true,
border: true,
showHeaderOverflow: true,
......@@ -266,20 +435,34 @@
},
columns: [
{
field: 'name',
title: 'Name',
width: 120,
field: 'fieldName',
title: '字段名',
align: 'center',
headerAlign: 'center'
},
{
field: 'calculationFormula',
title: '公式',
align: 'center',
headerAlign: 'center'
},
{
field: 'remark',
title: '备注',
align: 'center',
headerAlign: 'center'
},
{
title: '操作',
width: 100,
fixed: 'right',
slots: {
default: 'option_slot'
}
}
]
};
],
data: []
});
</script>
<style lang="scss" scoped>
......@@ -308,5 +491,17 @@
overflow: hidden !important;
}
}
&-title {
height: 46px;
box-sizing: border-box;
padding: 12px;
font-size: 16px;
color: #333333;
}
&-img {
width: 100%;
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment