Files
geg-gas-web/src/views/system/menu/components/SetPrintTemplate.vue
2025-10-21 18:04:02 +08:00

374 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<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>
</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">
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: []
}
]
});
function setApiConfig() {
data.apiParams[0].tableInfo = data.config.requestParamsConfigs;
data.apiParams[1].tableInfo = data.config.requestHeaderConfigs;
data.apiParams[2].tableInfo = data.config.requestBodyConfigs;
}
async function submitPrintId(id) {
let res = await getDesignInfo(id);
if (res) {
data.config = JSON.parse(res.apiConfig);
setApiConfig();
}
}
async function open() {
data.visible = true;
try {
if (props.hasMetaFormId) {
bindType.value = [
{
label: t('值'),
value: 'value'
},
{
label: t('表单数据'),
value: 'data'
}
];
}
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;
}
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('');
}
return buttonCode;
}
async function submit() {
// 提交配置
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: []
});
}
}
});
}
return arr;
}
// 去除不能选择的表单字段
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' //二维码组件
];
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>
.form-box {
display: flex;
justify-content: space-around;
margin: 10px 0;
}
.item {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
}
.label {
width: 100px;
margin-left: 20px;
}
.flex {
flex: 1;
}
.padding {
padding: 10px 20px;
}
</style>