feat: 服务商公共参数配置并回落到接口明细
All checks were successful
Build and Deploy Front / deploy (push) Successful in 6m38s
All checks were successful
Build and Deploy Front / deploy (push) Successful in 6m38s
新增服务商级公共参数入口与弹窗,按位置只读落入 Query/Header/Body,并完善授权入参与调试页按钮样式。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
a0fea7d001
commit
a5ef7e542d
@ -1955,7 +1955,6 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
size="small"
|
size="small"
|
||||||
type="primary"
|
|
||||||
:loading="isLoading"
|
:loading="isLoading"
|
||||||
:disabled="isLoading"
|
:disabled="isLoading"
|
||||||
@click="sendRequest"
|
@click="sendRequest"
|
||||||
|
|||||||
@ -416,7 +416,7 @@
|
|||||||
>
|
>
|
||||||
<a-dropdown
|
<a-dropdown
|
||||||
trigger="click"
|
trigger="click"
|
||||||
:popup-max-height="250"
|
:popup-max-height="false"
|
||||||
@select="handleActionSelect"
|
@select="handleActionSelect"
|
||||||
>
|
>
|
||||||
<a-button
|
<a-button
|
||||||
@ -460,7 +460,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<a-dropdown
|
<a-dropdown
|
||||||
trigger="click"
|
trigger="click"
|
||||||
:popup-max-height="250"
|
:popup-max-height="false"
|
||||||
@select="handleActionSelect"
|
@select="handleActionSelect"
|
||||||
>
|
>
|
||||||
<a-button
|
<a-button
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
buildSmartFillResult,
|
buildSmartFillResult,
|
||||||
} from '@/utils/curlToInterfaceFill';
|
} from '@/utils/curlToInterfaceFill';
|
||||||
import { useTabRowCounts } from '@/utils/useTabRowCounts';
|
import { useTabRowCounts } from '@/utils/useTabRowCounts';
|
||||||
import { FormKvPlaceholderOptions, ParameterType } from '@/constants/itfxEnums';
|
import { FormKvPlaceholderOptions, ParameterType, FieldPosition } from '@/constants/itfxEnums';
|
||||||
import {
|
import {
|
||||||
flattenTreeTableRows,
|
flattenTreeTableRows,
|
||||||
getTreeTableFlatRows,
|
getTreeTableFlatRows,
|
||||||
@ -440,6 +440,7 @@
|
|||||||
function validateKvParamRows(rows: any[], label: string): string | null {
|
function validateKvParamRows(rows: any[], label: string): string | null {
|
||||||
const seen = new Set<string>();
|
const seen = new Set<string>();
|
||||||
for (const row of rows || []) {
|
for (const row of rows || []) {
|
||||||
|
if (isCommonParamRow(row)) continue;
|
||||||
const name = String(row?.name ?? '').trim();
|
const name = String(row?.name ?? '').trim();
|
||||||
if (!name) return `${label} 存在未填写参数名的行,请补全或删除空行`;
|
if (!name) return `${label} 存在未填写参数名的行,请补全或删除空行`;
|
||||||
const key = name.toLowerCase();
|
const key = name.toLowerCase();
|
||||||
@ -583,6 +584,138 @@
|
|||||||
() => props.showQuery && !isDownstreamMode.value,
|
() => props.showQuery && !isDownstreamMode.value,
|
||||||
);
|
);
|
||||||
const showHeaderTab = computed(() => isDownstreamMode.value && props.showQuery);
|
const showHeaderTab = computed(() => isDownstreamMode.value && props.showQuery);
|
||||||
|
|
||||||
|
/** 下游:服务商公共参数按位置回落到 Query/Header/Body(只读置灰) */
|
||||||
|
const inheritedCommonParams = ref<any[]>([]);
|
||||||
|
const inheritedCommonParamsLoading = ref(false);
|
||||||
|
|
||||||
|
function normalizePositionList(row: any): number[] {
|
||||||
|
const list = row?.fieldPositionList;
|
||||||
|
if (Array.isArray(list) && list.length) {
|
||||||
|
return list.map((x: any) => Number(x)).filter((n: number) => Number.isFinite(n));
|
||||||
|
}
|
||||||
|
const fp = row?.fieldPositions;
|
||||||
|
if (typeof fp === 'string' && fp.trim()) {
|
||||||
|
return fp
|
||||||
|
.split(',')
|
||||||
|
.map((x) => Number(x.trim()))
|
||||||
|
.filter((n) => Number.isFinite(n));
|
||||||
|
}
|
||||||
|
if (Array.isArray(fp)) {
|
||||||
|
return fp.map((x: any) => Number(x)).filter((n: number) => Number.isFinite(n));
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function commonParamsForPosition(position: number) {
|
||||||
|
return inheritedCommonParams.value.filter((row) =>
|
||||||
|
normalizePositionList(row).includes(position),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const inheritedQueryParams = computed(() =>
|
||||||
|
isDownstreamMode.value ? commonParamsForPosition(FieldPosition.Query) : [],
|
||||||
|
);
|
||||||
|
const inheritedHeaderParams = computed(() =>
|
||||||
|
isDownstreamMode.value ? commonParamsForPosition(FieldPosition.Header) : [],
|
||||||
|
);
|
||||||
|
const inheritedBodyParams = computed(() =>
|
||||||
|
isDownstreamMode.value ? commonParamsForPosition(FieldPosition.Body) : [],
|
||||||
|
);
|
||||||
|
|
||||||
|
function isCommonParamRow(row: any) {
|
||||||
|
return !!row?.__fromCommonParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripCommonRows<T extends Record<string, any>>(rows: T[] | undefined | null): T[] {
|
||||||
|
return (Array.isArray(rows) ? rows : []).filter((r) => !isCommonParamRow(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterCommonFromActionRows(actions: any) {
|
||||||
|
const filterRows = (arr: any[]) =>
|
||||||
|
(Array.isArray(arr) ? arr : []).filter((r) => !isCommonParamRow(r));
|
||||||
|
return {
|
||||||
|
insertRecords: filterRows(actions?.insertRecords),
|
||||||
|
removeRecords: filterRows(actions?.removeRecords),
|
||||||
|
updateRecords: filterRows(actions?.updateRecords),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function toCommonKvRows(list: any[]) {
|
||||||
|
return (list || []).map((row, idx) => ({
|
||||||
|
__fromCommonParams: true,
|
||||||
|
disableEdit: true,
|
||||||
|
id: `common-kv-${row.id ?? idx}`,
|
||||||
|
name: row.fieldName || '',
|
||||||
|
value: row.fieldValue || '',
|
||||||
|
description: row.description || '公共参数',
|
||||||
|
__commonParamId: row.id,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeCommonKvRows(ownRows: any[] | undefined, commonList: any[]) {
|
||||||
|
return [...toCommonKvRows(commonList), ...stripCommonRows(ownRows)];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyKvTableWithCommon(
|
||||||
|
tableProps: { data: any[] },
|
||||||
|
tableRef: { value?: { reloadData?: (rows: any[]) => any } },
|
||||||
|
ownRows: any[] | undefined,
|
||||||
|
commonList: any[],
|
||||||
|
) {
|
||||||
|
const next = mergeCommonKvRows(ownRows, commonList);
|
||||||
|
tableProps.data = next;
|
||||||
|
await nextTick();
|
||||||
|
tableRef.value?.reloadData?.(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function remergeInheritedCommonIntoKvTables() {
|
||||||
|
if (!isDownstreamMode.value) return;
|
||||||
|
await applyKvTableWithCommon(
|
||||||
|
queryTableProps,
|
||||||
|
queryTableRef,
|
||||||
|
stripCommonRows(queryTableProps.data),
|
||||||
|
inheritedQueryParams.value,
|
||||||
|
);
|
||||||
|
if (showHeaderTab.value) {
|
||||||
|
await applyKvTableWithCommon(
|
||||||
|
headerTableProps,
|
||||||
|
headerTableRef,
|
||||||
|
stripCommonRows(headerTableProps.data),
|
||||||
|
inheritedHeaderParams.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await applyKvTableWithCommon(
|
||||||
|
bodyFormTableProps,
|
||||||
|
bodyFormTableRef,
|
||||||
|
stripCommonRows(bodyFormTableProps.data),
|
||||||
|
inheritedBodyParams.value,
|
||||||
|
);
|
||||||
|
refreshTabCounts();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshInheritedCommonParams() {
|
||||||
|
const spId = Number(props.serviceProviderId);
|
||||||
|
if (!isDownstreamMode.value || !Number.isFinite(spId) || spId <= 0) {
|
||||||
|
inheritedCommonParams.value = [];
|
||||||
|
await remergeInheritedCommonIntoKvTables();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inheritedCommonParamsLoading.value = true;
|
||||||
|
try {
|
||||||
|
const res: any = await getFixedParameterGetFixedParameterList({
|
||||||
|
serviceProviderId: spId,
|
||||||
|
});
|
||||||
|
const data = res?.data || res || [];
|
||||||
|
inheritedCommonParams.value = Array.isArray(data) ? data : [];
|
||||||
|
} catch {
|
||||||
|
inheritedCommonParams.value = [];
|
||||||
|
} finally {
|
||||||
|
inheritedCommonParamsLoading.value = false;
|
||||||
|
}
|
||||||
|
await remergeInheritedCommonIntoKvTables();
|
||||||
|
}
|
||||||
|
|
||||||
const isNoneBodyContentType = computed(
|
const isNoneBodyContentType = computed(
|
||||||
() => isDownstreamMode.value && isNoneContentType(props.basicFormData?.contentType),
|
() => isDownstreamMode.value && isNoneContentType(props.basicFormData?.contentType),
|
||||||
);
|
);
|
||||||
@ -992,7 +1125,9 @@
|
|||||||
mode: 'row',
|
mode: 'row',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
autoClear: false,
|
autoClear: false,
|
||||||
|
beforeEditMethod: ({ row }: { row: any }) => !isCommonParamRow(row),
|
||||||
},
|
},
|
||||||
|
rowClassName: ({ row }: { row: any }) => (isCommonParamRow(row) ? 'row-common-param' : ''),
|
||||||
},
|
},
|
||||||
showIndex: false,
|
showIndex: false,
|
||||||
data: [] as any[],
|
data: [] as any[],
|
||||||
@ -1017,6 +1152,14 @@
|
|||||||
data: [] as any[],
|
data: [] as any[],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [props.serviceProviderId, props.parameterMode] as const,
|
||||||
|
() => {
|
||||||
|
refreshInheritedCommonParams();
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
// Query 固定配置表格(不传 height,随内容自然增高,与 Query 列表的固定高度区分)
|
// Query 固定配置表格(不传 height,随内容自然增高,与 Query 列表的固定高度区分)
|
||||||
const queryFixedTableProps = computed(() => ({
|
const queryFixedTableProps = computed(() => ({
|
||||||
columns: [
|
columns: [
|
||||||
@ -1327,11 +1470,17 @@
|
|||||||
|
|
||||||
const canClearCurrentRequestTab = computed(() => {
|
const canClearCurrentRequestTab = computed(() => {
|
||||||
if (!showRequestTabClearAction.value) return false;
|
if (!showRequestTabClearAction.value) return false;
|
||||||
if (requestTab.value === 'query') return queryTabCount.value > 0;
|
if (requestTab.value === 'query') {
|
||||||
if (requestTab.value === 'header') return headerTabCount.value > 0;
|
return stripCommonRows(getTableFullData(queryTableRef, queryTableProps.data)).length > 0;
|
||||||
|
}
|
||||||
|
if (requestTab.value === 'header') {
|
||||||
|
return stripCommonRows(getTableFullData(headerTableRef, headerTableProps.data)).length > 0;
|
||||||
|
}
|
||||||
if (requestTab.value === 'fixed') return fixedConfigTabCount.value > 0;
|
if (requestTab.value === 'fixed') return fixedConfigTabCount.value > 0;
|
||||||
if (requestTab.value === 'body') {
|
if (requestTab.value === 'body') {
|
||||||
if (isBodyKvMode.value) return !isBodyKvEmpty.value;
|
if (isBodyKvMode.value) {
|
||||||
|
return stripCommonRows(getTableFullData(bodyFormTableRef, bodyFormTableProps.data)).length > 0;
|
||||||
|
}
|
||||||
return !isBodyTreeEmpty.value;
|
return !isBodyTreeEmpty.value;
|
||||||
}
|
}
|
||||||
if (requestTab.value === 'mappingBody') return !isMappingBodyEmpty.value;
|
if (requestTab.value === 'mappingBody') return !isMappingBodyEmpty.value;
|
||||||
@ -1339,48 +1488,65 @@
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听 queryParams prop 变化,同步到表格数据
|
// 监听 queryParams prop 变化,同步到表格数据(并合并公共参数)
|
||||||
watch(
|
watch(
|
||||||
() => props.queryParams,
|
() => props.queryParams,
|
||||||
(newVal: any) => {
|
async (newVal: any) => {
|
||||||
if (newVal && Array.isArray(newVal)) {
|
if (!newVal || !Array.isArray(newVal)) return;
|
||||||
// 只在数据真正变化时才更新,避免循环
|
const own = stripCommonRows(newVal);
|
||||||
const currentData = queryTableProps.data || [];
|
const currentOwn = stripCommonRows(queryTableProps.data || []);
|
||||||
if (currentData.length !== newVal.length || JSON.stringify(currentData) !== JSON.stringify(newVal)) {
|
if (
|
||||||
queryTableProps.data = [...newVal] as any[];
|
currentOwn.length !== own.length
|
||||||
if (queryTableRef.value) {
|
|| JSON.stringify(currentOwn) !== JSON.stringify(own)
|
||||||
queryTableRef.value.reloadData([...newVal]);
|
) {
|
||||||
}
|
await applyKvTableWithCommon(
|
||||||
}
|
queryTableProps,
|
||||||
|
queryTableRef,
|
||||||
|
own,
|
||||||
|
inheritedQueryParams.value,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
function syncKvTableProps(
|
function syncKvTableProps(
|
||||||
propList: any[] | undefined,
|
propList: any[] | undefined,
|
||||||
tableProps: { data: any[] },
|
tableProps: { data: any[] },
|
||||||
tableRef: typeof queryTableRef,
|
tableRef: typeof queryTableRef,
|
||||||
|
commonList: any[],
|
||||||
) {
|
) {
|
||||||
if (!propList || !Array.isArray(propList)) return;
|
if (!propList || !Array.isArray(propList)) return;
|
||||||
const currentData = tableProps.data || [];
|
const own = stripCommonRows(propList);
|
||||||
|
const currentOwn = stripCommonRows(tableProps.data || []);
|
||||||
if (
|
if (
|
||||||
currentData.length !== propList.length
|
currentOwn.length !== own.length
|
||||||
|| JSON.stringify(currentData) !== JSON.stringify(propList)
|
|| JSON.stringify(currentOwn) !== JSON.stringify(own)
|
||||||
) {
|
) {
|
||||||
tableProps.data = [...propList] as any[];
|
applyKvTableWithCommon(tableProps, tableRef, own, commonList);
|
||||||
tableRef.value?.reloadData?.([...propList]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.headerParams,
|
() => props.headerParams,
|
||||||
(newVal) => syncKvTableProps(newVal as any[], headerTableProps, headerTableRef),
|
(newVal) =>
|
||||||
|
syncKvTableProps(
|
||||||
|
newVal as any[],
|
||||||
|
headerTableProps,
|
||||||
|
headerTableRef,
|
||||||
|
inheritedHeaderParams.value,
|
||||||
|
),
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
watch(
|
watch(
|
||||||
() => props.bodyFormParams,
|
() => props.bodyFormParams,
|
||||||
(newVal) => syncKvTableProps(newVal as any[], bodyFormTableProps, bodyFormTableRef),
|
(newVal) =>
|
||||||
|
syncKvTableProps(
|
||||||
|
newVal as any[],
|
||||||
|
bodyFormTableProps,
|
||||||
|
bodyFormTableRef,
|
||||||
|
inheritedBodyParams.value,
|
||||||
|
),
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
watch(
|
watch(
|
||||||
@ -1839,13 +2005,13 @@
|
|||||||
tableRef: any,
|
tableRef: any,
|
||||||
keepRow?: (row: any) => boolean,
|
keepRow?: (row: any) => boolean,
|
||||||
) {
|
) {
|
||||||
const roots = [...(getTableFullData(tableRef) || [])];
|
const roots = [...(getTableFullData(tableRef) || [])].filter((r) => !isCommonParamRow(r));
|
||||||
if (!keepRow) return roots;
|
if (!keepRow) return roots;
|
||||||
const toRemove: any[] = [];
|
const toRemove: any[] = [];
|
||||||
roots.forEach((row) => {
|
roots.forEach((row) => {
|
||||||
if (keepRow(row)) {
|
if (keepRow(row)) {
|
||||||
if (Array.isArray(row?.children) && row.children.length) {
|
if (Array.isArray(row?.children) && row.children.length) {
|
||||||
toRemove.push(...row.children);
|
toRemove.push(...row.children.filter((c: any) => !isCommonParamRow(c)));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1858,17 +2024,32 @@
|
|||||||
const tab = requestTab.value;
|
const tab = requestTab.value;
|
||||||
if (tab === 'query') {
|
if (tab === 'query') {
|
||||||
await removeTableRows(queryTableRef, collectRemovableTableRows(queryTableRef));
|
await removeTableRows(queryTableRef, collectRemovableTableRows(queryTableRef));
|
||||||
queryTableProps.data = [];
|
await applyKvTableWithCommon(
|
||||||
|
queryTableProps,
|
||||||
|
queryTableRef,
|
||||||
|
[],
|
||||||
|
inheritedQueryParams.value,
|
||||||
|
);
|
||||||
} else if (tab === 'header') {
|
} else if (tab === 'header') {
|
||||||
await removeTableRows(headerTableRef, collectRemovableTableRows(headerTableRef));
|
await removeTableRows(headerTableRef, collectRemovableTableRows(headerTableRef));
|
||||||
headerTableProps.data = [];
|
await applyKvTableWithCommon(
|
||||||
|
headerTableProps,
|
||||||
|
headerTableRef,
|
||||||
|
[],
|
||||||
|
inheritedHeaderParams.value,
|
||||||
|
);
|
||||||
} else if (tab === 'fixed') {
|
} else if (tab === 'fixed') {
|
||||||
await removeTableRows(queryFixedTableRef, collectRemovableTableRows(queryFixedTableRef));
|
await removeTableRows(queryFixedTableRef, collectRemovableTableRows(queryFixedTableRef));
|
||||||
fixedParams.value = [];
|
fixedParams.value = [];
|
||||||
fixedParamsHasChanges.value = true;
|
fixedParamsHasChanges.value = true;
|
||||||
} else if (tab === 'body' && isBodyKvMode.value) {
|
} else if (tab === 'body' && isBodyKvMode.value) {
|
||||||
await removeTableRows(bodyFormTableRef, collectRemovableTableRows(bodyFormTableRef));
|
await removeTableRows(bodyFormTableRef, collectRemovableTableRows(bodyFormTableRef));
|
||||||
bodyFormTableProps.data = [];
|
await applyKvTableWithCommon(
|
||||||
|
bodyFormTableProps,
|
||||||
|
bodyFormTableRef,
|
||||||
|
[],
|
||||||
|
inheritedBodyParams.value,
|
||||||
|
);
|
||||||
} else if (tab === 'body' && !isNoneBodyContentType.value) {
|
} else if (tab === 'body' && !isNoneBodyContentType.value) {
|
||||||
if (hoistedBodyArrayWrapper.value) {
|
if (hoistedBodyArrayWrapper.value) {
|
||||||
const persisted = getRequestBodyFlatParams();
|
const persisted = getRequestBodyFlatParams();
|
||||||
@ -1941,6 +2122,7 @@
|
|||||||
|
|
||||||
// 删除 Query 参数行
|
// 删除 Query 参数行
|
||||||
async function deleteQueryRow(row: any) {
|
async function deleteQueryRow(row: any) {
|
||||||
|
if (isCommonParamRow(row)) return;
|
||||||
markDirty();
|
markDirty();
|
||||||
await queryTableRef.value?.removeRow(row);
|
await queryTableRef.value?.removeRow(row);
|
||||||
refreshTabCounts();
|
refreshTabCounts();
|
||||||
@ -1955,6 +2137,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deleteHeaderRow(row: any) {
|
async function deleteHeaderRow(row: any) {
|
||||||
|
if (isCommonParamRow(row)) return;
|
||||||
markDirty();
|
markDirty();
|
||||||
await headerTableRef.value?.removeRow(row);
|
await headerTableRef.value?.removeRow(row);
|
||||||
refreshTabCounts();
|
refreshTabCounts();
|
||||||
@ -1969,6 +2152,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deleteBodyFormRow(row: any) {
|
async function deleteBodyFormRow(row: any) {
|
||||||
|
if (isCommonParamRow(row)) return;
|
||||||
markDirty();
|
markDirty();
|
||||||
await bodyFormTableRef.value?.removeRow(row);
|
await bodyFormTableRef.value?.removeRow(row);
|
||||||
refreshTabCounts();
|
refreshTabCounts();
|
||||||
@ -2922,10 +3106,9 @@
|
|||||||
tableProps: { data: any[] },
|
tableProps: { data: any[] },
|
||||||
tableRef: { value?: { reloadData?: (rows: any[]) => void } },
|
tableRef: { value?: { reloadData?: (rows: any[]) => void } },
|
||||||
rows: any[],
|
rows: any[],
|
||||||
|
commonList: any[] = [],
|
||||||
) {
|
) {
|
||||||
tableProps.data = rows;
|
await applyKvTableWithCommon(tableProps, tableRef, rows, commonList);
|
||||||
await nextTick();
|
|
||||||
tableRef.value?.reloadData?.(rows);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadFlatListIntoTreeTable(
|
async function loadFlatListIntoTreeTable(
|
||||||
@ -3022,11 +3205,26 @@
|
|||||||
await nextTick();
|
await nextTick();
|
||||||
refBasicForm.value?.setFormValue?.(nextBasic);
|
refBasicForm.value?.setFormValue?.(nextBasic);
|
||||||
|
|
||||||
await reloadKvTable(queryTableProps, queryTableRef, payload.queryParams);
|
await reloadKvTable(
|
||||||
|
queryTableProps,
|
||||||
|
queryTableRef,
|
||||||
|
payload.queryParams,
|
||||||
|
inheritedQueryParams.value,
|
||||||
|
);
|
||||||
|
|
||||||
if (isDownstreamMode.value) {
|
if (isDownstreamMode.value) {
|
||||||
await reloadKvTable(headerTableProps, headerTableRef, payload.headerParams ?? []);
|
await reloadKvTable(
|
||||||
await reloadKvTable(bodyFormTableProps, bodyFormTableRef, isForm ? payload.bodyFormParams : []);
|
headerTableProps,
|
||||||
|
headerTableRef,
|
||||||
|
payload.headerParams ?? [],
|
||||||
|
inheritedHeaderParams.value,
|
||||||
|
);
|
||||||
|
await reloadKvTable(
|
||||||
|
bodyFormTableProps,
|
||||||
|
bodyFormTableRef,
|
||||||
|
isForm ? payload.bodyFormParams : [],
|
||||||
|
inheritedBodyParams.value,
|
||||||
|
);
|
||||||
if (!isForm && !isNone) {
|
if (!isForm && !isNone) {
|
||||||
mappingBodyTableProps.data = [];
|
mappingBodyTableProps.data = [];
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@ -3197,20 +3395,27 @@
|
|||||||
validateDetailParamsBeforeSave,
|
validateDetailParamsBeforeSave,
|
||||||
captureDirtyBaseline,
|
captureDirtyBaseline,
|
||||||
markDirty,
|
markDirty,
|
||||||
|
refreshInheritedCommonParams,
|
||||||
isDirty: () => isDirty.value,
|
isDirty: () => isDirty.value,
|
||||||
getSaveSnapshot: (): InterfaceDetailSnapshot => ({
|
getSaveSnapshot: (): InterfaceDetailSnapshot => ({
|
||||||
queryParams: queryTableRef.value?.getTableData?.()?.fullData
|
queryParams: stripCommonRows(
|
||||||
|
queryTableRef.value?.getTableData?.()?.fullData
|
||||||
|| queryTableRef.value?.xGrid?.getTableData()?.fullData
|
|| queryTableRef.value?.xGrid?.getTableData()?.fullData
|
||||||
|| queryTableProps.data
|
|| queryTableProps.data
|
||||||
|| [],
|
|| [],
|
||||||
headerParams: headerTableRef.value?.getTableData?.()?.fullData
|
),
|
||||||
|
headerParams: stripCommonRows(
|
||||||
|
headerTableRef.value?.getTableData?.()?.fullData
|
||||||
|| headerTableRef.value?.xGrid?.getTableData()?.fullData
|
|| headerTableRef.value?.xGrid?.getTableData()?.fullData
|
||||||
|| headerTableProps.data
|
|| headerTableProps.data
|
||||||
|| [],
|
|| [],
|
||||||
bodyFormParams: bodyFormTableRef.value?.getTableData?.()?.fullData
|
),
|
||||||
|
bodyFormParams: stripCommonRows(
|
||||||
|
bodyFormTableRef.value?.getTableData?.()?.fullData
|
||||||
|| bodyFormTableRef.value?.xGrid?.getTableData()?.fullData
|
|| bodyFormTableRef.value?.xGrid?.getTableData()?.fullData
|
||||||
|| bodyFormTableProps.data
|
|| bodyFormTableProps.data
|
||||||
|| [],
|
|| [],
|
||||||
|
),
|
||||||
requestParams: getRequestBodyFlatParams(),
|
requestParams: getRequestBodyFlatParams(),
|
||||||
mappingBodyParams: getTreeTableFlatRows(
|
mappingBodyParams: getTreeTableFlatRows(
|
||||||
mappingBodyTableRef.value?.getTableData?.()?.fullData
|
mappingBodyTableRef.value?.getTableData?.()?.fullData
|
||||||
@ -3221,9 +3426,9 @@
|
|||||||
|| responseTableRef.value?.xGrid?.getTableData()?.fullData
|
|| responseTableRef.value?.xGrid?.getTableData()?.fullData
|
||||||
|| responseTableProps.data
|
|| responseTableProps.data
|
||||||
|| [],
|
|| [],
|
||||||
queryActionRows: queryTableRef.value?.getActionRows?.() || { insertRecords: [], removeRecords: [], updateRecords: [] },
|
queryActionRows: filterCommonFromActionRows(queryTableRef.value?.getActionRows?.()),
|
||||||
headerActionRows: headerTableRef.value?.getActionRows?.() || { insertRecords: [], removeRecords: [], updateRecords: [] },
|
headerActionRows: filterCommonFromActionRows(headerTableRef.value?.getActionRows?.()),
|
||||||
bodyFormActionRows: bodyFormTableRef.value?.getActionRows?.() || { insertRecords: [], removeRecords: [], updateRecords: [] },
|
bodyFormActionRows: filterCommonFromActionRows(bodyFormTableRef.value?.getActionRows?.()),
|
||||||
requestActionRows: stripBodyRootFromActionRows(
|
requestActionRows: stripBodyRootFromActionRows(
|
||||||
requestTableRef.value?.getActionRows?.() || {
|
requestTableRef.value?.getActionRows?.() || {
|
||||||
insertRecords: [],
|
insertRecords: [],
|
||||||
@ -3472,7 +3677,10 @@
|
|||||||
placeholder="请输入参数名"
|
placeholder="请输入参数名"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{ row.name || '-' }}</span>
|
<span v-else class="kv-name-cell">
|
||||||
|
{{ row.name || '-' }}
|
||||||
|
<span v-if="isCommonParamRow(row)" class="common-param-tag">公共</span>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #name_edit="{ row }">
|
<template #name_edit="{ row }">
|
||||||
@ -3540,13 +3748,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<a-space>
|
<a-space v-if="!isCommonParamRow(row)">
|
||||||
<a-popconfirm content="确定删除该参数?" @ok="deleteQueryRow(row)">
|
<a-popconfirm content="确定删除该参数?" @ok="deleteQueryRow(row)">
|
||||||
<a-button type="text" class="row-action-btn">
|
<a-button type="text" class="row-action-btn">
|
||||||
<IconDelete />
|
<IconDelete />
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
<span v-else class="common-param-action">—</span>
|
||||||
</template>
|
</template>
|
||||||
</TablePro>
|
</TablePro>
|
||||||
</div>
|
</div>
|
||||||
@ -3640,7 +3849,10 @@
|
|||||||
>
|
>
|
||||||
<template #name="{ row }">
|
<template #name="{ row }">
|
||||||
<a-input v-if="isHeaderRowEditing(row)" v-model="row.name" allow-clear placeholder="请输入参数名" />
|
<a-input v-if="isHeaderRowEditing(row)" v-model="row.name" allow-clear placeholder="请输入参数名" />
|
||||||
<span v-else>{{ row.name || '-' }}</span>
|
<span v-else class="kv-name-cell">
|
||||||
|
{{ row.name || '-' }}
|
||||||
|
<span v-if="isCommonParamRow(row)" class="common-param-tag">公共</span>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #name_edit="{ row }">
|
<template #name_edit="{ row }">
|
||||||
<a-input v-model="row.name" allow-clear placeholder="请输入参数名" />
|
<a-input v-model="row.name" allow-clear placeholder="请输入参数名" />
|
||||||
@ -3671,11 +3883,16 @@
|
|||||||
<a-input v-model="row.description" allow-clear placeholder="请输入描述" />
|
<a-input v-model="row.description" allow-clear placeholder="请输入描述" />
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<a-popconfirm content="确定删除该参数?" @ok="deleteHeaderRow(row)">
|
<a-popconfirm
|
||||||
|
v-if="!isCommonParamRow(row)"
|
||||||
|
content="确定删除该参数?"
|
||||||
|
@ok="deleteHeaderRow(row)"
|
||||||
|
>
|
||||||
<a-button type="text" class="row-action-btn">
|
<a-button type="text" class="row-action-btn">
|
||||||
<IconDelete />
|
<IconDelete />
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
|
<span v-else class="common-param-action">—</span>
|
||||||
</template>
|
</template>
|
||||||
</TablePro>
|
</TablePro>
|
||||||
</div>
|
</div>
|
||||||
@ -3687,7 +3904,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Body KV(FormUrlEncoded) -->
|
<!-- Body KV(FormUrlEncoded) -->
|
||||||
<div v-show="requestTab === 'body' && isBodyKvMode" class="table-content">
|
<div v-show="requestTab === 'body' && isBodyKvMode" class="table-content body-kv-pane">
|
||||||
<TablePro
|
<TablePro
|
||||||
ref="bodyFormTableRef"
|
ref="bodyFormTableRef"
|
||||||
v-bind="bodyFormTableProps"
|
v-bind="bodyFormTableProps"
|
||||||
@ -3696,7 +3913,10 @@
|
|||||||
>
|
>
|
||||||
<template #name="{ row }">
|
<template #name="{ row }">
|
||||||
<a-input v-if="isBodyFormRowEditing(row)" v-model="row.name" allow-clear placeholder="参数名" />
|
<a-input v-if="isBodyFormRowEditing(row)" v-model="row.name" allow-clear placeholder="参数名" />
|
||||||
<span v-else>{{ row.name || '-' }}</span>
|
<span v-else class="kv-name-cell">
|
||||||
|
{{ row.name || '-' }}
|
||||||
|
<span v-if="isCommonParamRow(row)" class="common-param-tag">公共</span>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #name_edit="{ row }">
|
<template #name_edit="{ row }">
|
||||||
<a-input v-model="row.name" allow-clear placeholder="参数名" />
|
<a-input v-model="row.name" allow-clear placeholder="参数名" />
|
||||||
@ -3727,11 +3947,16 @@
|
|||||||
<a-input v-model="row.description" allow-clear />
|
<a-input v-model="row.description" allow-clear />
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<a-popconfirm content="确定删除该参数?" @ok="deleteBodyFormRow(row)">
|
<a-popconfirm
|
||||||
|
v-if="!isCommonParamRow(row)"
|
||||||
|
content="确定删除该参数?"
|
||||||
|
@ok="deleteBodyFormRow(row)"
|
||||||
|
>
|
||||||
<a-button type="text" class="row-action-btn">
|
<a-button type="text" class="row-action-btn">
|
||||||
<IconDelete />
|
<IconDelete />
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
|
<span v-else class="common-param-action">—</span>
|
||||||
</template>
|
</template>
|
||||||
</TablePro>
|
</TablePro>
|
||||||
</div>
|
</div>
|
||||||
@ -4597,6 +4822,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kv-name-cell {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.common-param-tag {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0 5px;
|
||||||
|
height: 18px;
|
||||||
|
line-height: 18px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
background: var(--color-fill-2);
|
||||||
|
border: 1px solid var(--color-border-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.common-param-action {
|
||||||
|
color: var(--color-text-4);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.row-common-param) {
|
||||||
|
color: var(--color-text-3) !important;
|
||||||
|
background: var(--color-fill-1) !important;
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: var(--color-text-3) !important;
|
||||||
|
background: var(--color-fill-1) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-kv-pane {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 请求方式 + 请求地址 - 符合设计规范
|
// 请求方式 + 请求地址 - 符合设计规范
|
||||||
.api-test-header {
|
.api-test-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -2514,12 +2514,12 @@ export default {
|
|||||||
'system.serviceProviders.dropdown.authConfig': 'Auth config',
|
'system.serviceProviders.dropdown.authConfig': 'Auth config',
|
||||||
'system.serviceProviders.dropdown.accountManage': 'Account management',
|
'system.serviceProviders.dropdown.accountManage': 'Account management',
|
||||||
'system.serviceProviders.dropdown.export': 'Export',
|
'system.serviceProviders.dropdown.export': 'Export',
|
||||||
'system.serviceProviders.dropdown.fixedParams': 'Common parameters',
|
'system.serviceProviders.dropdown.fixedParams': 'Common params',
|
||||||
'system.serviceProviders.dropdown.delete': 'Delete',
|
'system.serviceProviders.dropdown.delete': 'Delete',
|
||||||
|
|
||||||
'system.serviceProviders.publish.title': 'Publish mapping cache · {name}',
|
'system.serviceProviders.publish.title': 'Publish mapping cache · {name}',
|
||||||
'system.serviceProviders.publish.tip': 'After auth/provider changes are saved, remapped system interfaces must be republished to refresh the live cache.',
|
'system.serviceProviders.publish.tip': 'After auth, common params, or provider changes are saved, remapped system interfaces must be republished to refresh the live cache.',
|
||||||
'system.serviceProviders.publish.confirmAfterSave': 'Saved. Check and publish mapping cache for this provider now?',
|
'system.serviceProviders.publish.confirmAfterSave': 'Saved. Common params / config take effect online only after publishing mapping cache. Check and publish now?',
|
||||||
'system.serviceProviders.publish.goPublish': 'Publish',
|
'system.serviceProviders.publish.goPublish': 'Publish',
|
||||||
'system.serviceProviders.publish.later': 'Later',
|
'system.serviceProviders.publish.later': 'Later',
|
||||||
'system.serviceProviders.publish.close': 'Close',
|
'system.serviceProviders.publish.close': 'Close',
|
||||||
|
|||||||
@ -2412,12 +2412,12 @@ export default {
|
|||||||
'system.serviceProviders.dropdown.authConfig': '授权配置',
|
'system.serviceProviders.dropdown.authConfig': '授权配置',
|
||||||
'system.serviceProviders.dropdown.accountManage': '账户管理',
|
'system.serviceProviders.dropdown.accountManage': '账户管理',
|
||||||
'system.serviceProviders.dropdown.export': '导出',
|
'system.serviceProviders.dropdown.export': '导出',
|
||||||
'system.serviceProviders.dropdown.fixedParams': '公共参数配置',
|
'system.serviceProviders.dropdown.fixedParams': '公共参数',
|
||||||
'system.serviceProviders.dropdown.delete': '删除',
|
'system.serviceProviders.dropdown.delete': '删除',
|
||||||
|
|
||||||
'system.serviceProviders.publish.title': '发布映射缓存 · {name}',
|
'system.serviceProviders.publish.title': '发布映射缓存 · {name}',
|
||||||
'system.serviceProviders.publish.tip': '授权配置、服务商信息等变更写入数据库后,需对已映射的系统接口重新发布,线上缓存才会更新。',
|
'system.serviceProviders.publish.tip': '授权配置、公共参数、服务商信息等变更写入数据库后,需对已映射的系统接口重新发布,线上缓存才会更新。',
|
||||||
'system.serviceProviders.publish.confirmAfterSave': '保存成功。是否立即检查并发布该服务商相关的映射缓存?',
|
'system.serviceProviders.publish.confirmAfterSave': '保存成功。公共参数/配置需发布映射缓存后才对线上生效,是否立即检查并发布?',
|
||||||
'system.serviceProviders.publish.goPublish': '去发布',
|
'system.serviceProviders.publish.goPublish': '去发布',
|
||||||
'system.serviceProviders.publish.later': '稍后',
|
'system.serviceProviders.publish.later': '稍后',
|
||||||
'system.serviceProviders.publish.close': '关闭',
|
'system.serviceProviders.publish.close': '关闭',
|
||||||
|
|||||||
@ -547,6 +547,8 @@
|
|||||||
confirmLeaveUnsaved: (options?: { content?: string }) =>
|
confirmLeaveUnsaved: (options?: { content?: string }) =>
|
||||||
interfaceDetailRef.value?.confirmLeaveUnsaved?.(options) ?? Promise.resolve(true),
|
interfaceDetailRef.value?.confirmLeaveUnsaved?.(options) ?? Promise.resolve(true),
|
||||||
captureDirtyBaseline: () => interfaceDetailRef.value?.captureDirtyBaseline?.(),
|
captureDirtyBaseline: () => interfaceDetailRef.value?.captureDirtyBaseline?.(),
|
||||||
|
refreshInheritedCommonParams: () =>
|
||||||
|
interfaceDetailRef.value?.refreshInheritedCommonParams?.(),
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
getServiceProviderChangeAuthInterface,
|
getServiceProviderChangeAuthInterface,
|
||||||
getServiceProviderGetAuthInfo,
|
getServiceProviderGetAuthInfo,
|
||||||
} from '@/api/ServiceProviderInterface/serviceProviderAuth';
|
} from '@/api/ServiceProviderInterface/serviceProviderAuth';
|
||||||
import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary';
|
|
||||||
import { addModalForm, configData, interfaceId } from './data';
|
import { addModalForm, configData, interfaceId } from './data';
|
||||||
import { $baseConfirm } from '@/utils/confirm';
|
import { $baseConfirm } from '@/utils/confirm';
|
||||||
import FormPro from '@/components/FormPro/index.vue';
|
import FormPro from '@/components/FormPro/index.vue';
|
||||||
@ -234,66 +233,18 @@
|
|||||||
key: number;
|
key: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const dictionaryLoaded = ref(false);
|
const restaurants = ref<RestaurantItem[]>([{ value: '$FromAccount', key: 1 }]);
|
||||||
const loadingDictionary = ref(false);
|
|
||||||
const restaurants = ref<RestaurantItem[]>([]);
|
|
||||||
|
|
||||||
async function loadDictionaryData() {
|
function filterOption(inputValue: string, option: any) {
|
||||||
if (dictionaryLoaded.value || loadingDictionary.value) {
|
return (
|
||||||
return;
|
!inputValue ||
|
||||||
}
|
String(option.value || '')
|
||||||
|
.toLowerCase()
|
||||||
loadingDictionary.value = true;
|
.includes(String(inputValue).toLowerCase())
|
||||||
try {
|
);
|
||||||
const response: any = await getDictionaryGetList({ type: 'ParameterPlaceholder' });
|
|
||||||
let data: API.EnumCacheEntry[] = [];
|
|
||||||
if (Array.isArray(response)) {
|
|
||||||
data = response;
|
|
||||||
} else if (response && Array.isArray(response.data)) {
|
|
||||||
data = response.data;
|
|
||||||
} else if (response && response.data) {
|
|
||||||
data = Array.isArray(response.data) ? response.data : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = data.map((item: any, index: number) => ({
|
|
||||||
value: String(item.value || ''),
|
|
||||||
key: item.key || index,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const defaultOptions = [
|
|
||||||
{ value: '$FromAccount', key: 1 },
|
|
||||||
{ value: '$TimeStamp', key: 2 },
|
|
||||||
];
|
|
||||||
|
|
||||||
const allOptions = [...defaultOptions];
|
|
||||||
options.forEach((option: RestaurantItem) => {
|
|
||||||
if (!allOptions.find((item) => item.value === option.value)) {
|
|
||||||
allOptions.push(option);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
restaurants.value = allOptions;
|
|
||||||
dictionaryLoaded.value = true;
|
|
||||||
} catch {
|
|
||||||
restaurants.value = [
|
|
||||||
{ value: '$FromAccount', key: 1 },
|
|
||||||
{ value: '$TimeStamp', key: 2 },
|
|
||||||
];
|
|
||||||
} finally {
|
|
||||||
loadingDictionary.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadAll() {
|
|
||||||
return [
|
|
||||||
{ value: '$FromAccount', key: 1 },
|
|
||||||
{ value: '$TimeStamp', key: 2 },
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
restaurants.value = loadAll();
|
|
||||||
|
|
||||||
if (configData.interfaceCode) {
|
if (configData.interfaceCode) {
|
||||||
oldVal.value = configData.interfaceCode;
|
oldVal.value = configData.interfaceCode;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@ -312,15 +263,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function filterOption(inputValue: string, option: any) {
|
|
||||||
return (
|
|
||||||
!inputValue ||
|
|
||||||
String(option.value || '')
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(String(inputValue).toLowerCase())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteRow(row: any) {
|
function deleteRow(row: any) {
|
||||||
tableRef.value.removeRow(row);
|
tableRef.value.removeRow(row);
|
||||||
}
|
}
|
||||||
@ -354,8 +296,8 @@
|
|||||||
v-model="record.value"
|
v-model="record.value"
|
||||||
:data="restaurants"
|
:data="restaurants"
|
||||||
allow-clear
|
allow-clear
|
||||||
|
placeholder="请选择或输入 $FromAccount"
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@focus="() => { if (!dictionaryLoaded && !loadingDictionary) loadDictionaryData(); }"
|
|
||||||
@select="(val) => (record.value = val)"
|
@select="(val) => (record.value = val)"
|
||||||
@change="(val) => { record.value = val; }"
|
@change="(val) => { record.value = val; }"
|
||||||
/>
|
/>
|
||||||
|
|||||||
406
src/views/api/downstreamInterface/comps/FixedParameterConfig.vue
Normal file
406
src/views/api/downstreamInterface/comps/FixedParameterConfig.vue
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, nextTick } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import useModal from '@/components/ModalPro/useModal';
|
||||||
|
import ModalPro from '@/components/ModalPro/index.vue';
|
||||||
|
import SelectPro from '@/components/SelectPro/index.vue';
|
||||||
|
import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary';
|
||||||
|
import {
|
||||||
|
getFixedParameterGetFixedParameterList,
|
||||||
|
postFixedParameterMaintainParameter,
|
||||||
|
} from '@/api/ParameterServices/fixedParameter';
|
||||||
|
import { IconDelete, IconPlus } from '@arco-design/web-vue/es/icon';
|
||||||
|
import { $baseMessage } from '@/utils';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'FixedParameterConfig',
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'saved', payload: { id: number; name?: string; code?: string }): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const [register, { openModal, setModalProps }] = useModal() as any;
|
||||||
|
|
||||||
|
const serviceProviderId = ref(0);
|
||||||
|
const serviceProviderMeta = ref<{ id: number; name?: string; code?: string } | null>(null);
|
||||||
|
const loading = ref(false);
|
||||||
|
const saving = ref(false);
|
||||||
|
|
||||||
|
type FixedRow = {
|
||||||
|
__rowKey: string | number;
|
||||||
|
id?: number;
|
||||||
|
fieldName?: string;
|
||||||
|
fieldValue?: string;
|
||||||
|
fieldPositionList?: Array<number | string>;
|
||||||
|
description?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableData = ref<FixedRow[]>([]);
|
||||||
|
const originalById = ref<Map<number, FixedRow>>(new Map());
|
||||||
|
let rowKeySeq = 0;
|
||||||
|
|
||||||
|
const placeholderOptions = ref<{ value: string; label: string }[]>([]);
|
||||||
|
|
||||||
|
const tableColumns = computed(() => [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
width: 64,
|
||||||
|
align: 'center' as const,
|
||||||
|
render: ({ rowIndex }: any) => rowIndex + 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '参数名',
|
||||||
|
dataIndex: 'fieldName',
|
||||||
|
slotName: 'fieldName',
|
||||||
|
minWidth: 140,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '参数值',
|
||||||
|
dataIndex: 'fieldValue',
|
||||||
|
slotName: 'fieldValue',
|
||||||
|
minWidth: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '位置',
|
||||||
|
dataIndex: 'fieldPositionList',
|
||||||
|
slotName: 'fieldPositions',
|
||||||
|
minWidth: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '描述',
|
||||||
|
dataIndex: 'description',
|
||||||
|
slotName: 'description',
|
||||||
|
minWidth: 140,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
slotName: 'action',
|
||||||
|
width: 72,
|
||||||
|
align: 'center' as const,
|
||||||
|
fixed: 'right' as const,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
async function loadDictionaries() {
|
||||||
|
try {
|
||||||
|
const phRes: any = await getDictionaryGetList({ type: 'ParameterPlaceholder' });
|
||||||
|
const phList = phRes?.data || phRes || [];
|
||||||
|
placeholderOptions.value = (Array.isArray(phList) ? phList : []).map((item: any) => ({
|
||||||
|
value: String(item.value ?? item.key ?? ''),
|
||||||
|
label: String(item.value ?? item.key ?? ''),
|
||||||
|
}));
|
||||||
|
} catch {
|
||||||
|
placeholderOptions.value = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeRow(item: any): FixedRow {
|
||||||
|
const id = item?.id != null ? Number(item.id) : undefined;
|
||||||
|
return {
|
||||||
|
__rowKey: id ?? `new_${++rowKeySeq}`,
|
||||||
|
id,
|
||||||
|
fieldName: item?.fieldName ?? '',
|
||||||
|
fieldValue: item?.fieldValue ?? '',
|
||||||
|
fieldPositionList: Array.isArray(item?.fieldPositionList)
|
||||||
|
? [...item.fieldPositionList]
|
||||||
|
: [],
|
||||||
|
description: item?.description ?? '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadList() {
|
||||||
|
if (!serviceProviderId.value) return;
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const res: any = await getFixedParameterGetFixedParameterList({
|
||||||
|
serviceProviderId: serviceProviderId.value,
|
||||||
|
});
|
||||||
|
const data = res?.data || res || [];
|
||||||
|
const list = (Array.isArray(data) ? data : []).map(normalizeRow);
|
||||||
|
tableData.value = list;
|
||||||
|
const map = new Map<number, FixedRow>();
|
||||||
|
list.forEach((row) => {
|
||||||
|
if (row.id != null) {
|
||||||
|
map.set(row.id, {
|
||||||
|
...row,
|
||||||
|
fieldPositionList: [...(row.fieldPositionList || [])],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
originalById.value = map;
|
||||||
|
} catch {
|
||||||
|
tableData.value = [];
|
||||||
|
originalById.value = new Map();
|
||||||
|
$baseMessage('加载公共参数失败', 'error');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init(input: number | { id: number; name?: string; code?: string }) {
|
||||||
|
const id = typeof input === 'number' ? input : Number(input?.id);
|
||||||
|
if (!Number.isFinite(id) || id <= 0) {
|
||||||
|
$baseMessage('请先选择服务商', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
serviceProviderId.value = id;
|
||||||
|
serviceProviderMeta.value =
|
||||||
|
typeof input === 'number'
|
||||||
|
? { id, name: undefined, code: undefined }
|
||||||
|
: { id, name: input?.name, code: input?.code };
|
||||||
|
|
||||||
|
setModalProps?.({
|
||||||
|
title: `${t('system.serviceProviders.dropdown.fixedParams')}${
|
||||||
|
serviceProviderMeta.value?.name ? ` - ${serviceProviderMeta.value.name}` : ''
|
||||||
|
}`,
|
||||||
|
showFooter: true,
|
||||||
|
okText: '保存',
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
openModal();
|
||||||
|
await nextTick();
|
||||||
|
await loadDictionaries();
|
||||||
|
await loadList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAddRow() {
|
||||||
|
tableData.value.push({
|
||||||
|
__rowKey: `new_${++rowKeySeq}`,
|
||||||
|
fieldName: '',
|
||||||
|
fieldValue: '',
|
||||||
|
fieldPositionList: [],
|
||||||
|
description: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDeleteRow(record: FixedRow) {
|
||||||
|
tableData.value = tableData.value.filter((r) => r.__rowKey !== record.__rowKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
function positionsEqual(a?: Array<number | string>, b?: Array<number | string>) {
|
||||||
|
const aa = [...(a || [])].map(String).sort();
|
||||||
|
const bb = [...(b || [])].map(String).sort();
|
||||||
|
if (aa.length !== bb.length) return false;
|
||||||
|
return aa.every((v, i) => v === bb[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rowChanged(curr: FixedRow, orig: FixedRow) {
|
||||||
|
return (
|
||||||
|
String(curr.fieldName ?? '') !== String(orig.fieldName ?? '') ||
|
||||||
|
String(curr.fieldValue ?? '') !== String(orig.fieldValue ?? '') ||
|
||||||
|
String(curr.description ?? '') !== String(orig.description ?? '') ||
|
||||||
|
!positionsEqual(curr.fieldPositionList, orig.fieldPositionList)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildItems() {
|
||||||
|
const items: any[] = [];
|
||||||
|
const currentIds = new Set<number>();
|
||||||
|
|
||||||
|
for (const row of tableData.value) {
|
||||||
|
const name = String(row.fieldName ?? '').trim();
|
||||||
|
if (!name) continue;
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
fieldName: name,
|
||||||
|
fieldValue: row.fieldValue ?? '',
|
||||||
|
fieldPositionList: row.fieldPositionList || [],
|
||||||
|
description: row.description ?? '',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (row.id == null) {
|
||||||
|
items.push({ ...payload, options: 1, id: undefined });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIds.add(row.id);
|
||||||
|
const orig = originalById.value.get(row.id);
|
||||||
|
if (!orig || rowChanged(row, orig)) {
|
||||||
|
items.push({ ...payload, options: 3, id: row.id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [id, orig] of originalById.value.entries()) {
|
||||||
|
if (!currentIds.has(id)) {
|
||||||
|
items.push({
|
||||||
|
id,
|
||||||
|
fieldName: orig.fieldName,
|
||||||
|
fieldValue: orig.fieldValue,
|
||||||
|
fieldPositionList: orig.fieldPositionList || [],
|
||||||
|
description: orig.description,
|
||||||
|
options: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onModalSave() {
|
||||||
|
if (!serviceProviderId.value) return false;
|
||||||
|
|
||||||
|
const emptyName = tableData.value.some((r) => !String(r.fieldName ?? '').trim());
|
||||||
|
if (emptyName) {
|
||||||
|
$baseMessage('请填写参数名', 'warning');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const names = tableData.value.map((r) => String(r.fieldName ?? '').trim().toLowerCase());
|
||||||
|
if (new Set(names).size !== names.length) {
|
||||||
|
$baseMessage('参数名不能重复', 'warning');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = buildItems();
|
||||||
|
if (items.length === 0) {
|
||||||
|
$baseMessage('暂无变更需要保存', 'warning');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
saving.value = true;
|
||||||
|
setModalProps?.({ confirmLoading: true });
|
||||||
|
try {
|
||||||
|
await postFixedParameterMaintainParameter({
|
||||||
|
serviceProviderId: serviceProviderId.value,
|
||||||
|
items,
|
||||||
|
});
|
||||||
|
$baseMessage('保存成功,如需生效请去发布', 'success');
|
||||||
|
emit('saved', {
|
||||||
|
id: Number(serviceProviderId.value),
|
||||||
|
name: serviceProviderMeta.value?.name,
|
||||||
|
code: serviceProviderMeta.value?.code,
|
||||||
|
});
|
||||||
|
await loadList();
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
$baseMessage('保存失败', 'error');
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
saving.value = false;
|
||||||
|
setModalProps?.({ confirmLoading: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ init });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="fixed-parameter-config">
|
||||||
|
<ModalPro
|
||||||
|
:width="920"
|
||||||
|
:title="t('system.serviceProviders.dropdown.fixedParams')"
|
||||||
|
:loading="loading || saving"
|
||||||
|
@register="register"
|
||||||
|
@ok="onModalSave"
|
||||||
|
>
|
||||||
|
<div class="fixed-parameter-body">
|
||||||
|
<a-alert type="info" :show-icon="false" class="modal-form-tip">
|
||||||
|
配置当前服务商的公共参数,供其下接口共用。路径:修改 → 保存 → 发布映射缓存后才对线上生效。
|
||||||
|
</a-alert>
|
||||||
|
|
||||||
|
<div class="table-toolbar">
|
||||||
|
<div class="toolbar-left">
|
||||||
|
<a-button type="primary" class="app-btn-primary-soft" size="small" @click="handleAddRow">
|
||||||
|
<template #icon><IconPlus /></template>
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-right">
|
||||||
|
<span class="row-count">共 {{ tableData.length }} 条</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
size="small"
|
||||||
|
row-key="__rowKey"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:data="tableData"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="false"
|
||||||
|
:bordered="{ cell: true }"
|
||||||
|
:scroll="{ y: 420 }"
|
||||||
|
class="fixed-parameter-table"
|
||||||
|
>
|
||||||
|
<template #empty>
|
||||||
|
<div class="empty-tip">暂无公共参数,点击「新增」添加</div>
|
||||||
|
</template>
|
||||||
|
<template #fieldName="{ record }">
|
||||||
|
<a-input v-model="record.fieldName" allow-clear placeholder="请输入参数名" />
|
||||||
|
</template>
|
||||||
|
<template #fieldValue="{ record }">
|
||||||
|
<a-auto-complete
|
||||||
|
v-model="record.fieldValue"
|
||||||
|
:data="placeholderOptions"
|
||||||
|
allow-clear
|
||||||
|
placeholder="请选择或输入参数值"
|
||||||
|
:filter-option="
|
||||||
|
(inputValue, option) =>
|
||||||
|
!inputValue ||
|
||||||
|
String(option.value || '')
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(String(inputValue).toLowerCase())
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #fieldPositions="{ record }">
|
||||||
|
<SelectPro
|
||||||
|
v-model="record.fieldPositionList"
|
||||||
|
:api="getDictionaryGetList"
|
||||||
|
:extra="{ type: 'FieldPosition' }"
|
||||||
|
:is-page="false"
|
||||||
|
:immediate="true"
|
||||||
|
:label-keys="['value']"
|
||||||
|
:multiple="true"
|
||||||
|
id-key="key"
|
||||||
|
placeholder="请选择位置"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #description="{ record }">
|
||||||
|
<a-input v-model="record.description" allow-clear placeholder="可选" />
|
||||||
|
</template>
|
||||||
|
<template #action="{ record }">
|
||||||
|
<a-button type="text" size="small" status="danger" title="删除" @click="handleDeleteRow(record)">
|
||||||
|
<template #icon><IconDelete /></template>
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
</ModalPro>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.fixed-parameter-body {
|
||||||
|
.modal-form-tip {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-count {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tip {
|
||||||
|
padding: 24px 0;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-parameter-table {
|
||||||
|
:deep(.arco-input-wrapper),
|
||||||
|
:deep(.arco-select-view),
|
||||||
|
:deep(.arco-auto-complete) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -18,6 +18,7 @@
|
|||||||
postServiceProviderImport,
|
postServiceProviderImport,
|
||||||
} from '@/api/interface-serviceProvider/serviceProviderImportExport';
|
} from '@/api/interface-serviceProvider/serviceProviderImportExport';
|
||||||
import ParameterConfig from '@/views/api/downstreamInterface/comps/ParameterConfig.vue';
|
import ParameterConfig from '@/views/api/downstreamInterface/comps/ParameterConfig.vue';
|
||||||
|
import FixedParameterConfig from '@/views/api/downstreamInterface/comps/FixedParameterConfig.vue';
|
||||||
import FormPro from '@/components/FormPro/index.vue';
|
import FormPro from '@/components/FormPro/index.vue';
|
||||||
import TableButtons from '@/components/TableButtons/index.vue';
|
import TableButtons from '@/components/TableButtons/index.vue';
|
||||||
import {
|
import {
|
||||||
@ -32,6 +33,7 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary';
|
import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary';
|
||||||
import { getAppGetDropDownList } from '@/api/ApplicationServices/apps';
|
import { getAppGetDropDownList } from '@/api/ApplicationServices/apps';
|
||||||
|
import { getFixedParameterGetFixedParameterList } from '@/api/ParameterServices/fixedParameter';
|
||||||
import ServiceProviderInterfaceModal from './components/ServiceProviderInterfaceModal.vue';
|
import ServiceProviderInterfaceModal from './components/ServiceProviderInterfaceModal.vue';
|
||||||
import AccountList from './comps/AccountList.vue';
|
import AccountList from './comps/AccountList.vue';
|
||||||
import ProviderMapPublishModal from './comps/ProviderMapPublishModal.vue';
|
import ProviderMapPublishModal from './comps/ProviderMapPublishModal.vue';
|
||||||
@ -48,6 +50,7 @@
|
|||||||
IconRefresh,
|
IconRefresh,
|
||||||
IconMore,
|
IconMore,
|
||||||
IconDelete,
|
IconDelete,
|
||||||
|
IconList,
|
||||||
} from '@arco-design/web-vue/es/icon';
|
} from '@arco-design/web-vue/es/icon';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
@ -111,6 +114,8 @@
|
|||||||
const searchKeyword = ref('');
|
const searchKeyword = ref('');
|
||||||
const serviceProviderList = ref<any[]>([]);
|
const serviceProviderList = ref<any[]>([]);
|
||||||
const selectedProvider = ref<any>(null);
|
const selectedProvider = ref<any>(null);
|
||||||
|
const commonParamsCount = ref<number | null>(null);
|
||||||
|
const commonParamsLoading = ref(false);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
// 接口弹窗相关
|
// 接口弹窗相关
|
||||||
@ -960,11 +965,63 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const accountList = ref();
|
const accountList = ref();
|
||||||
|
const fixedParameterConfigRef = ref<InstanceType<typeof FixedParameterConfig> | null>(null);
|
||||||
|
|
||||||
function accountManageClick(row: any) {
|
function accountManageClick(row: any) {
|
||||||
accountList.value?.init?.(row);
|
accountList.value?.init?.(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleFixedParamsWithSelect(provider: any) {
|
||||||
|
handleProviderSelect(provider);
|
||||||
|
setTimeout(() => {
|
||||||
|
fixedParameterConfigRef.value?.init?.(provider);
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshCommonParamsCount(providerLike?: any) {
|
||||||
|
const id = Number(providerLike?.id || selectedProvider.value?.id || 0);
|
||||||
|
if (!Number.isFinite(id) || id <= 0) {
|
||||||
|
commonParamsCount.value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
commonParamsLoading.value = true;
|
||||||
|
try {
|
||||||
|
const res: any = await getFixedParameterGetFixedParameterList({
|
||||||
|
serviceProviderId: id,
|
||||||
|
});
|
||||||
|
const data = res?.data || res || [];
|
||||||
|
commonParamsCount.value = Array.isArray(data) ? data.length : 0;
|
||||||
|
} catch {
|
||||||
|
commonParamsCount.value = null;
|
||||||
|
} finally {
|
||||||
|
commonParamsLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => selectedProvider.value?.id,
|
||||||
|
() => {
|
||||||
|
refreshCommonParamsCount();
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
function openCommonParamsFromTabs() {
|
||||||
|
const provider = selectedProvider.value;
|
||||||
|
if (!provider?.id) {
|
||||||
|
$baseMessage('请先选择服务商', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fixedParameterConfigRef.value?.init?.(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFixedParamsSaved(payload: any) {
|
||||||
|
refreshCommonParamsCount(payload);
|
||||||
|
interfaceDetailModalRef.value?.refreshInheritedCommonParams?.();
|
||||||
|
interfaceModalRef.value?.refreshInheritedCommonParams?.();
|
||||||
|
askGoPublish(payload);
|
||||||
|
}
|
||||||
|
|
||||||
function mapAccountClick(row: { id: any; code: any; name?: string }) {
|
function mapAccountClick(row: { id: any; code: any; name?: string }) {
|
||||||
accountList.value?.init?.(row);
|
accountList.value?.init?.(row);
|
||||||
}
|
}
|
||||||
@ -1644,6 +1701,10 @@
|
|||||||
<IconSettings style="margin-right: 8px;" />
|
<IconSettings style="margin-right: 8px;" />
|
||||||
{{ t('system.serviceProviders.dropdown.authConfig') }}
|
{{ t('system.serviceProviders.dropdown.authConfig') }}
|
||||||
</a-doption>
|
</a-doption>
|
||||||
|
<a-doption @click="handleFixedParamsWithSelect(nodeData)">
|
||||||
|
<IconList style="margin-right: 8px;" />
|
||||||
|
{{ t('system.serviceProviders.dropdown.fixedParams') }}
|
||||||
|
</a-doption>
|
||||||
<a-doption @click="accountManageClick(nodeData)">
|
<a-doption @click="accountManageClick(nodeData)">
|
||||||
<IconUser style="margin-right: 8px;" />
|
<IconUser style="margin-right: 8px;" />
|
||||||
{{ t('system.serviceProviders.dropdown.accountManage') }}
|
{{ t('system.serviceProviders.dropdown.accountManage') }}
|
||||||
@ -1719,7 +1780,22 @@
|
|||||||
:items="interfaceDetailTabItems"
|
:items="interfaceDetailTabItems"
|
||||||
@change="switchInterfaceDetailTab"
|
@change="switchInterfaceDetailTab"
|
||||||
/>
|
/>
|
||||||
<div class="tabs-extra" v-if="selectedInterface && interfaceDetailTab !== 'detail'"></div>
|
<div v-if="selectedProvider" class="tabs-extra">
|
||||||
|
<a-button
|
||||||
|
size="small"
|
||||||
|
class="common-params-entry"
|
||||||
|
title="服务商公共参数,发布映射后对该服务商下接口生效"
|
||||||
|
@click="openCommonParamsFromTabs"
|
||||||
|
>
|
||||||
|
公共参数{{
|
||||||
|
commonParamsLoading
|
||||||
|
? ''
|
||||||
|
: commonParamsCount != null
|
||||||
|
? ` · ${commonParamsCount}`
|
||||||
|
: ''
|
||||||
|
}}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1813,6 +1889,7 @@
|
|||||||
ref="parameterConfigFlag"
|
ref="parameterConfigFlag"
|
||||||
@saved="askGoPublish"
|
@saved="askGoPublish"
|
||||||
/>
|
/>
|
||||||
|
<FixedParameterConfig ref="fixedParameterConfigRef" @saved="onFixedParamsSaved" />
|
||||||
<AccountList ref="accountList" @saved="askGoPublish" />
|
<AccountList ref="accountList" @saved="askGoPublish" />
|
||||||
<ProviderMapPublishModal ref="providerPublishRef" />
|
<ProviderMapPublishModal ref="providerPublishRef" />
|
||||||
</div>
|
</div>
|
||||||
@ -1995,6 +2072,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.common-params-entry {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user