feat(credit): 为企业信用模块添加数据统计和标签高亮功能

- 在CreditCompany模型中新增多个信用相关记录数字段用于数据统计
- 实现标签页数据高亮显示功能,通过记录数判断标签是否有数据
- 添加tabCountFieldMap映射配置不同标签对应的记录数字段
- 实现syncTabsHasDataFromCounts方法同步标签数据状态
- 新增normalizeHasData方法规范化数据存在性判断逻辑
- 添加CSS样式实现有数据标签的红色高亮显示效果
- 更新开发环境API地址配置并移除注释标记
This commit is contained in:
2026-01-28 23:45:27 +08:00
parent 17487cce2b
commit f78aa97bd1
3 changed files with 137 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
VITE_APP_NAME=后台管理(开发环境) VITE_APP_NAME=后台管理(开发环境)
#VITE_API_URL=http://127.0.0.1:9200/api VITE_API_URL=http://127.0.0.1:9200/api
#VITE_SERVER_API_URL=http://127.0.0.1:8000/api #VITE_SERVER_API_URL=http://127.0.0.1:8000/api

View File

@@ -108,6 +108,56 @@ export interface CreditCompany {
cechnologyLevel?: string; cechnologyLevel?: string;
// 是否小微企业 // 是否小微企业
smallEnterprise?: string; smallEnterprise?: string;
// 记录数
creditAdministrativeLicense?: number;
// 记录数
creditBankruptcy?: number;
// 记录数
creditBranch?: number;
// 记录数
creditBreachOfTrust?: number;
// 记录数
creditCaseFiling?: number;
// 记录数
creditCompetitor?: number;
// 记录数
creditCourtAnnouncement?: number;
// 记录数
creditCourtSession?: number;
// 记录数
creditCustomer?: number;
// 记录数
creditDeliveryNotice?: number;
// 记录数
creditExternal?: number;
// 记录数
creditFinalVersion?: number;
// 记录数
creditGqdj?: number;
// 记录数
creditHistoricalLegalPerson?: number;
// 记录数
creditJudgmentDebtor?: number;
// 记录数
creditJudicialDocument?: number;
// 记录数
creditJudiciary?: number;
// 记录数
creditMediation?: number;
// 记录数
creditNearbyCompany?: number;
// 记录数
creditPatent?: number;
// 记录数
creditRiskRelation?: number;
// 记录数
creditSupplier?: number;
// 记录数
creditSuspectedRelationship?: number;
// 记录数
creditUser?: number;
// 记录数
creditXgxf?: number;
// 备注 // 备注
comments?: string; comments?: string;
// 是否推荐 // 是否推荐

View File

@@ -40,7 +40,16 @@
:tabBarGutter="9" :tabBarGutter="9"
class="credit-company-tabs" class="credit-company-tabs"
> >
<a-tab-pane v-for="tab in tabList" :key="tab.key" :tab="tab.label"> <a-tab-pane v-for="tab in tabList" :key="tab.key">
<template #tab>
<span
:class="{
'credit-company-tab-has-data': tabHasData[tab.key]
}"
>
{{ tab.label }}
</span>
</template>
<a-space style="margin-bottom: 12px"> <a-space style="margin-bottom: 12px">
<a-button <a-button
type="primary" type="primary"
@@ -272,6 +281,38 @@
{ key: '历史法定代表人', label: '历史法定代表人' } { key: '历史法定代表人', label: '历史法定代表人' }
]; ];
/**
* 企业详情接口会下发各子表“记录数”(见 CreditCompany 模型中 `// 记录数` 字段)。
* 用这个来做 Tab 高亮,避免为了计算高亮去逐个请求所有子表接口。
*/
const tabCountFieldMap: Record<string, keyof CreditCompany> = {
招投标: 'creditUser',
对外投资: 'creditExternal',
风险关系: 'creditRiskRelation',
竞争对手: 'creditCompetitor',
供应商: 'creditSupplier',
客户: 'creditCustomer',
司法案件: 'creditJudiciary',
被执行人: 'creditJudgmentDebtor',
限制高消费: 'creditXgxf',
终本案件: 'creditFinalVersion',
开庭公告: 'creditCourtSession',
法院公告: 'creditCourtAnnouncement',
失信被执行人: 'creditBreachOfTrust',
裁判文书: 'creditJudicialDocument',
立案信息: 'creditCaseFiling',
诉前调解: 'creditMediation',
送达公告: 'creditDeliveryNotice',
股权冻结: 'creditGqdj',
附近企业: 'creditNearbyCompany',
分支机构: 'creditBranch',
破产重整: 'creditBankruptcy',
行政许可: 'creditAdministrativeLicense',
疑似关系: 'creditSuspectedRelationship',
专利: 'creditPatent',
历史法定代表人: 'creditHistoricalLegalPerson'
};
type TabApiConfig = { type TabApiConfig = {
page: ( page: (
params: any params: any
@@ -436,7 +477,9 @@
'recommend', 'recommend',
'url', 'url',
'comments', 'comments',
'companyId' 'companyId',
// Backend flag; do not show in tables.
'hasData'
]); ]);
const commonTitleMap: Record<string, string> = { const commonTitleMap: Record<string, string> = {
@@ -1183,6 +1226,7 @@
}; };
const tabState = reactive<Record<string, TabState>>({}); const tabState = reactive<Record<string, TabState>>({});
const tabHasData = reactive<Record<string, boolean>>({});
tabList.forEach((tab) => { tabList.forEach((tab) => {
tabState[tab.key] = { tabState[tab.key] = {
loading: false, loading: false,
@@ -1195,6 +1239,7 @@
}, },
loadedSignature: undefined loadedSignature: undefined
}; };
tabHasData[tab.key] = false;
}); });
const activeTab = ref(tabList[0].key); const activeTab = ref(tabList[0].key);
@@ -1492,6 +1537,29 @@
tabState[tab.key].loading = false; tabState[tab.key].loading = false;
tabState[tab.key].loadedSignature = undefined; tabState[tab.key].loadedSignature = undefined;
resetTabPagination(tab.key); resetTabPagination(tab.key);
tabHasData[tab.key] = false;
});
};
const normalizeHasData = (
res: any,
list: Record<string, any>[],
total: number
) => {
const hasDataRaw =
res?.hasData ?? (list.length ? (list[0] as any)?.hasData : undefined);
return (
Number(hasDataRaw) === 1 ||
list.some((row) => Number((row as any)?.hasData) === 1) ||
(total ?? 0) > 0
);
};
const syncTabsHasDataFromCounts = () => {
tabList.forEach((tab) => {
const field = tabCountFieldMap[tab.key];
const raw = (form as any)?.[field] ?? (props.data as any)?.[field] ?? 0;
tabHasData[tab.key] = Number(raw) > 0;
}); });
}; };
@@ -1546,7 +1614,13 @@
} }
state.pagination.total = res?.count ?? 0; state.pagination.total = res?.count ?? 0;
// Keep the count field in sync (only when backend returns a count), so Tab highlight can update after import/refresh.
const countField = tabCountFieldMap[key];
if (countField && typeof (res as any)?.count === 'number') {
(form as any)[countField] = (res as any).count;
}
state.data = list; state.data = list;
tabHasData[key] = normalizeHasData(res as any, list, state.pagination.total);
if (!state.columns.length) { if (!state.columns.length) {
state.columns = buildColumns(key, state.data); state.columns = buildColumns(key, state.data);
} }
@@ -1584,6 +1658,7 @@
assignObject(form, props.data); assignObject(form, props.data);
} }
activeTab.value = tabList[0].key; activeTab.value = tabList[0].key;
syncTabsHasDataFromCounts();
loadTabData(activeTab.value, true); loadTabData(activeTab.value, true);
} else { } else {
showRelatedImport.value = false; showRelatedImport.value = false;
@@ -1604,7 +1679,16 @@
resetForm(); resetForm();
clearTabData(); clearTabData();
assignObject(form, data); assignObject(form, data);
syncTabsHasDataFromCounts();
loadTabData(activeTab.value, true); loadTabData(activeTab.value, true);
} }
); );
</script> </script>
<style scoped>
/* Tab label highlight when the backend marks this module as having data. */
.credit-company-tab-has-data {
color: #ff4d4f;
font-weight: 600;
}
</style>