1549 lines
42 KiB
Vue
1549 lines
42 KiB
Vue
<script lang="ts" setup>
|
||
import Sortable from 'sortablejs';
|
||
import XEUtils from 'xe-utils';
|
||
import { getCurrentInstance, nextTick, onMounted, reactive, ref } from 'vue';
|
||
import { cloneDeep, random } from 'lodash';
|
||
import { Message } from '@arco-design/web-vue';
|
||
|
||
import { IconDragArrow, IconPlus, IconDelete } from '@arco-design/web-vue/es/icon';
|
||
|
||
import {
|
||
postParameterParse,
|
||
postParameterValidateParameter,
|
||
} from '@/api/ParameterServices/parameter';
|
||
import { getInterfaceGetInterfaceById } from '@/api/InterfaceServices/interface';
|
||
import { postInterfaceSaveServiceProviderInterface } from '@/api/InterfaceServices/serviceProviderInterface';
|
||
import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary';
|
||
import { $baseMessage, $baseConfirm } from '@/utils';
|
||
import { useI18n } from 'vue-i18n';
|
||
import { paramColumns, formItems, formRules, validRulesEdit } from '../../interface/config';
|
||
// Import API types
|
||
import type { ParameterInput } from '@/api/types';
|
||
|
||
const { t } = useI18n();
|
||
const emit = defineEmits(['close', 'saved']);
|
||
|
||
defineOptions({
|
||
name: 'ServiceProviderInterfaceModal',
|
||
});
|
||
|
||
// 添加类型注解的响应式变量
|
||
const drawerVisible = ref<boolean>(false); // 参数弹窗(布尔类型)
|
||
const drawerVisible1 = ref<boolean>(false); // 参数弹窗(布尔类型)
|
||
const analysisLoading = ref<boolean>(false); // 解析loading(布尔类型)
|
||
const importLoading = ref<boolean>(false); // 导入loading(布尔类型)
|
||
const flag = ref<boolean>(false); // 标识(布尔类型)
|
||
const { proxy } = getCurrentInstance() || { proxy: null };
|
||
const refSearchForm = ref<any | undefined>(); // 表单组件引用(可能为undefined)
|
||
const tabs = ref<'Json' | 'Xml'>('Json'); // 标签页状态(仅允许"Json"/"Xml")
|
||
const tabs1 = ref<'Json' | 'Xml'>('Json'); // 标签页状态(仅允许"Json"/"Xml")
|
||
const textareaJson = ref<string>(''); // Json文本域(字符串类型)
|
||
const textareaXml = ref<string>(''); // Xml文本域(字符串类型)
|
||
const textareaJson1 = ref<string>(''); // 返回参数Json文本域(字符串类型)
|
||
const textareaXml1 = ref<string>(''); // 返回参数Xml文本域(字符串类型)
|
||
const dataList = ref<any[] | undefined>(); // 解析后的数据列表(任意数组或undefined)
|
||
const dataList1 = ref<any[] | undefined>(); // 返回参数解析后的数据列表(任意数组或undefined)
|
||
const tableRef = ref(); // 请求参数表格引用(可能为undefined)
|
||
const tableRef1 = ref(); // 返回参数表格引用(可能为undefined)
|
||
|
||
// 服务商接口特有的字段
|
||
const serviceProviderId = ref<number>(0);
|
||
const serviceProviderName = ref<string>('');
|
||
const isEditMode = ref<boolean>(false);
|
||
|
||
// 添加类型注解的响应式对象
|
||
const tableForm = reactive<any>({
|
||
optionType: 1,
|
||
id: 0,
|
||
name: '',
|
||
abbreviation: '',
|
||
requestAddress: '',
|
||
description: '',
|
||
isBatch: true,
|
||
requestProtocol: undefined,
|
||
requestMethod: undefined,
|
||
category: undefined,
|
||
contentType: undefined,
|
||
isReturnMessage: true,
|
||
// 服务商接口特有字段
|
||
serviceProviderId: 0,
|
||
qps: 0,
|
||
isDisableAuth: false,
|
||
mappedParamType: undefined,
|
||
responseContentType: undefined,
|
||
inParameterList: [],
|
||
outParameterList: [],
|
||
});
|
||
|
||
const tableProps = reactive<any>({
|
||
columns: [
|
||
...paramColumns.map((col: any) => ({ ...col })),
|
||
// 在末尾追加“必填”列(单选框)
|
||
{
|
||
field: 'isRequired',
|
||
title: '必填',
|
||
width: 80,
|
||
align: 'center',
|
||
slots: { default: 'isRequired' },
|
||
},
|
||
],
|
||
isCellSort: false,
|
||
showToolbar: false,
|
||
isColumnsDrag: false,
|
||
showPager: false,
|
||
tableConfig: {
|
||
editConfig: {
|
||
trigger: 'click',
|
||
mode: 'row',
|
||
showStatus: true,
|
||
autoClear: false,
|
||
},
|
||
},
|
||
showIndex: false,
|
||
data: [],
|
||
minHeight: 200,
|
||
keepSource: true,
|
||
size: 'small',
|
||
useForm: false,
|
||
autoHeight: false,
|
||
maxHeight: 500,
|
||
editRules: validRulesEdit.value,
|
||
toolbarConfig: {
|
||
setting: false
|
||
},
|
||
});
|
||
|
||
const tableProps1 = reactive<any>({
|
||
columns: [
|
||
...paramColumns.map((col: any) => ({ ...col })),
|
||
{
|
||
field: 'isRequired',
|
||
title: '必填',
|
||
width: 80,
|
||
align: 'center',
|
||
slots: { default: 'isRequired' },
|
||
},
|
||
],
|
||
isCellSort: false,
|
||
showToolbar: false,
|
||
isColumnsDrag: false,
|
||
showPager: false,
|
||
|
||
tableConfig: {
|
||
editConfig: {
|
||
trigger: 'click',
|
||
mode: 'row',
|
||
showStatus: true,
|
||
autoClear: false,
|
||
},
|
||
},
|
||
showIndex: false,
|
||
data: [],
|
||
minHeight: 200,
|
||
keepSource: true,
|
||
size: 'small',
|
||
useForm: false,
|
||
autoHeight: false,
|
||
maxHeight: 500,
|
||
editRules: validRulesEdit.value,
|
||
toolbarConfig: {
|
||
setting: false
|
||
},
|
||
});
|
||
|
||
let sortable: any = null;
|
||
let sortable1: any = null;
|
||
// 请求参数排序
|
||
const requestSort = ref<any[]>([]);
|
||
// 返回参数排序
|
||
const backSort = ref<any[]>([]);
|
||
|
||
// 获取行号
|
||
function getRowSeq(row: any, refTable: any) {
|
||
console.log(refTable, 'refTable.xGrid');
|
||
console.log(
|
||
refTable.xGrid?.getRowSeq(row),
|
||
'refTable.xGrid?.getRowSeq(row)'
|
||
);
|
||
return `${refTable.xGrid?.getRowSeq(row)}` || '0';
|
||
}
|
||
|
||
const ParameterTypeList = ref<any[]>([]);
|
||
|
||
async function EnumValueInfoGetList() {
|
||
const list = await getDictionaryGetList({
|
||
type: 'ParameterType',
|
||
});
|
||
ParameterTypeList.value = list;
|
||
}
|
||
|
||
// 服务商接口特有的表单配置
|
||
const serviceProviderFormItems = [
|
||
{
|
||
comp: 'a-input',
|
||
field: 'name',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '* 请填写接口中文名称',
|
||
},
|
||
},
|
||
{
|
||
comp: 'a-input',
|
||
field: 'abbreviation',
|
||
label: '',
|
||
span: 6,
|
||
required: true,
|
||
compProps: {
|
||
placeholder: '* 请填写接口code',
|
||
},
|
||
},
|
||
{
|
||
comp: 'SelectPro',
|
||
field: 'requestProtocol',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '* 请选择请求协议',
|
||
api: getDictionaryGetList,
|
||
extra: { type: 'RequestProtocol' },
|
||
labelKeys: ['value'],
|
||
idKey: 'key',
|
||
isPage: false,
|
||
showHeader: false,
|
||
},
|
||
},
|
||
{
|
||
comp: 'SelectPro',
|
||
field: 'requestMethod',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '* 请选择请求方式',
|
||
api: getDictionaryGetList,
|
||
extra: { type: 'RequestMethod' },
|
||
labelKeys: ['value'],
|
||
idKey: 'key',
|
||
isPage: false,
|
||
showHeader: false,
|
||
},
|
||
},
|
||
{
|
||
comp: 'a-input',
|
||
field: 'requestAddress',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '* 例: http://xx/api/CreateOrder',
|
||
},
|
||
},
|
||
{
|
||
comp: 'SelectPro',
|
||
field: 'contentType',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '* 请选择Content-Type',
|
||
api: getDictionaryGetList,
|
||
extra: { type: 'ContentType' },
|
||
labelKeys: ['value'],
|
||
idKey: 'key',
|
||
isPage: false,
|
||
showHeader: false,
|
||
},
|
||
},
|
||
{
|
||
comp: 'SelectPro',
|
||
field: 'responseContentType',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '请选择Response-Content-Type',
|
||
api: getDictionaryGetList,
|
||
extra: { type: 'ResponseContentType' },
|
||
labelKeys: ['value'],
|
||
idKey: 'key',
|
||
isPage: false,
|
||
showHeader: false,
|
||
},
|
||
},
|
||
{
|
||
comp: 'SelectPro',
|
||
field: 'isDisableAuth',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
options: [
|
||
{ value: true, label: '是' },
|
||
{ value: false, label: '否' },
|
||
],
|
||
labelKeys: ['label'],
|
||
idKey: 'value',
|
||
isPage: false,
|
||
showHeader: false,
|
||
},
|
||
},
|
||
{
|
||
comp: 'a-input-number',
|
||
field: 'qps',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
min: 0,
|
||
precision: 0,
|
||
controlsPosition: 'right',
|
||
valueOnClear: 0,
|
||
controls: false,
|
||
placeholder: 'QPS',
|
||
style: { width: '100%' },
|
||
},
|
||
},
|
||
{
|
||
comp: 'SelectPro',
|
||
field: 'mappedParamType',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
api: getDictionaryGetList,
|
||
extra: { type: 'ParameterType' },
|
||
placeholder: '请选择根节点',
|
||
labelKeys: ['value'],
|
||
idKey: 'key',
|
||
isPage: false,
|
||
showHeader: false,
|
||
style: { width: '100%' },
|
||
},
|
||
},
|
||
{
|
||
comp: 'a-input',
|
||
field: 'description',
|
||
label: '',
|
||
span: 6,
|
||
compProps: {
|
||
placeholder: '请输入接口备注',
|
||
allowClear: true,
|
||
style: { width: '100%' },
|
||
},
|
||
},
|
||
];
|
||
|
||
// 服务商接口特有的验证规则
|
||
const serviceProviderFormRules = {
|
||
name: [{ required: true, message: '输入不能为空', trigger: 'change' }],
|
||
abbreviation: [
|
||
{ required: true, message: '输入不能为空', trigger: 'change' },
|
||
{
|
||
max: 30,
|
||
message: '请控制长度在30个字符之内',
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
requestAddress: [
|
||
{ required: true, message: '输入不能为空', trigger: 'change' },
|
||
],
|
||
requestProtocol: [
|
||
{ required: true, message: '请选择请求协议', trigger: 'change' },
|
||
],
|
||
requestMethod: [
|
||
{ required: true, message: '请选择请求方式', trigger: 'change' },
|
||
],
|
||
contentType: [
|
||
{ required: true, message: '请选择Content-Type', trigger: 'change' },
|
||
],
|
||
description: [
|
||
{
|
||
max: 200,
|
||
message: '请控制长度在200个字符之内',
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
};
|
||
|
||
// 初始化函数
|
||
async function init(data?: any) {
|
||
if (data) {
|
||
serviceProviderId.value = data.serviceProviderId;
|
||
serviceProviderName.value = data.serviceProviderName;
|
||
isEditMode.value = data.mode === 'edit';
|
||
|
||
if (isEditMode.value && data.id) {
|
||
// 编辑模式,加载接口数据
|
||
const interfaceData = await getInterfaceGetInterfaceById({
|
||
id: data.id,
|
||
});
|
||
refSearchForm.value?.setFormValue(interfaceData);
|
||
// 确保编辑时携带正确的标识与操作类型
|
||
tableForm.id = interfaceData.id || data.id;
|
||
tableForm.optionType = 3;
|
||
tableForm.inParameterList = interfaceData.inParameterList || [];
|
||
tableForm.outParameterList = interfaceData.outParameterList || [];
|
||
tableProps.data = interfaceData.inParameterList || [];
|
||
tableProps1.data = interfaceData.outParameterList || [];
|
||
tableRef.value?.reloadData(interfaceData.inParameterList || []);
|
||
tableRef1.value?.reloadData(interfaceData.outParameterList || []);
|
||
} else {
|
||
// 新增模式,设置默认值
|
||
tableForm.serviceProviderId = serviceProviderId.value;
|
||
tableForm.id = 0;
|
||
tableForm.optionType = 1;
|
||
}
|
||
}
|
||
|
||
await EnumValueInfoGetList();
|
||
}
|
||
|
||
// 保存函数
|
||
async function saveInterface() {
|
||
try {
|
||
// 结束编辑,确保勾选/输入值写回行数据
|
||
await tableRef.value?.clearActived?.();
|
||
await tableRef1.value?.clearActived?.();
|
||
|
||
const formData = refSearchForm.value?.getValues();
|
||
if (!formData) {
|
||
$baseMessage('请填写完整信息', 'error');
|
||
throw new Error('请填写完整信息');
|
||
}
|
||
|
||
// 规范化参数列表:只保留后端需要的字段,并写入排序,去除 children/_X_ROW_CHILD 等UI字段
|
||
const normalizeList = (arr: any[] = [], isInPara: boolean) => {
|
||
return (arr || []).map((item: any, idx: number) => ({
|
||
id: item.id ?? 0,
|
||
pId: item.pId ?? 0,
|
||
alias: item.alias ?? item.name ?? '',
|
||
name: item.name ?? '',
|
||
cnName: item.cnName ?? null,
|
||
type: item.type,
|
||
isRequired: !!item.isRequired,
|
||
description: item.description ?? null,
|
||
isInPara: isInPara,
|
||
sort: String(idx + 1),
|
||
optionType: item.optionType ?? 3, // 编辑模式下默认为修改操作
|
||
}));
|
||
};
|
||
|
||
// 从表单容器中取最新数据(表格在编辑模式下)
|
||
const inList = (tableRef.value?.getTableData?.().fullData ?? tableForm.inParameterList) as any[];
|
||
const outList = (tableRef1.value?.getTableData?.().fullData ?? tableForm.outParameterList) as any[];
|
||
|
||
// 同步表单双向数据,保证界面与提交一致
|
||
// 规范化参数列表:去除UI字段、isRequired转数值、sort转字符串
|
||
const normalizedIn = normalizeList(inList, true).map((it: any, idx: number) => {
|
||
const { _X_ROW_CHILD, _X_ROW_KEY, children, ...rest } = it || {};
|
||
const payload: any = {
|
||
...rest,
|
||
// 按工作版请求:布尔必填、字符串 sort、强制入参标识
|
||
isRequired: Boolean(it?.isRequired),
|
||
sort: String(rest?.sort ?? (idx + 1)),
|
||
isInPara: true,
|
||
pId: rest?.pId ?? 0,
|
||
};
|
||
// 需要带回 _X_ROW_KEY(后端可能用来定位行)
|
||
payload._X_ROW_KEY = _X_ROW_KEY ?? `row_${idx + 1}`;
|
||
// id 未生成时不传,避免发送 undefined
|
||
if (!payload.id && payload.id !== 0) delete payload.id;
|
||
return payload;
|
||
});
|
||
const normalizedOut = normalizeList(outList, false).map((it: any, idx: number) => {
|
||
const { _X_ROW_CHILD, _X_ROW_KEY, children, ...rest } = it || {};
|
||
const payload: any = {
|
||
...rest,
|
||
isRequired: Boolean(it?.isRequired),
|
||
sort: String(rest?.sort ?? (idx + 1)),
|
||
isInPara: false,
|
||
pId: rest?.pId ?? 0,
|
||
};
|
||
payload._X_ROW_KEY = _X_ROW_KEY ?? `row_${idx + 1}`;
|
||
if (!payload.id && payload.id !== 0) delete payload.id;
|
||
return payload;
|
||
});
|
||
|
||
tableForm.inParameterList = normalizedIn;
|
||
tableForm.outParameterList = normalizedOut;
|
||
|
||
// 获取二次请求参数数据
|
||
const formParameterList = tableRef2.value?.getTableData().fullData || [];
|
||
|
||
// 参数过滤函数,name 和 value 都不能为空(更严格,避免只传 name)
|
||
function isValidParam(param: any) {
|
||
return param
|
||
&& param.name && String(param.name).trim() !== ''
|
||
&& param.value && String(param.value).trim() !== '';
|
||
}
|
||
const filteredInList = (tableForm.inParameterList || []).filter(isValidParam);
|
||
const filteredOutList = (tableForm.outParameterList || []).filter(isValidParam);
|
||
const filteredFormList = (formParameterList || []).filter(isValidParam);
|
||
|
||
const saveData: any = {
|
||
...formData,
|
||
serviceProviderId: serviceProviderId.value,
|
||
inParameterList: filteredInList,
|
||
outParameterList: filteredOutList,
|
||
formParameterList: filteredFormList,
|
||
};
|
||
// 规范化新增/编辑的标识字段
|
||
if (isEditMode.value) {
|
||
saveData.id = formData.id || tableForm.id; // 编辑时必须带id
|
||
saveData.optionType = 3; // 编辑
|
||
} else {
|
||
// 新增时,有的接口要求不传id/或传0;这里优先不传
|
||
delete saveData.id;
|
||
saveData.optionType = 1; // 新增
|
||
}
|
||
|
||
await postInterfaceSaveServiceProviderInterface(saveData);
|
||
$baseMessage('保存成功', 'success');
|
||
emit('saved');
|
||
emit('close');
|
||
return true; // 返回成功状态
|
||
} catch (error) {
|
||
$baseMessage('保存失败', 'error');
|
||
throw error; // 重新抛出错误
|
||
}
|
||
}
|
||
|
||
// 关闭弹窗
|
||
function closeModal() {
|
||
emit('close');
|
||
}
|
||
|
||
// 新增请求参数
|
||
async function addNewRequestParam() {
|
||
try {
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
pId: 0,
|
||
type: 1,
|
||
name: '',
|
||
cnName: '',
|
||
description: '',
|
||
isRequired: false,
|
||
};
|
||
|
||
await nextTick();
|
||
const { row: newRow } = await tableRef.value!.addRow(record);
|
||
await nextTick();
|
||
await tableRef.value?.editRowEvent(newRow);
|
||
} catch (error) {
|
||
console.error('新增参数失败', error);
|
||
$baseMessage('新增参数失败,请重试', 'error');
|
||
}
|
||
}
|
||
|
||
// 新增返回参数
|
||
async function addNewResponseParam() {
|
||
try {
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
pId: 0,
|
||
type: 1,
|
||
name: '',
|
||
cnName: '',
|
||
description: '',
|
||
isRequired: false,
|
||
};
|
||
|
||
await nextTick();
|
||
const { row: newRow } = await tableRef1.value!.addRow(record);
|
||
await nextTick();
|
||
await tableRef1.value?.editRowEvent(newRow);
|
||
} catch (error) {
|
||
console.error('新增参数失败', error);
|
||
$baseMessage('新增参数失败,请重试', 'error');
|
||
}
|
||
}
|
||
|
||
// 判断行是否处于编辑状态
|
||
function isRowEditing(row: any): boolean {
|
||
if (!row || !tableRef.value) return false;
|
||
try {
|
||
return tableRef.value.isEditByRow(row);
|
||
} catch (error) {
|
||
console.error('检查编辑状态失败', error);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 判断返回参数表格行是否处于编辑状态
|
||
function isRowEditing1(row: any): boolean {
|
||
if (!row || !tableRef1.value) return false;
|
||
try {
|
||
return tableRef1.value.isEditByRow(row);
|
||
} catch (error) {
|
||
console.error('检查编辑状态失败', error);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 编辑行
|
||
function editRow(row: any) {
|
||
tableRef.value?.editRowEvent(row);
|
||
}
|
||
|
||
// 保存行
|
||
function saveRow(row: any) {
|
||
tableRef.value?.saveRowEvent(row);
|
||
}
|
||
|
||
// 删除行
|
||
function deleteRow(row: any) {
|
||
tableRef.value?.removeRowEvent(row);
|
||
}
|
||
|
||
// 编辑返回参数行
|
||
function editRow1(row: any) {
|
||
tableRef1.value?.editRowEvent(row);
|
||
}
|
||
|
||
// 保存返回参数行
|
||
function saveRow1(row: any) {
|
||
tableRef1.value?.saveRowEvent(row);
|
||
}
|
||
|
||
// 删除返回参数行
|
||
function deleteRow1(row: any) {
|
||
tableRef1.value?.removeRowEvent(row);
|
||
}
|
||
|
||
// 获取参数类型名称
|
||
function getParameterTypeName(type: any) {
|
||
const paramType = ParameterTypeList.value.find(item => item.key === type);
|
||
return paramType ? paramType.value : type;
|
||
}
|
||
|
||
// 打开参数解析弹窗
|
||
function drawerClick() {
|
||
drawerVisible.value = true;
|
||
}
|
||
|
||
// 打开返回参数解析弹窗
|
||
function drawerClick1() {
|
||
drawerVisible1.value = true;
|
||
}
|
||
|
||
// 取消参数解析
|
||
function cancelClick() {
|
||
drawerVisible.value = false;
|
||
textareaJson.value = '';
|
||
textareaXml.value = '';
|
||
}
|
||
|
||
// 取消返回参数解析
|
||
function cancelClick1() {
|
||
drawerVisible1.value = false;
|
||
textareaJson1.value = '';
|
||
textareaXml1.value = '';
|
||
}
|
||
|
||
// 解析参数
|
||
async function JsonXmlClick() {
|
||
if (!textareaJson.value && !textareaXml.value) {
|
||
$baseMessage('请先输入要解析的内容', 'warning');
|
||
return;
|
||
}
|
||
|
||
analysisLoading.value = true;
|
||
try {
|
||
const content = tabs.value === 'Json' ? textareaJson.value : textareaXml.value;
|
||
const data = await postParameterParse({
|
||
parameterParseType: tabs.value === 'Json' ? 1 : 2,
|
||
parameterContent: content,
|
||
});
|
||
|
||
dataList.value = data;
|
||
$baseMessage('解析成功', 'success');
|
||
} catch (error) {
|
||
$baseMessage('解析失败', 'error');
|
||
} finally {
|
||
analysisLoading.value = false;
|
||
}
|
||
}
|
||
|
||
// 解析返回参数
|
||
async function JsonXmlClick1() {
|
||
if (!textareaJson1.value && !textareaXml1.value) {
|
||
$baseMessage('请先输入要解析的内容', 'warning');
|
||
return;
|
||
}
|
||
|
||
analysisLoading.value = true;
|
||
try {
|
||
const content = tabs1.value === 'Json' ? textareaJson1.value : textareaXml1.value;
|
||
const data = await postParameterParse({
|
||
parameterParseType: tabs1.value === 'Json' ? 1 : 2,
|
||
parameterContent: content,
|
||
});
|
||
|
||
dataList1.value = data;
|
||
$baseMessage('解析成功', 'success');
|
||
} catch (error) {
|
||
$baseMessage('解析失败', 'error');
|
||
} finally {
|
||
analysisLoading.value = false;
|
||
}
|
||
}
|
||
|
||
// 导入参数
|
||
async function importClick() {
|
||
if (!dataList.value) {
|
||
$baseMessage('导入失败,请先解析', 'error');
|
||
return;
|
||
}
|
||
|
||
importLoading.value = true;
|
||
try {
|
||
const rc: any[] = cloneDeep(dataList.value);
|
||
const arr: any[] = rc.map((i) => {
|
||
return {
|
||
...i,
|
||
cnName: '',
|
||
description: '',
|
||
optionType: 1,
|
||
alias: i?.alias || i?.name,
|
||
sort: `${i}`,
|
||
};
|
||
});
|
||
|
||
await postParameterValidateParameter(arr);
|
||
$baseMessage('导入成功', 'success');
|
||
|
||
dataList.value.sort((a: any, b: any) => a.id - b.id);
|
||
dataList.value.forEach((node: any) => {
|
||
tableRef.value?.addRowsAt(node, -1);
|
||
});
|
||
|
||
drawerVisible.value = false;
|
||
textareaJson.value = '';
|
||
textareaXml.value = '';
|
||
} catch (error) {
|
||
$baseMessage('导入失败', 'error');
|
||
} finally {
|
||
importLoading.value = false;
|
||
}
|
||
}
|
||
|
||
// 导入返回参数
|
||
async function importClick1() {
|
||
if (!dataList1.value) {
|
||
$baseMessage('导入失败,请先解析', 'error');
|
||
return;
|
||
}
|
||
|
||
importLoading.value = true;
|
||
try {
|
||
const rc: any[] = cloneDeep(dataList1.value);
|
||
const arr: any[] = rc.map((i) => {
|
||
return {
|
||
...i,
|
||
cnName: '',
|
||
description: '',
|
||
optionType: 0,
|
||
alias: i?.alias || i?.name,
|
||
sort: `${i}`,
|
||
};
|
||
});
|
||
|
||
await postParameterValidateParameter(arr);
|
||
$baseMessage('导入成功', 'success');
|
||
|
||
dataList1.value.sort((a: any, b: any) => a.id - b.id);
|
||
dataList1.value.forEach((node: any) => {
|
||
tableRef1.value?.addRowsAt(node, -1);
|
||
});
|
||
|
||
drawerVisible1.value = false;
|
||
textareaJson1.value = '';
|
||
textareaXml1.value = '';
|
||
} catch (error) {
|
||
$baseMessage('导入失败', 'error');
|
||
} finally {
|
||
importLoading.value = false;
|
||
}
|
||
}
|
||
|
||
// 添加子级行(请求参数)
|
||
async function addRow(currRow: any) {
|
||
// 如果当前行没有内容,则添加一个顶级行
|
||
if (!currRow.name) {
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
pId: 0,
|
||
type: 1,
|
||
name: '',
|
||
};
|
||
|
||
try {
|
||
const result = await tableRef.value?.addRow(record);
|
||
if (result && result.row) {
|
||
await nextTick();
|
||
await tableRef.value?.editRowEvent(result.row);
|
||
}
|
||
} catch (error) {
|
||
console.error('新增参数失败', error);
|
||
$baseMessage('新增参数失败,请重试', 'error');
|
||
}
|
||
return undefined;
|
||
}
|
||
|
||
// 如果当前行有内容,则添加子级行
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
pId: currRow.id,
|
||
type: 1,
|
||
name: '',
|
||
};
|
||
|
||
if (currRow.type === 8 || currRow.type === 9 || currRow.type === 11) {
|
||
$baseMessage('该参数类型不可新增下一级', 'error');
|
||
return undefined;
|
||
}
|
||
|
||
await tableRef.value?.addRowsAt(record, -1);
|
||
await tableRef.value?.setTreeExpand(currRow, true);
|
||
return undefined;
|
||
}
|
||
|
||
// 删除行(请求参数)
|
||
async function delRow(currRow: any) {
|
||
await tableRef.value?.removeRow(currRow);
|
||
if (!currRow.children) currRow.type.disabled = false;
|
||
return undefined;
|
||
}
|
||
|
||
// 添加子级行(返回参数)
|
||
async function addRow1(currRow: any) {
|
||
// 如果当前行没有内容,则添加一个顶级行
|
||
if (!currRow.name) {
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
pId: 0,
|
||
type: 1,
|
||
name: '',
|
||
};
|
||
|
||
try {
|
||
const result = await tableRef1.value?.addRow(record);
|
||
if (result && result.row) {
|
||
await nextTick();
|
||
await tableRef1.value?.editRowEvent(result.row);
|
||
}
|
||
} catch (error) {
|
||
console.error('新增参数失败', error);
|
||
$baseMessage('新增参数失败,请重试', 'error');
|
||
}
|
||
return undefined;
|
||
}
|
||
|
||
// 如果当前行有内容,则添加子级行
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
pId: currRow.id,
|
||
type: 1,
|
||
name: '',
|
||
};
|
||
|
||
if (currRow.type === 8 || currRow.type === 9 || currRow.type === 11) {
|
||
$baseMessage('该参数类型不可新增下一级', 'error');
|
||
return undefined;
|
||
}
|
||
|
||
await tableRef1.value?.addRowsAt(record, -1);
|
||
await tableRef1.value?.setTreeExpand(currRow, true);
|
||
return undefined;
|
||
}
|
||
|
||
// 删除行(返回参数)
|
||
async function delRow1(currRow: any) {
|
||
await tableRef1.value?.removeRow(currRow);
|
||
if (!currRow.children) currRow.type.disabled = false;
|
||
return undefined;
|
||
}
|
||
|
||
// 二次请求参数相关
|
||
const tableRef2 = ref();
|
||
const tableProps2 = reactive({
|
||
columns: [
|
||
{ field: 'name', title: '参数名', slots: { edit: 'name' } },
|
||
{ field: 'value', title: '参数值', slots: { edit: 'value' } },
|
||
{ field: 'description', title: '描述', slots: { edit: 'description' } },
|
||
{ field: 'action', title: '操作', width: 120, slots: { default: 'action' } },
|
||
],
|
||
editConfig: { trigger: 'click', mode: 'row' },
|
||
tableConfig: { data: [] },
|
||
showPager: false,
|
||
});
|
||
|
||
// 新增二次请求参数
|
||
async function addNewFormParam() {
|
||
try {
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
name: '',
|
||
value: '',
|
||
description: '',
|
||
};
|
||
|
||
await nextTick();
|
||
const { row: newRow } = await tableRef2.value!.addRow(record);
|
||
await nextTick();
|
||
await tableRef2.value?.editRowEvent(newRow);
|
||
} catch (error) {
|
||
console.error('新增二次请求参数失败', error);
|
||
$baseMessage('新增二次请求参数失败,请重试', 'error');
|
||
}
|
||
}
|
||
|
||
// 判断行是否在编辑状态(二次请求参数)
|
||
function isRowEditing2(row: any) {
|
||
return tableRef2.value?.isRowEditing(row) || false;
|
||
}
|
||
|
||
// 添加子级行(二次请求参数)
|
||
async function addRow2(currRow: any) {
|
||
const record = {
|
||
id: random(0, 2099999999),
|
||
name: '',
|
||
value: '',
|
||
description: '',
|
||
};
|
||
|
||
await tableRef2.value?.addRowsAt(record, -1);
|
||
return undefined;
|
||
}
|
||
|
||
// 删除行(二次请求参数)
|
||
async function delRow2(currRow: any) {
|
||
await tableRef2.value?.removeRow(currRow);
|
||
return undefined;
|
||
}
|
||
|
||
// 暴露方法给父组件
|
||
defineExpose({
|
||
init,
|
||
saveInterface,
|
||
closeModal,
|
||
});
|
||
|
||
onMounted(() => {
|
||
EnumValueInfoGetList();
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<div class="service-provider-interface-modal">
|
||
<!-- 基础信息 -->
|
||
<div class="section">
|
||
<div class="section-content">
|
||
<FormPro
|
||
ref="refSearchForm"
|
||
v-model="tableForm"
|
||
:button-config="{ showBtn: false }"
|
||
:default-span="6"
|
||
:row-gutter="8"
|
||
:form-layout="'inline'"
|
||
:item-list="serviceProviderFormItems"
|
||
:label-col-props="{
|
||
span: 6,
|
||
}"
|
||
:required-position="'none'"
|
||
:rules="serviceProviderFormRules"
|
||
:wrapper-col-props="{ span: 18 }"
|
||
size="small"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 请求参数 -->
|
||
<div class="section">
|
||
<div class="section-content">
|
||
<div class="table-header">
|
||
<span class="table-title">请求体</span>
|
||
<div class="table-toolbar">
|
||
<a-space :size="8">
|
||
<a-button status="success" @click="addNewRequestParam">
|
||
新增
|
||
</a-button>
|
||
<a-button status="warning" @click="drawerClick()"> 解析</a-button>
|
||
</a-space>
|
||
</div>
|
||
</div>
|
||
<TablePro
|
||
ref="tableRef"
|
||
v-bind="tableProps"
|
||
:tree-config="{
|
||
transform: true,
|
||
rowField: 'id',
|
||
parentField: 'pId',
|
||
lazy: false,
|
||
showIcon: true,
|
||
}"
|
||
:row-config="{ isHover: true }"
|
||
:mouse-config="{
|
||
area: false,
|
||
}"
|
||
class="request-params-table"
|
||
>
|
||
<!-- 表格模板插槽 -->
|
||
<template #asdsad="{ row }">
|
||
<div class="flex justify-center items-center">
|
||
<IconDragArrow style="font-size: 24px" />
|
||
</div>
|
||
</template>
|
||
|
||
<template #name="{ row }">
|
||
<template v-if="isRowEditing(row)">
|
||
<a-input
|
||
v-model="row.name"
|
||
allow-clear
|
||
placeholder="请输入参数名"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.name }}</span>
|
||
</template>
|
||
|
||
<template #cnName="{ row }">
|
||
<template v-if="isRowEditing(row)">
|
||
<a-input
|
||
v-model="row.cnName"
|
||
allow-clear
|
||
placeholder="请输入中文名称"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.cnName }}</span>
|
||
</template>
|
||
|
||
<template #type="{ row }">
|
||
<template v-if="isRowEditing(row)">
|
||
<a-select
|
||
v-model="row.type"
|
||
:disabled="!!row.children?.length"
|
||
placeholder="请选择类型"
|
||
>
|
||
<a-option
|
||
v-for="option in ParameterTypeList"
|
||
:key="option.key"
|
||
:value="option.key"
|
||
>
|
||
{{ option.value }}
|
||
</a-option>
|
||
</a-select>
|
||
</template>
|
||
<span v-else>{{ getParameterTypeName(row.type) }}</span>
|
||
</template>
|
||
|
||
<template #description="{ row }">
|
||
<template v-if="isRowEditing(row)">
|
||
<a-input
|
||
v-model="row.description"
|
||
allow-clear
|
||
placeholder="请输入描述"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.description }}</span>
|
||
</template>
|
||
|
||
<template #isRequired="{ row }">
|
||
<a-checkbox v-model="row.isRequired" />
|
||
</template>
|
||
|
||
<template #action="{ row }">
|
||
<a-space>
|
||
<a-button type="text" status="success" @click="addRow(row)">
|
||
<IconPlus />
|
||
</a-button>
|
||
<a-button type="text" status="danger" @click="delRow(row)">
|
||
<IconDelete />
|
||
</a-button>
|
||
</a-space>
|
||
</template>
|
||
</TablePro>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 返回参数 -->
|
||
<div class="section">
|
||
<div class="section-content">
|
||
<div class="table-header">
|
||
<span class="table-title">返回体</span>
|
||
<div class="table-toolbar">
|
||
<a-space :size="8">
|
||
<a-button status="success" @click="addNewResponseParam">
|
||
新增
|
||
</a-button>
|
||
<a-button status="warning" @click="drawerClick1()"> 解析</a-button>
|
||
</a-space>
|
||
</div>
|
||
</div>
|
||
<TablePro
|
||
ref="tableRef1"
|
||
v-bind="tableProps1"
|
||
:tree-config="{
|
||
transform: true,
|
||
rowField: 'id',
|
||
parentField: 'pId',
|
||
lazy: false,
|
||
showIcon: true,
|
||
}"
|
||
:row-config="{ isHover: true }"
|
||
:mouse-config="{
|
||
area: false,
|
||
}"
|
||
class="response-params-table"
|
||
>
|
||
<!-- 返回参数表格模板插槽 -->
|
||
<template #asdsad>
|
||
<div class="flex justify-center items-center">
|
||
<IconDragArrow style="font-size: 24px" />
|
||
</div>
|
||
</template>
|
||
|
||
<template #name="{ row }">
|
||
<template v-if="isRowEditing1(row)">
|
||
<a-input
|
||
v-model="row.name"
|
||
allow-clear
|
||
placeholder="请输入参数名"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.name }}</span>
|
||
</template>
|
||
|
||
<template #cnName="{ row }">
|
||
<template v-if="isRowEditing1(row)">
|
||
<a-input
|
||
v-model="row.cnName"
|
||
allow-clear
|
||
placeholder="请输入中文名称"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.cnName }}</span>
|
||
</template>
|
||
|
||
<template #type="{ row }">
|
||
<template v-if="isRowEditing1(row)">
|
||
<a-select
|
||
v-model="row.type"
|
||
:disabled="!!row.children?.length"
|
||
placeholder="请选择类型"
|
||
>
|
||
<a-option
|
||
v-for="option in ParameterTypeList"
|
||
:key="option.key"
|
||
:value="option.key"
|
||
>
|
||
{{ option.value }}
|
||
</a-option>
|
||
</a-select>
|
||
</template>
|
||
<span v-else>{{ getParameterTypeName(row.type) }}</span>
|
||
</template>
|
||
|
||
<template #description="{ row }">
|
||
<template v-if="isRowEditing1(row)">
|
||
<a-input
|
||
v-model="row.description"
|
||
allow-clear
|
||
placeholder="请输入描述"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.description }}</span>
|
||
</template>
|
||
|
||
<template #isRequired="{ row }">
|
||
<a-checkbox v-model="row.isRequired" />
|
||
</template>
|
||
|
||
<template #action="{ row }">
|
||
<a-space>
|
||
<a-button type="text" status="success" @click="addRow1(row)">
|
||
<IconPlus />
|
||
</a-button>
|
||
<a-button type="text" status="danger" @click="delRow1(row)">
|
||
<IconDelete />
|
||
</a-button>
|
||
</a-space>
|
||
</template>
|
||
</TablePro>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 二次请求参数 -->
|
||
<div class="section">
|
||
<div class="section-content">
|
||
<div class="table-header">
|
||
<span class="table-title">二次请求参数</span>
|
||
<div class="table-toolbar">
|
||
<a-space :size="8">
|
||
<a-button status="success" @click="addNewFormParam">
|
||
新增
|
||
</a-button>
|
||
</a-space>
|
||
</div>
|
||
</div>
|
||
<TablePro
|
||
ref="tableRef2"
|
||
v-bind="tableProps2"
|
||
:row-config="{ isHover: true }"
|
||
:mouse-config="{
|
||
area: false,
|
||
}"
|
||
:use-form="false"
|
||
class="form-params-table"
|
||
>
|
||
<template #name="{ row }">
|
||
<template v-if="isRowEditing2(row)">
|
||
<a-input
|
||
v-model="row.name"
|
||
allow-clear
|
||
placeholder="请输入参数名"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.name }}</span>
|
||
</template>
|
||
|
||
<template #value="{ row }">
|
||
<template v-if="isRowEditing2(row)">
|
||
<a-input
|
||
v-model="row.value"
|
||
allow-clear
|
||
placeholder="请输入参数值"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.value }}</span>
|
||
</template>
|
||
|
||
<template #description="{ row }">
|
||
<template v-if="isRowEditing2(row)">
|
||
<a-input
|
||
v-model="row.description"
|
||
allow-clear
|
||
placeholder="请输入描述"
|
||
/>
|
||
</template>
|
||
<span v-else>{{ row.description }}</span>
|
||
</template>
|
||
|
||
<template #action="{ row }">
|
||
<a-space>
|
||
<a-button type="text" status="success" @click="addRow2(row)">
|
||
<IconPlus />
|
||
</a-button>
|
||
<a-button type="text" status="danger" @click="delRow2(row)">
|
||
<IconDelete />
|
||
</a-button>
|
||
</a-space>
|
||
</template>
|
||
</TablePro>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 参数解析弹窗 -->
|
||
<a-drawer
|
||
v-model:visible="drawerVisible"
|
||
:width="500"
|
||
title="参数解析"
|
||
class="analysis-drawer"
|
||
:footer="true"
|
||
>
|
||
<div class="drawer-content-wrapper">
|
||
<div class="drawer-tabs-container">
|
||
<a-tabs v-model="tabs" class="drawer-tabs">
|
||
<a-tab-pane key="Json" title="Json" />
|
||
<a-tab-pane key="Xml" title="Xml" />
|
||
</a-tabs>
|
||
</div>
|
||
|
||
<div class="drawer-textarea-container">
|
||
<div v-if="tabs === 'Json'" class="textarea-wrapper">
|
||
<a-textarea
|
||
v-model="textareaJson"
|
||
type="textarea"
|
||
placeholder="请输入JSON格式数据"
|
||
resize="none"
|
||
height="100%"
|
||
/>
|
||
</div>
|
||
<div v-else class="textarea-wrapper">
|
||
<a-textarea
|
||
v-model="textareaXml"
|
||
type="textarea"
|
||
placeholder="请输入XML格式数据"
|
||
resize="none"
|
||
height="100%"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<template #footer>
|
||
<div class="drawer-footer">
|
||
<a-button @click="cancelClick">取消</a-button>
|
||
<a-button
|
||
type="primary"
|
||
:loading="analysisLoading"
|
||
class="ml-12px"
|
||
@click="JsonXmlClick"
|
||
>
|
||
解析
|
||
</a-button>
|
||
<a-button
|
||
type="primary"
|
||
:loading="importLoading"
|
||
class="ml-12px"
|
||
@click="importClick"
|
||
>
|
||
导入
|
||
</a-button>
|
||
</div>
|
||
</template>
|
||
</a-drawer>
|
||
|
||
<!-- 返回参数解析弹窗 -->
|
||
<a-drawer
|
||
v-model:visible="drawerVisible1"
|
||
:width="500"
|
||
title="参数解析"
|
||
class="analysis-drawer"
|
||
:footer="true"
|
||
>
|
||
<div class="drawer-content-wrapper">
|
||
<div class="drawer-tabs-container">
|
||
<a-tabs v-model="tabs1" class="drawer-tabs">
|
||
<a-tab-pane key="Json" title="Json" />
|
||
<a-tab-pane key="Xml" title="Xml" />
|
||
</a-tabs>
|
||
</div>
|
||
|
||
<div class="drawer-textarea-container">
|
||
<div v-if="tabs1 === 'Json'" class="textarea-wrapper">
|
||
<a-textarea
|
||
v-model="textareaJson1"
|
||
type="textarea"
|
||
placeholder="请输入JSON格式数据"
|
||
resize="none"
|
||
height="100%"
|
||
/>
|
||
</div>
|
||
<div v-else class="textarea-wrapper">
|
||
<a-textarea
|
||
v-model="textareaXml1"
|
||
type="textarea"
|
||
placeholder="请输入XML格式数据"
|
||
resize="none"
|
||
height="100%"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<template #footer>
|
||
<div class="drawer-footer">
|
||
<a-button @click="cancelClick1">取消</a-button>
|
||
<a-button
|
||
type="primary"
|
||
:loading="analysisLoading"
|
||
class="ml-12px"
|
||
@click="JsonXmlClick1"
|
||
>
|
||
解析
|
||
</a-button>
|
||
<a-button
|
||
type="primary"
|
||
:loading="importLoading"
|
||
class="ml-12px"
|
||
@click="importClick1"
|
||
>
|
||
导入
|
||
</a-button>
|
||
</div>
|
||
</template>
|
||
</a-drawer>
|
||
</div>
|
||
</template>
|
||
|
||
<style lang="less" scoped>
|
||
.service-provider-interface-modal {
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: var(--color-fill-2);
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
padding: 12px;
|
||
}
|
||
|
||
.section {
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
margin-bottom: 16px;
|
||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.section-content {
|
||
padding: 20px;
|
||
}
|
||
|
||
.table-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 4px;
|
||
padding-bottom: 4px;
|
||
border-bottom: 1px solid #e5e6eb;
|
||
}
|
||
|
||
.table-title {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #8c8c8c;
|
||
}
|
||
|
||
.table-toolbar {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.action-footer {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 24px 0;
|
||
margin-top: 24px;
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||
position: sticky;
|
||
bottom: 20px;
|
||
z-index: 10;
|
||
}
|
||
|
||
.mr-10px {
|
||
margin-right: 12px;
|
||
}
|
||
|
||
.ml-12px {
|
||
margin-left: 12px;
|
||
}
|
||
|
||
.analysis-drawer {
|
||
:deep(.arco-drawer-body) {
|
||
padding: 0;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
:deep(.arco-drawer-footer) {
|
||
border-top: 1px solid #e5e6eb;
|
||
padding: 16px 24px;
|
||
background-color: #fff;
|
||
min-height: 68px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
:deep(.arco-drawer-header) {
|
||
border-bottom: 1px solid #e5e6eb;
|
||
padding: 16px 24px;
|
||
min-height: 56px;
|
||
flex-shrink: 0;
|
||
}
|
||
}
|
||
|
||
.drawer-content-wrapper {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.drawer-tabs-container {
|
||
flex-shrink: 0;
|
||
border-bottom: 1px solid #e5e6eb;
|
||
}
|
||
|
||
.drawer-tabs {
|
||
:deep(.arco-tabs-content) {
|
||
display: none;
|
||
}
|
||
}
|
||
|
||
.drawer-textarea-container {
|
||
flex: 1;
|
||
padding: 16px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.textarea-wrapper {
|
||
height: 100%;
|
||
}
|
||
|
||
.drawer-footer {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
}
|
||
|
||
:deep(.arco-form-item) {
|
||
margin-bottom: 20px;
|
||
.arco-input {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.arco-select-view-value {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.arco-select-view-single.arco-select-view-size-medium .arco-select-view-input {
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
/* 强制移除输入框左侧的必填星号及预留空位(仅作用于此弹窗作用域) */
|
||
:deep(.arco-form-item-label-col) {
|
||
.arco-form-item-label-required,
|
||
.arco-form-item-label-asterisk,
|
||
.arco-form-item-label-required-symbol {
|
||
display: none !important;
|
||
}
|
||
/* 去除为星号预留的空白 */
|
||
.arco-form-item-label {
|
||
padding-left: 0 !important;
|
||
}
|
||
}
|
||
|
||
:deep(.arco-form-item-label-col) {
|
||
font-weight: 500;
|
||
}
|
||
|
||
:deep(.arco-btn) {
|
||
height: 36px;
|
||
padding: 0 16px;
|
||
font-weight: 500;
|
||
font-size: 14px;
|
||
|
||
&.arco-btn-primary {
|
||
background-color: #1684fc;
|
||
|
||
&:hover {
|
||
background-color: #0e76e6;
|
||
}
|
||
}
|
||
|
||
&.arco-btn-text {
|
||
padding: 0 8px;
|
||
}
|
||
}
|
||
|
||
:deep(.vxe-table) {
|
||
.vxe-table--header {
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
.vxe-table--body {
|
||
.vxe-body--row {
|
||
&:hover {
|
||
background-color: #f0f9ff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|