Commit 2f38cd24 by 王宝涛

feat(finereport): 添加帆软报表预览和批量打印功能

- 新增预览地址、报表名称、打印地址、描述和启用状态字段配置
- 添加报表名称和打印地址表格列定义
- 更新帆软报表模型接口定义,增加相关字段
- 启用帆软JS库的引入,移除注释标记
- 修改API端点路径,从code获取改为params方式
- 添加表格行选择功能和预览、打印操作按钮
- 实现预览功能,支持单条记录预览
- 实现批量打印功能,支持多选报表打印
- 优化表格行点击选择逻辑
parent 8796a1bf
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<script src="/plugins/js/plugin.js"></script> <script src="/plugins/js/plugin.js"></script>
<script src="/luckysheet.umd.js"></script> <script src="/luckysheet.umd.js"></script>
<!-- 引入帆软JS库,不需要帆软报表,可不用引入。该JS库是从帆软服务器上远程引入,并且finereport.js非实体文件,而是多个JS文件拼接后的集合 --> <!-- 引入帆软JS库,不需要帆软报表,可不用引入。该JS库是从帆软服务器上远程引入,并且finereport.js非实体文件,而是多个JS文件拼接后的集合 -->
<!-- <script src="<%=VITE_GLOB_FINE_REPORT_URL%>/webroot/decision/view/report?op=emb&resource=finereport.js"></script>--> <script src="<%=VITE_GLOB_FINE_REPORT_URL%>/webroot/decision/view/report?op=emb&resource=finereport.js"></script>
<script> <script>
(async () => { (async () => {
var htmlRoot = document.getElementById('htmlRoot'); var htmlRoot = document.getElementById('htmlRoot');
......
...@@ -8,8 +8,7 @@ enum Api { ...@@ -8,8 +8,7 @@ enum Api {
List = '/system/finereport/list', List = '/system/finereport/list',
Info = '/system/finereport/info', Info = '/system/finereport/info',
MesFineReport = '/system/finereport', MesFineReport = '/system/finereport',
GetByCode = '/system/finereport/code', InfoByCode = '/system/finereport/infoByCode',
} }
...@@ -45,12 +44,13 @@ export async function getMesFineReport(id: String, mode: ErrorMessageMode = 'mod ...@@ -45,12 +44,13 @@ export async function getMesFineReport(id: String, mode: ErrorMessageMode = 'mod
} }
/** /**
* @description: 根据模板标识获取MesFineReport信息 * @description: 根据标识获取MesFineReport信息
*/ */
export async function getMesFineReportByCode(code: String, mode: ErrorMessageMode = 'modal') { export async function getMesFineReportByCode(code: String, mode: ErrorMessageMode = 'modal') {
return defHttp.get<MesFineReportPageModel>( return defHttp.get<MesFineReportPageModel>(
{ {
url: Api.GetByCode + '/' + code, url: Api.InfoByCode,
params: { code },
}, },
{ {
errorMessageMode: mode, errorMessageMode: mode,
......
...@@ -7,6 +7,16 @@ export interface MesFineReportPageParams extends BasicPageParams { ...@@ -7,6 +7,16 @@ export interface MesFineReportPageParams extends BasicPageParams {
templateName: string; templateName: string;
templateCode: string; templateCode: string;
previewUrl: string;
reportName: string;
printUrl: string;
description: string;
enabled: string;
} }
/** /**
...@@ -22,6 +32,12 @@ export interface MesFineReportPageModel { ...@@ -22,6 +32,12 @@ export interface MesFineReportPageModel {
previewUrl: string; previewUrl: string;
enabled: string; enabled: string;
reportName: string;
printUrl: string;
description: string;
} }
/** /**
......
...@@ -14,6 +14,49 @@ export const searchFormSchema: FormSchema[] = [ ...@@ -14,6 +14,49 @@ export const searchFormSchema: FormSchema[] = [
defaultValue: undefined, defaultValue: undefined,
component: 'Input', component: 'Input',
}, },
{
field: 'previewUrl',
label: '预览地址',
defaultValue: undefined,
component: 'Input',
},
{
field: 'reportName',
label: '报表名称',
defaultValue: undefined,
component: 'Input',
},
{
field: 'printUrl',
label: '打印地址',
defaultValue: undefined,
component: 'Input',
},
{
field: 'description',
label: '描述',
defaultValue: undefined,
component: 'Input',
},
{
field: 'enabled',
label: '是否启用',
defaultValue: 1,
component: 'Select',
componentProps: {
getPopupContainer: () => document.body,
options: [
{
label: '开',
value: 1,
},
{
label: '关',
value: 0,
},
],
},
},
]; ];
export const columns: BasicColumn[] = [ export const columns: BasicColumn[] = [
...@@ -68,6 +111,45 @@ export const columns: BasicColumn[] = [ ...@@ -68,6 +111,45 @@ export const columns: BasicColumn[] = [
styleConfig: undefined, styleConfig: undefined,
listStyle: undefined, listStyle: undefined,
}, },
{
resizable: true,
dataIndex: 'reportName',
title: '报表名称',
componentType: 'input',
fixed: false,
sorter: true,
styleConfig: undefined,
listStyle: '',
},
{
resizable: true,
dataIndex: 'printUrl',
title: '打印地址',
componentType: 'input',
fixed: false,
sorter: true,
styleConfig: undefined,
listStyle: '',
},
{
resizable: true,
dataIndex: 'description',
title: '描述',
componentType: 'textarea',
fixed: false,
sorter: true,
styleConfig: undefined,
listStyle: undefined,
},
]; ];
//表头合并配置 //表头合并配置
export const headerMergingData = []; export const headerMergingData = [];
...@@ -267,7 +349,7 @@ export const formProps: FormProps = { ...@@ -267,7 +349,7 @@ export const formProps: FormProps = {
scan: false, scan: false,
bordered: true, bordered: true,
isShowAi: false, isShowAi: false,
tooltipConfig: { visible: true, title: '在设计器中报表模板的名称,.cpt后缀' }, tooltipConfig: { visible: true, title: '在设计器中报表模板的名称' },
style: { width: '100%' }, style: { width: '100%' },
}, },
}, },
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<template #resizeRight> <template #resizeRight>
<BasicTable @register="registerTable" isMenuTable ref="tableRef" <BasicTable @register="registerTable" isMenuTable ref="tableRef" :row-selection="{ selectedRowKeys: selectedKeys, onChange: onSelectChange }"
> >
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
import { Modal } from 'ant-design-vue'; import { Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'; import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { BasicTable, useTable, TableAction, ActionItem } from '/@/components/Table'; import { BasicTable, useTable, TableAction, ActionItem } from '/@/components/Table';
import { getMesFineReportPage, deleteMesFineReport} from '/@/api/system/finereport'; import { getMesFineReportPage, deleteMesFineReport, getMesFineReportByCode} from '/@/api/system/finereport';
import { ResizePageWrapper } from '/@/components/Page'; import { ResizePageWrapper } from '/@/components/Page';
import { useMessage } from '/@/hooks/web/useMessage'; import { useMessage } from '/@/hooks/web/useMessage';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
...@@ -120,6 +120,9 @@ ...@@ -120,6 +120,9 @@
import { useConcurrentLock } from '/@/hooks/web/useConcurrentLock'; import { useConcurrentLock } from '/@/hooks/web/useConcurrentLock';
import { useUserStore } from '/@/store/modules/user';
const userStore = useUserStore();
const pageParamsInfo = ref<any>({}); const pageParamsInfo = ref<any>({});
const { enableLockeData,handleOpenFormEnableLockeData, handleCloseFormEnableLocke, handleHasEnableLocke } = const { enableLockeData,handleOpenFormEnableLockeData, handleCloseFormEnableLocke, handleHasEnableLocke } =
useConcurrentLock(); useConcurrentLock();
...@@ -138,9 +141,9 @@ ...@@ -138,9 +141,9 @@
//展示在列表内的按钮 //展示在列表内的按钮
const actionButtons = ref<string[]>(["view","edit","delete"]); const actionButtons = ref<string[]>(["view","edit","preview","delete"]);
const buttonConfigs = computed(()=>{ const buttonConfigs = computed(()=>{
const list = [{"isUse":true,"name":"查看","code":"view","icon":"ant-design:eye-outlined","isDefault":true},{"isUse":true,"name":"新增","code":"add","icon":"ant-design:plus-outlined","isDefault":true},{"isUse":true,"name":"编辑","code":"edit","icon":"ant-design:form-outlined","isDefault":true,"isEnableLock":true},{"isUse":true,"name":"删除","code":"delete","icon":"ant-design:delete-outlined","isDefault":true}] const list = [{"buttonId":"2017161412910284800","name":"查看","code":"view","icon":"ant-design:eye-outlined","isDefault":true,"isUse":true},{"buttonId":"2017161412914479104","name":"新增","code":"add","icon":"ant-design:plus-outlined","isDefault":true,"isUse":true},{"buttonId":"2017161412914479105","name":"编辑","code":"edit","icon":"ant-design:form-outlined","isDefault":true,"isUse":true,"isEnableLock":true},{"buttonId":"2029469719079505920","name":"帆软打印","code":"fineReportPrint","icon":"ant-design:printer-outlined","isDefault":true,"isUse":true,"showType":"top","buttonType":"primary"},{"isUse":true,"name":"预览","code":"preview","icon":"ant-design:laptop-outlined","isDefault":false,"setting":[],"showType":"inline","buttonType":"primary"},{"buttonId":"2017161412914479106","name":"删除","code":"delete","icon":"ant-design:delete-outlined","isDefault":true,"isUse":true}]
return filterButtonAuth(list); return filterButtonAuth(list);
}) })
...@@ -152,7 +155,7 @@ ...@@ -152,7 +155,7 @@
return buttonConfigs.value?.filter((x) => actionButtons.value.includes(x.code)); return buttonConfigs.value?.filter((x) => actionButtons.value.includes(x.code));
}); });
const btnEvent = {view : handleView,add : handleAdd,edit : handleEdit,delete : handleDelete,} const btnEvent = {view : handleView,add : handleAdd,edit : handleEdit,delete : handleDelete,preview : handlePreview,fineReportPrint : handleFineReportPrint, }
const { currentRoute } = useRouter(); const { currentRoute } = useRouter();
...@@ -164,6 +167,8 @@ ...@@ -164,6 +167,8 @@
const selectedKeys = ref<string[]>([]);
const selectedRowsData = ref<any[]>([]);
...@@ -196,6 +201,8 @@ ...@@ -196,6 +201,8 @@
selectedKeys.value = [];
selectedRowsData.value = [];
}, },
useSearchForm: true, useSearchForm: true,
...@@ -234,7 +241,7 @@ ...@@ -234,7 +241,7 @@
openModal(true, { isUpdate: false, }); openModal(true, { isUpdate: false, });
} }
async function handleEdit(record: Recordable) { async function handleEdit(record: Recordable) {
let field = 'id'; let field = 'id';
...@@ -267,7 +274,55 @@ ...@@ -267,7 +274,55 @@
function handleDelete(record: Recordable) { function handleDelete(record: Recordable) {
deleteList([record.id]); deleteList([record.id]);
} }
/**
* 预览fine report模板页面
* @param record
*/
function handlePreview(record: Recordable) {
const ssoToken = userStore.getFineReportToken;
const url = `${record.previewUrl}&id=${record.id}&ssoToken=${ssoToken}`;
window.open(url, '_blank');
}
/**
* 批量打印fine report模板
*/
async function handleFineReportPrint() {
if (!selectedKeys.value.length) {
notification.warning({
message: t('提示'),
description: t('请选择数据'),
});
return;
}
// 定义的模板标识
const code = 'code2';
const fineReportData = await getMesFineReportByCode(code);
let reportlets = "[";
for (const item of selectedKeys.value) {
reportlets += "{reportlet: '" + fineReportData.reportName + "', id: '" + item + "'},"
}
reportlets += "]";
const config = {
printUrl : fineReportData.printUrl,
isPopUp : false,
data :{
// 多模板格式: [{reportlet: 'name.cpt', a: 'a1'}, {reportlet: 'name.cpt', b: 'b1'}] 同样的模板会出现多页
// 单模板格式: [{reportlet: 'name.cpt', a: 'a1', b: 'b1'}] 同样的模板只会有单页
reportlets: reportlets // 需要打印的模板列表
// reportlets: [{reportlet: 'Certificate.cpt', id: '2016702346492686338'}, {reportlet: 'Certificate.cpt', id: '2016702576495734786'}]
// reportlets: "[{reportlet: 'Certificate.cpt',id: '2016702776895385601'}"
},
printType : 0, // 打印类型,0为零客户端打印,1为本地打印
// 以下为零客户端打印的参数,仅当 printType 为 0 时生效
ieQuietPrint : false,// IE静默打印设置 true为静默,false为不静默
};
window.FR.doURLPrint(config);
}
function deleteList(ids) { function deleteList(ids) {
Modal.confirm({ Modal.confirm({
title: '提示信息', title: '提示信息',
...@@ -292,10 +347,24 @@ ...@@ -292,10 +347,24 @@
function onSelectChange(selectedRowKeys: [], selectedRows) {
selectedKeys.value = selectedRowKeys;
selectedRowsData.value = selectedRows;
}
function customRow(record: Recordable) { function customRow(record: Recordable) {
return { return {
onClick: () => {
let selectedRowKeys = [...selectedKeys.value];
if (selectedRowKeys.indexOf(record.id) >= 0) {
let index = selectedRowKeys.indexOf(record.id);
selectedRowKeys.splice(index, 1);
} else {
selectedRowKeys.push(record.id);
}
selectedKeys.value = selectedRowKeys;
},
ondblclick: () => { ondblclick: () => {
if (record.isCanEdit && hasPermission("finereport:edit")) { if (record.isCanEdit && hasPermission("finereport:edit")) {
handleEdit(record); handleEdit(record);
...@@ -307,6 +376,8 @@ ...@@ -307,6 +376,8 @@
function handleSuccess() { function handleSuccess() {
selectedKeys.value = [];
selectedRowsData.value = [];
reload(); reload();
} }
...@@ -389,4 +460,4 @@ ...@@ -389,4 +460,4 @@
</style> </style>
\ No newline at end of file
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