Files
geg-gas-web/src/views/system/menu/components/SetPrintTemplate.vue

374 lines
14 KiB
Vue
Raw Normal View History

<template>
2025-10-21 18:04:02 +08:00
<span @click.stop="open"
><slot></slot>
<ModalPanel :visible="data.visible" :width="1100" :title="t('API配置')" @submit="submit" @close="close">
<NodeHead class="mb-3 mt-3 ml-3" :nodeName="t('API配置')" />
<div class="form-box">
<div class="label"><em class="text-red-600">*</em>{{ t('打印模板') }}</div>
<a-select class="flex" v-model:value="data.printId" style="width: 100%" placeholder="请选择打印模板" @change="submitPrintId">
<a-select-option v-for="(item, index) in data.printData" :key="index" :value="item.id" :disabled="item.enabledMark == 0"> {{ item.name }}</a-select-option>
</a-select>
2025-10-21 18:04:02 +08:00
</div>
<div class="form-box">
<div class="item">
<div class="label"><em class="text-red-600">*</em>{{ t('接口名称') }}</div>
<a-input v-model:value="data.config.name" :placeholder="t('点击选择接口')" disabled style="width: 100%" class="flex">
<template #suffix>
<Icon icon="ant-design:ellipsis-outlined" />
</template>
</a-input>
</div>
<div class="item">
<div class="label"><em class="text-red-600">*</em>{{ t('请求方法') }}</div>
<a-input v-model:value="data.config.method" disabled :placeholder="t('请求方法')" class="flex" style="width: 100%">
<template #suffix>
<Icon icon="ant-design:ellipsis-outlined" />
</template>
</a-input>
</div>
</div>
<a-tabs v-if="data.visible" class="padding">
<a-tab-pane :key="item.key" :tab="item.title" v-for="item in data.apiParams">
<a-table :dataSource="item.tableInfo" :columns="apiConfigColumns" :pagination="false" :scroll="{ y: '260px' }">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'assignmentType'">
<a-select v-model:value="record.assignmentType" style="width: 100%" :placeholder="t('请选择赋值类型')">
<a-select-option :value="bind.value" v-for="bind in bindType" :key="bind.value">
{{ bind.label }}
</a-select-option>
</a-select>
</template>
<template v-else-if="column.key === 'value'">
<a-tree-select
v-if="record.assignmentType === 'data'"
v-model:value="record.config"
show-search
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="Please select"
allow-clear
tree-default-expand-all
:tree-data="data.formConfigData"
:field-names="{
children: 'children',
label: 'title',
value: 'key'
}"
/>
<a-input v-else v-model:value="record.value" :placeholder="record.type ? t('请填写值') : t('请先选择赋值类型后再配置值')" />
</template>
</template>
</a-table>
</a-tab-pane>
</a-tabs>
</ModalPanel>
</span>
</template>
<script setup lang="ts">
2025-10-21 18:04:02 +08:00
import { NodeHead, ModalPanel } from '/@/components/ModalPanel/index';
import { reactive, ref } from 'vue';
import { Icon } from '/@/components/Icon';
import { ApiConfig, InputParamItem } from '/@/components/ApiConfig/src/interface';
import { useI18n } from '/@/hooks/web/useI18n';
import { TreeProps, notification } from 'ant-design-vue';
import { PrintBasicData, PrintButtonRowItem, PrintConfigData } from '/@/model/generator/print';
import { addPrintConfig, getDesignInfo, getDesignPrintList, getPrintConfigInfo } from '/@/api/system/generator/print';
import { camelCaseString } from '/@/utils/event/design';
const { t } = useI18n();
const props = withDefaults(
defineProps<{
row: PrintButtonRowItem;
hasMetaFormId: Boolean;
}>(),
{}
);
const bindType = ref([
{
label: t('值'),
value: 'value'
}
]);
let emits = defineEmits(['close']);
let data: {
visible: boolean;
printId: string;
printData: Array<PrintBasicData>;
config: ApiConfig;
formConfigData: TreeProps['treeData'];
apiParams: Array<{ key: string; title: string; tableInfo: Array<InputParamItem> }>;
} = reactive({
visible: false,
printId: '',
printData: [],
formConfigData: [],
config: {
id: '',
name: '',
method: '',
requestParamsConfigs: [], //Query Params
requestHeaderConfigs: [], //Header
requestBodyConfigs: [] //Body
},
apiParams: [
{
key: '1',
title: 'Query Params',
tableInfo: []
},
{
key: '2',
title: 'Header',
tableInfo: []
},
{
key: '3',
title: 'Body',
tableInfo: []
}
]
});
2025-10-21 18:04:02 +08:00
function setApiConfig() {
data.apiParams[0].tableInfo = data.config.requestParamsConfigs;
2025-10-21 18:04:02 +08:00
data.apiParams[1].tableInfo = data.config.requestHeaderConfigs;
2025-10-21 18:04:02 +08:00
data.apiParams[2].tableInfo = data.config.requestBodyConfigs;
}
2025-10-21 18:04:02 +08:00
async function submitPrintId(id) {
let res = await getDesignInfo(id);
if (res) {
data.config = JSON.parse(res.apiConfig);
setApiConfig();
}
2025-10-21 18:04:02 +08:00
}
async function open() {
data.visible = true;
try {
if (props.hasMetaFormId) {
bindType.value = [
{
label: t('值'),
value: 'value'
},
{
label: t('表单数据'),
value: 'data'
}
];
}
2025-10-21 18:04:02 +08:00
let res = await getDesignPrintList();
data.printData = res;
let info = await getPrintConfigInfo(getButtonCode(), props.row.menuId);
if (info.enabledMark == null) {
// notification.warning({
// message: t('提示'),
// description: t('当前功能未绑定打印模板,请绑定后再进行模板打印。'),
// });
if (props.hasMetaFormId && info.formJson) {
let formConfig = JSON.parse(info.formJson);
let formType = 1;
if (info.formType == 0) {
//表单类型:0 系统表单 1 自定义表单
formType = 0;
}
let arr = getSchemasConfig(formConfig.formJson.list, formType);
data.formConfigData = arr;
}
} else {
if (info.enabledMark == 0) {
notification.warning({
message: t('提示'),
description: t('找不到打印模板,请联系管理员。')
});
} else {
if (props.hasMetaFormId && info.formJson) {
let formConfig = JSON.parse(info.formJson);
let formType = 1;
if (info.formType == 0) {
//表单类型:0 系统表单 1 自定义表单
formType = 0;
}
let arr = getSchemasConfig(formConfig.formJson.list, formType);
data.formConfigData = arr;
}
2025-10-21 18:04:02 +08:00
if (info.schemaId) {
data.printId = info.schemaId;
}
if (info.apiConfig) {
data.config = JSON.parse(info.apiConfig);
setApiConfig();
}
}
}
} catch (error) {}
}
function close() {
data.visible = false;
emits('close');
}
function getButtonCode() {
let buttonCode = props.row.code;
if (props.row.code.includes(':')) {
let arr = props.row.code.split(':');
arr.shift();
buttonCode = arr.join('');
}
2025-10-21 18:04:02 +08:00
return buttonCode;
}
2025-10-21 18:04:02 +08:00
async function submit() {
// 提交配置
2025-10-21 18:04:02 +08:00
let submitData: PrintConfigData = {
apiConfig: JSON.stringify(data.config),
buttonCode: getButtonCode(),
buttonId: props.row.id,
menuId: props.row.menuId,
schemaId: data.printId
};
try {
let res = await addPrintConfig(submitData);
if (res) {
close();
}
} catch (error) {}
}
function getSchemasConfig(list, formType) {
const arr: TreeProps['treeData'] = [];
if (list && list.length > 0) {
list.forEach((ele1) => {
if (['card', 'Card', 'tab', 'grid'].includes(ele1.type)) {
if (ele1.layout && ele1.layout.length > 0) {
ele1.layout.forEach((ele2) => {
if (ele2.list && ele2.list.length > 0) {
arr.push(...getSchemasConfig(ele2.list, formType));
}
});
}
} else if (['one-for-one'].includes(ele1.type) || ['form'].includes(ele1.type)) {
if (ele1.children && ele1.children.length > 0) {
arr.push(...getSchemasConfig(ele1.children, formType));
}
} else if (['table-layout'].includes(ele1.type)) {
if (ele1.layout && ele1.layout.length > 0) {
ele1.layout.forEach((ele2) => {
if (ele2.list && ele2.list.length > 0) {
ele2.list.forEach((ele3) => {
if (ele3.children && ele3.children.length > 0) {
arr.push(...getSchemasConfig(ele3.children, formType));
}
});
}
});
}
}
if (['Card', 'Tab'].includes(ele1.component)) {
if (ele1.children && ele1.children.length > 0) {
ele1.children.forEach((ele2) => {
if (ele2.list && ele2.list.length > 0) {
arr.push(...getSchemasConfig(ele2.list, formType));
}
});
}
} else if (ele1.component === 'TableLayout') {
if (ele1.children && ele1.children.length > 0) {
ele1.children.forEach((ele2) => {
if (ele2.list && ele2.list.length > 0) {
ele2.list.forEach((ele3) => {
if (ele3.children && ele3.children.length > 0) {
arr.push(...getSchemasConfig(ele3.children, formType));
}
});
}
});
}
} else if (ele1.component == 'SubForm') {
} else {
if (ele1.type && ele1.label && ele1.bindField && !disableTypes.includes(ele1.type)) {
let bindField = formType == 0 ? camelCaseString(ele1.bindField) : ele1.bindField;
arr.push({
title: ele1.label ? ele1.label : bindField,
key: bindField,
children: []
});
}
}
});
}
2025-10-21 18:04:02 +08:00
return arr;
}
2025-10-21 18:04:02 +08:00
// 去除不能选择的表单字段
const visitorsBookType = 'opinion'; //意见簿类型
const titleType = 'title'; //标题类型
const dividerType = 'divider'; //分割线类型
const infoType = 'info'; //信息体
const autoCodeType = 'auto-code'; //编码
const buttonType = 'button'; //按钮
// 标题,分割线、信息体,按钮,编码,意见簿,只允许查看权限
const disableTypes = [
visitorsBookType,
titleType,
dividerType,
infoType,
autoCodeType,
buttonType,
'qrcode' //二维码组件
];
2025-10-21 18:04:02 +08:00
const apiConfigColumns = [
{
title: t('API入参名称'),
dataIndex: 'name',
key: 'name',
align: 'center'
},
{
title: t('API入参类型'),
dataIndex: 'dataType',
key: 'dataType',
align: 'center'
},
{
title: t('赋值类型'),
dataIndex: 'assignmentType',
key: 'assignmentType',
align: 'center'
},
{
title: t('赋值配置'),
dataIndex: 'value',
key: 'value',
align: 'center'
}
];
</script>
<style lang="less" scoped>
2025-10-21 18:04:02 +08:00
.form-box {
display: flex;
justify-content: space-around;
margin: 10px 0;
}
2025-10-21 18:04:02 +08:00
.item {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
}
2025-10-21 18:04:02 +08:00
.label {
width: 100px;
margin-left: 20px;
}
2025-10-21 18:04:02 +08:00
.flex {
flex: 1;
}
2025-10-21 18:04:02 +08:00
.padding {
padding: 10px 20px;
}
</style>