diff --git a/src/components/ApiTest/index.vue b/src/components/ApiTest/index.vue index 22c2f5d..ac3ed06 100644 --- a/src/components/ApiTest/index.vue +++ b/src/components/ApiTest/index.vue @@ -1955,7 +1955,6 @@ (); for (const row of rows || []) { + if (isCommonParamRow(row)) continue; const name = String(row?.name ?? '').trim(); if (!name) return `${label} 存在未填写参数名的行,请补全或删除空行`; const key = name.toLowerCase(); @@ -583,6 +584,138 @@ () => props.showQuery && !isDownstreamMode.value, ); const showHeaderTab = computed(() => isDownstreamMode.value && props.showQuery); + + /** 下游:服务商公共参数按位置回落到 Query/Header/Body(只读置灰) */ + const inheritedCommonParams = ref([]); + 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>(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( () => isDownstreamMode.value && isNoneContentType(props.basicFormData?.contentType), ); @@ -992,7 +1125,9 @@ mode: 'row', showStatus: true, autoClear: false, + beforeEditMethod: ({ row }: { row: any }) => !isCommonParamRow(row), }, + rowClassName: ({ row }: { row: any }) => (isCommonParamRow(row) ? 'row-common-param' : ''), }, showIndex: false, data: [] as any[], @@ -1017,6 +1152,14 @@ data: [] as any[], }); + watch( + () => [props.serviceProviderId, props.parameterMode] as const, + () => { + refreshInheritedCommonParams(); + }, + { immediate: true }, + ); + // Query 固定配置表格(不传 height,随内容自然增高,与 Query 列表的固定高度区分) const queryFixedTableProps = computed(() => ({ columns: [ @@ -1327,11 +1470,17 @@ const canClearCurrentRequestTab = computed(() => { if (!showRequestTabClearAction.value) return false; - if (requestTab.value === 'query') return queryTabCount.value > 0; - if (requestTab.value === 'header') return headerTabCount.value > 0; + if (requestTab.value === 'query') { + 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 === 'body') { - if (isBodyKvMode.value) return !isBodyKvEmpty.value; + if (isBodyKvMode.value) { + return stripCommonRows(getTableFullData(bodyFormTableRef, bodyFormTableProps.data)).length > 0; + } return !isBodyTreeEmpty.value; } if (requestTab.value === 'mappingBody') return !isMappingBodyEmpty.value; @@ -1339,48 +1488,65 @@ return false; }); - // 监听 queryParams prop 变化,同步到表格数据 + // 监听 queryParams prop 变化,同步到表格数据(并合并公共参数) watch( () => props.queryParams, - (newVal: any) => { - if (newVal && Array.isArray(newVal)) { - // 只在数据真正变化时才更新,避免循环 - const currentData = queryTableProps.data || []; - if (currentData.length !== newVal.length || JSON.stringify(currentData) !== JSON.stringify(newVal)) { - queryTableProps.data = [...newVal] as any[]; - if (queryTableRef.value) { - queryTableRef.value.reloadData([...newVal]); - } - } + async (newVal: any) => { + if (!newVal || !Array.isArray(newVal)) return; + const own = stripCommonRows(newVal); + const currentOwn = stripCommonRows(queryTableProps.data || []); + if ( + currentOwn.length !== own.length + || JSON.stringify(currentOwn) !== JSON.stringify(own) + ) { + await applyKvTableWithCommon( + queryTableProps, + queryTableRef, + own, + inheritedQueryParams.value, + ); } }, - { immediate: true } + { immediate: true }, ); function syncKvTableProps( propList: any[] | undefined, tableProps: { data: any[] }, tableRef: typeof queryTableRef, + commonList: any[], ) { if (!propList || !Array.isArray(propList)) return; - const currentData = tableProps.data || []; + const own = stripCommonRows(propList); + const currentOwn = stripCommonRows(tableProps.data || []); if ( - currentData.length !== propList.length - || JSON.stringify(currentData) !== JSON.stringify(propList) + currentOwn.length !== own.length + || JSON.stringify(currentOwn) !== JSON.stringify(own) ) { - tableProps.data = [...propList] as any[]; - tableRef.value?.reloadData?.([...propList]); + applyKvTableWithCommon(tableProps, tableRef, own, commonList); } } watch( () => props.headerParams, - (newVal) => syncKvTableProps(newVal as any[], headerTableProps, headerTableRef), + (newVal) => + syncKvTableProps( + newVal as any[], + headerTableProps, + headerTableRef, + inheritedHeaderParams.value, + ), { immediate: true }, ); watch( () => props.bodyFormParams, - (newVal) => syncKvTableProps(newVal as any[], bodyFormTableProps, bodyFormTableRef), + (newVal) => + syncKvTableProps( + newVal as any[], + bodyFormTableProps, + bodyFormTableRef, + inheritedBodyParams.value, + ), { immediate: true }, ); watch( @@ -1839,13 +2005,13 @@ tableRef: any, keepRow?: (row: any) => boolean, ) { - const roots = [...(getTableFullData(tableRef) || [])]; + const roots = [...(getTableFullData(tableRef) || [])].filter((r) => !isCommonParamRow(r)); if (!keepRow) return roots; const toRemove: any[] = []; roots.forEach((row) => { if (keepRow(row)) { if (Array.isArray(row?.children) && row.children.length) { - toRemove.push(...row.children); + toRemove.push(...row.children.filter((c: any) => !isCommonParamRow(c))); } return; } @@ -1858,17 +2024,32 @@ const tab = requestTab.value; if (tab === 'query') { await removeTableRows(queryTableRef, collectRemovableTableRows(queryTableRef)); - queryTableProps.data = []; + await applyKvTableWithCommon( + queryTableProps, + queryTableRef, + [], + inheritedQueryParams.value, + ); } else if (tab === 'header') { await removeTableRows(headerTableRef, collectRemovableTableRows(headerTableRef)); - headerTableProps.data = []; + await applyKvTableWithCommon( + headerTableProps, + headerTableRef, + [], + inheritedHeaderParams.value, + ); } else if (tab === 'fixed') { await removeTableRows(queryFixedTableRef, collectRemovableTableRows(queryFixedTableRef)); fixedParams.value = []; fixedParamsHasChanges.value = true; } else if (tab === 'body' && isBodyKvMode.value) { await removeTableRows(bodyFormTableRef, collectRemovableTableRows(bodyFormTableRef)); - bodyFormTableProps.data = []; + await applyKvTableWithCommon( + bodyFormTableProps, + bodyFormTableRef, + [], + inheritedBodyParams.value, + ); } else if (tab === 'body' && !isNoneBodyContentType.value) { if (hoistedBodyArrayWrapper.value) { const persisted = getRequestBodyFlatParams(); @@ -1941,6 +2122,7 @@ // 删除 Query 参数行 async function deleteQueryRow(row: any) { + if (isCommonParamRow(row)) return; markDirty(); await queryTableRef.value?.removeRow(row); refreshTabCounts(); @@ -1955,6 +2137,7 @@ } async function deleteHeaderRow(row: any) { + if (isCommonParamRow(row)) return; markDirty(); await headerTableRef.value?.removeRow(row); refreshTabCounts(); @@ -1969,6 +2152,7 @@ } async function deleteBodyFormRow(row: any) { + if (isCommonParamRow(row)) return; markDirty(); await bodyFormTableRef.value?.removeRow(row); refreshTabCounts(); @@ -2922,10 +3106,9 @@ tableProps: { data: any[] }, tableRef: { value?: { reloadData?: (rows: any[]) => void } }, rows: any[], + commonList: any[] = [], ) { - tableProps.data = rows; - await nextTick(); - tableRef.value?.reloadData?.(rows); + await applyKvTableWithCommon(tableProps, tableRef, rows, commonList); } async function loadFlatListIntoTreeTable( @@ -3022,11 +3205,26 @@ await nextTick(); refBasicForm.value?.setFormValue?.(nextBasic); - await reloadKvTable(queryTableProps, queryTableRef, payload.queryParams); + await reloadKvTable( + queryTableProps, + queryTableRef, + payload.queryParams, + inheritedQueryParams.value, + ); if (isDownstreamMode.value) { - await reloadKvTable(headerTableProps, headerTableRef, payload.headerParams ?? []); - await reloadKvTable(bodyFormTableProps, bodyFormTableRef, isForm ? payload.bodyFormParams : []); + await reloadKvTable( + headerTableProps, + headerTableRef, + payload.headerParams ?? [], + inheritedHeaderParams.value, + ); + await reloadKvTable( + bodyFormTableProps, + bodyFormTableRef, + isForm ? payload.bodyFormParams : [], + inheritedBodyParams.value, + ); if (!isForm && !isNone) { mappingBodyTableProps.data = []; await nextTick(); @@ -3197,20 +3395,27 @@ validateDetailParamsBeforeSave, captureDirtyBaseline, markDirty, + refreshInheritedCommonParams, isDirty: () => isDirty.value, getSaveSnapshot: (): InterfaceDetailSnapshot => ({ - queryParams: queryTableRef.value?.getTableData?.()?.fullData + queryParams: stripCommonRows( + queryTableRef.value?.getTableData?.()?.fullData || queryTableRef.value?.xGrid?.getTableData()?.fullData || queryTableProps.data || [], - headerParams: headerTableRef.value?.getTableData?.()?.fullData + ), + headerParams: stripCommonRows( + headerTableRef.value?.getTableData?.()?.fullData || headerTableRef.value?.xGrid?.getTableData()?.fullData || headerTableProps.data || [], - bodyFormParams: bodyFormTableRef.value?.getTableData?.()?.fullData + ), + bodyFormParams: stripCommonRows( + bodyFormTableRef.value?.getTableData?.()?.fullData || bodyFormTableRef.value?.xGrid?.getTableData()?.fullData || bodyFormTableProps.data || [], + ), requestParams: getRequestBodyFlatParams(), mappingBodyParams: getTreeTableFlatRows( mappingBodyTableRef.value?.getTableData?.()?.fullData @@ -3221,9 +3426,9 @@ || responseTableRef.value?.xGrid?.getTableData()?.fullData || responseTableProps.data || [], - queryActionRows: queryTableRef.value?.getActionRows?.() || { insertRecords: [], removeRecords: [], updateRecords: [] }, - headerActionRows: headerTableRef.value?.getActionRows?.() || { insertRecords: [], removeRecords: [], updateRecords: [] }, - bodyFormActionRows: bodyFormTableRef.value?.getActionRows?.() || { insertRecords: [], removeRecords: [], updateRecords: [] }, + queryActionRows: filterCommonFromActionRows(queryTableRef.value?.getActionRows?.()), + headerActionRows: filterCommonFromActionRows(headerTableRef.value?.getActionRows?.()), + bodyFormActionRows: filterCommonFromActionRows(bodyFormTableRef.value?.getActionRows?.()), requestActionRows: stripBodyRootFromActionRows( requestTableRef.value?.getActionRows?.() || { insertRecords: [], @@ -3472,7 +3677,10 @@ placeholder="请输入参数名" /> - {{ row.name || '-' }} + + {{ row.name || '-' }} + 公共 + @@ -3640,7 +3849,10 @@ > @@ -3687,7 +3904,7 @@ -
+
@@ -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 { display: flex; diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index 158b545..0eee2a6 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -2514,12 +2514,12 @@ export default { 'system.serviceProviders.dropdown.authConfig': 'Auth config', 'system.serviceProviders.dropdown.accountManage': 'Account management', 'system.serviceProviders.dropdown.export': 'Export', - 'system.serviceProviders.dropdown.fixedParams': 'Common parameters', + 'system.serviceProviders.dropdown.fixedParams': 'Common params', 'system.serviceProviders.dropdown.delete': 'Delete', '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.confirmAfterSave': 'Saved. Check and publish mapping cache for this provider now?', + '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. Common params / config take effect online only after publishing mapping cache. Check and publish now?', 'system.serviceProviders.publish.goPublish': 'Publish', 'system.serviceProviders.publish.later': 'Later', 'system.serviceProviders.publish.close': 'Close', diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index b812de6..6551e2f 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -2412,12 +2412,12 @@ export default { 'system.serviceProviders.dropdown.authConfig': '授权配置', 'system.serviceProviders.dropdown.accountManage': '账户管理', 'system.serviceProviders.dropdown.export': '导出', - 'system.serviceProviders.dropdown.fixedParams': '公共参数配置', + 'system.serviceProviders.dropdown.fixedParams': '公共参数', 'system.serviceProviders.dropdown.delete': '删除', 'system.serviceProviders.publish.title': '发布映射缓存 · {name}', - 'system.serviceProviders.publish.tip': '授权配置、服务商信息等变更写入数据库后,需对已映射的系统接口重新发布,线上缓存才会更新。', - 'system.serviceProviders.publish.confirmAfterSave': '保存成功。是否立即检查并发布该服务商相关的映射缓存?', + 'system.serviceProviders.publish.tip': '授权配置、公共参数、服务商信息等变更写入数据库后,需对已映射的系统接口重新发布,线上缓存才会更新。', + 'system.serviceProviders.publish.confirmAfterSave': '保存成功。公共参数/配置需发布映射缓存后才对线上生效,是否立即检查并发布?', 'system.serviceProviders.publish.goPublish': '去发布', 'system.serviceProviders.publish.later': '稍后', 'system.serviceProviders.publish.close': '关闭', diff --git a/src/views/api/downstreamInterface/components/ServiceProviderInterfaceModal.vue b/src/views/api/downstreamInterface/components/ServiceProviderInterfaceModal.vue index 7a9dc98..803f641 100644 --- a/src/views/api/downstreamInterface/components/ServiceProviderInterfaceModal.vue +++ b/src/views/api/downstreamInterface/components/ServiceProviderInterfaceModal.vue @@ -547,6 +547,8 @@ confirmLeaveUnsaved: (options?: { content?: string }) => interfaceDetailRef.value?.confirmLeaveUnsaved?.(options) ?? Promise.resolve(true), captureDirtyBaseline: () => interfaceDetailRef.value?.captureDirtyBaseline?.(), + refreshInheritedCommonParams: () => + interfaceDetailRef.value?.refreshInheritedCommonParams?.(), }); diff --git a/src/views/api/downstreamInterface/comps/Entering.vue b/src/views/api/downstreamInterface/comps/Entering.vue index 07f6a73..155a602 100644 --- a/src/views/api/downstreamInterface/comps/Entering.vue +++ b/src/views/api/downstreamInterface/comps/Entering.vue @@ -7,7 +7,6 @@ getServiceProviderChangeAuthInterface, getServiceProviderGetAuthInfo, } from '@/api/ServiceProviderInterface/serviceProviderAuth'; - import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary'; import { addModalForm, configData, interfaceId } from './data'; import { $baseConfirm } from '@/utils/confirm'; import FormPro from '@/components/FormPro/index.vue'; @@ -234,66 +233,18 @@ key: number; }; - const dictionaryLoaded = ref(false); - const loadingDictionary = ref(false); - const restaurants = ref([]); + const restaurants = ref([{ value: '$FromAccount', key: 1 }]); - async function loadDictionaryData() { - if (dictionaryLoaded.value || loadingDictionary.value) { - return; - } - - loadingDictionary.value = true; - 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 }, - ]; + function filterOption(inputValue: string, option: any) { + return ( + !inputValue || + String(option.value || '') + .toLowerCase() + .includes(String(inputValue).toLowerCase()) + ); } onMounted(async () => { - restaurants.value = loadAll(); - if (configData.interfaceCode) { oldVal.value = configData.interfaceCode; 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) { tableRef.value.removeRow(row); } @@ -354,8 +296,8 @@ v-model="record.value" :data="restaurants" allow-clear + placeholder="请选择或输入 $FromAccount" :filter-option="filterOption" - @focus="() => { if (!dictionaryLoaded && !loadingDictionary) loadDictionaryData(); }" @select="(val) => (record.value = val)" @change="(val) => { record.value = val; }" /> diff --git a/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue b/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue new file mode 100644 index 0000000..b8f45e5 --- /dev/null +++ b/src/views/api/downstreamInterface/comps/FixedParameterConfig.vue @@ -0,0 +1,406 @@ + + + + + diff --git a/src/views/api/downstreamInterface/index.vue b/src/views/api/downstreamInterface/index.vue index 747f1fe..91ffe0e 100644 --- a/src/views/api/downstreamInterface/index.vue +++ b/src/views/api/downstreamInterface/index.vue @@ -18,6 +18,7 @@ postServiceProviderImport, } from '@/api/interface-serviceProvider/serviceProviderImportExport'; 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 TableButtons from '@/components/TableButtons/index.vue'; import { @@ -32,6 +33,7 @@ import dayjs from 'dayjs'; import { getDictionaryGetList } from '@/api/ApplicationServices/dictionary'; import { getAppGetDropDownList } from '@/api/ApplicationServices/apps'; + import { getFixedParameterGetFixedParameterList } from '@/api/ParameterServices/fixedParameter'; import ServiceProviderInterfaceModal from './components/ServiceProviderInterfaceModal.vue'; import AccountList from './comps/AccountList.vue'; import ProviderMapPublishModal from './comps/ProviderMapPublishModal.vue'; @@ -48,6 +50,7 @@ IconRefresh, IconMore, IconDelete, + IconList, } from '@arco-design/web-vue/es/icon'; import { useI18n } from 'vue-i18n'; @@ -111,6 +114,8 @@ const searchKeyword = ref(''); const serviceProviderList = ref([]); const selectedProvider = ref(null); + const commonParamsCount = ref(null); + const commonParamsLoading = ref(false); const loading = ref(false); // 接口弹窗相关 @@ -960,11 +965,63 @@ } const accountList = ref(); + const fixedParameterConfigRef = ref | null>(null); function accountManageClick(row: any) { 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 }) { accountList.value?.init?.(row); } @@ -1644,6 +1701,10 @@ {{ t('system.serviceProviders.dropdown.authConfig') }} + + + {{ t('system.serviceProviders.dropdown.fixedParams') }} + {{ t('system.serviceProviders.dropdown.accountManage') }} @@ -1719,7 +1780,22 @@ :items="interfaceDetailTabItems" @change="switchInterfaceDetailTab" /> -
+
+ + 公共参数{{ + commonParamsLoading + ? '' + : commonParamsCount != null + ? ` · ${commonParamsCount}` + : '' + }} + +
@@ -1813,6 +1889,7 @@ ref="parameterConfigFlag" @saved="askGoPublish" /> + @@ -1995,6 +2072,11 @@ display: flex; align-items: center; flex-shrink: 0; + gap: 8px; + + .common-params-entry { + color: var(--color-text-2); + } } } }