fix: align case-file rule filters with business types

This commit is contained in:
wren
2026-05-06 18:18:49 +08:00
parent c7bbe59882
commit 2d8bab2c91
6 changed files with 52 additions and 27 deletions
+2 -1
View File
@@ -136,13 +136,14 @@ export function Layout({ children, userRole = 'developer' as UserRole, frontendJ
const isRulesTestTopbarPage = isRulesTestDetail;
const rulesTestDetailData = matches.find(match => match.pathname.startsWith('/rulesTest/detail'))?.data as RulesTestDetailData | undefined;
const detailPack = rulesTestDetailData?.pack;
const detailPackFilterMainType = detailPack?.businessType || detailPack?.mainType || '';
const isContractDetail = !!detailPack?.documentType?.includes('合同');
const isCaseFileDetail = !!detailPack?.documentType?.includes('案卷');
const showFieldNav = isContractDetail && (detailPack?.fields?.length || 0) > 0;
const showSubDocumentNav = isCaseFileDetail && (detailPack?.subDocuments?.length || 0) > 0;
const showVisualNav = (detailPack?.visualElements?.length || 0) > 0;
const rulesListHref = detailPack?.documentType
? `/rulesTest/list?documentType=${encodeURIComponent(detailPack.documentType)}${detailPack.mainType ? `&mainType=${encodeURIComponent(detailPack.mainType)}` : ''}`
? `/rulesTest/list?documentType=${encodeURIComponent(detailPack.documentType)}${detailPackFilterMainType ? `&mainType=${encodeURIComponent(detailPackFilterMainType)}` : ''}`
: '/rulesTest/list';
return (
+2 -16
View File
@@ -344,22 +344,8 @@ export function Sidebar({ onToggle, collapsed, userRole, frontendJWT = '' }: Sid
if (isCaseFileModule) {
return {
...item,
children: [
{
id: 'rules-admin-penalty',
title: '行政处罚',
path: buildRulesTestListPath('行政处罚'),
icon: 'ri-list-check-3',
order: 1
},
{
id: 'rules-admin-license',
title: '行政许可',
path: buildRulesTestListPath('行政许可'),
icon: 'ri-list-check-3',
order: 2
}
]
path: buildRulesTestListPath(),
children: undefined
};
}
+2 -1
View File
@@ -518,6 +518,7 @@ export default function RulesTestDetail() {
() => versions.find((item) => ['published', 'rollback'].includes(item.status) && item.id !== pack.currentVersionId),
[versions, pack.currentVersionId],
);
const packFilterMainType = pack.businessType || pack.mainType;
const currentResolvedVersion = useMemo(
() => versions.find((item) => item.id === pack.currentVersionId || item.id === pack.fallbackVersionId) || null,
[pack.currentVersionId, pack.fallbackVersionId, versions],
@@ -719,7 +720,7 @@ export default function RulesTestDetail() {
}
];
const backLink = `/rulesTest/list?documentType=${encodeURIComponent(pack.documentType)}&mainType=${encodeURIComponent(pack.mainType)}&subtype=${encodeURIComponent(pack.subtype)}`;
const backLink = `/rulesTest/list?documentType=${encodeURIComponent(pack.documentType)}&mainType=${encodeURIComponent(packFilterMainType)}&subtype=${encodeURIComponent(pack.subtype)}`;
return (
<div className="rules-test-page rules-page">
+34 -9
View File
@@ -71,6 +71,10 @@ function resolveDocumentScope(pack: Pick<RuleYamlPack, 'documentType' | 'mainTyp
return pack.documentType || pack.mainType || pack.moduleType || '未分类';
}
function resolveBusinessType(pack: Pick<RuleYamlPack, 'businessType' | 'mainType'>): string {
return pack.businessType || pack.mainType || '';
}
function riskColor(risk: string): TagColor {
if (risk === 'high') return 'red';
if (risk === 'medium') return 'orange';
@@ -103,7 +107,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
const documentTypes = unique(packScopes.map(item => item.scope));
const requestedDocumentType = requestedFilters.documentType;
const inferredDocumentType = requestedMainType
? packScopes.find(item => item.pack.mainType === requestedMainType)?.scope || ''
? packScopes.find(item => resolveBusinessType(item.pack) === requestedMainType)?.scope || ''
: '';
const currentDocumentType = documentTypes.includes(requestedDocumentType)
? requestedDocumentType
@@ -114,18 +118,18 @@ export async function loader({ request }: LoaderFunctionArgs) {
const scopedFilters = {
...requestedFilters,
documentType: currentDocumentType,
mainType: scopedDocumentPacks.some(pack => pack.mainType === requestedFilters.mainType)
mainType: scopedDocumentPacks.some(pack => resolveBusinessType(pack) === requestedFilters.mainType)
? requestedFilters.mainType
: '',
subtype: scopedDocumentPacks.some(pack =>
(!requestedFilters.mainType || pack.mainType === requestedFilters.mainType) &&
(!requestedFilters.mainType || resolveBusinessType(pack) === requestedFilters.mainType) &&
pack.subtype === requestedFilters.subtype
)
? requestedFilters.subtype
: ''
};
const scopedByMainTypePacks = scopedDocumentPacks.filter(pack =>
!scopedFilters.mainType || pack.mainType === scopedFilters.mainType
!scopedFilters.mainType || resolveBusinessType(pack) === scopedFilters.mainType
);
const subtypeOptions = unique(scopedByMainTypePacks.map(pack => pack.subtype));
const ruleGroupSourcePacks = scopedFilters.subtype
@@ -141,7 +145,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
ruleGroup: ruleGroupOptions.includes(requestedFilters.ruleGroup) ? requestedFilters.ruleGroup : ''
};
const visiblePacks = scopedDocumentPacks.filter(pack =>
(!filters.mainType || pack.mainType === filters.mainType) &&
(!filters.mainType || resolveBusinessType(pack) === filters.mainType) &&
(!filters.subtype || pack.subtype === filters.subtype)
);
@@ -152,7 +156,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
packId: pack.id,
documentType: pack.documentType,
moduleType: pack.moduleType,
mainType: pack.mainType,
mainType: resolveBusinessType(pack),
subtype: pack.subtype,
yamlName: pack.metadata.name || '待配置 YAML',
yamlStatus: pack.sourceStatus,
@@ -182,7 +186,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
packId: pack.id,
documentType: pack.documentType,
moduleType: pack.moduleType,
mainType: pack.mainType,
mainType: resolveBusinessType(pack),
subtype: pack.subtype,
yamlName: pack.metadata.name,
yamlStatus: pack.sourceStatus
@@ -213,7 +217,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
pageSize: filters.pageSize,
options: {
documentTypes,
mainTypes: unique(scopedDocumentPacks.map(pack => pack.mainType)),
mainTypes: unique(scopedDocumentPacks.map(pack => resolveBusinessType(pack))),
subtypes: subtypeOptions,
ruleGroups: ruleGroupOptions
}
@@ -244,6 +248,16 @@ export default function RulesTestList() {
const handleFilterChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const { name, value } = event.target;
if (name === 'mainType') {
updateParams({
mainType: value,
ruleTypeName: undefined,
subtype: undefined,
documentAttributeType: undefined,
ruleGroup: undefined,
});
return;
}
if (name === 'subtype') {
updateParams({ subtype: value, documentAttributeType: undefined, ruleGroup: undefined });
return;
@@ -257,7 +271,7 @@ export default function RulesTestList() {
const handleReset = () => {
const nextParams = new URLSearchParams(searchParams);
['ruleGroup', 'subtype', 'documentAttributeType', 'keyword', 'page'].forEach(key => nextParams.delete(key));
['mainType', 'ruleTypeName', 'ruleGroup', 'subtype', 'documentAttributeType', 'keyword', 'page'].forEach(key => nextParams.delete(key));
nextParams.set('page', '1');
setSearchParams(nextParams);
};
@@ -362,6 +376,16 @@ export default function RulesTestList() {
</Button>
}
>
<FilterSelect
label="业务类型"
name="mainType"
value={filters.mainType}
options={options.mainTypes.map(mainType => ({ value: mainType, label: mainType }))}
onChange={handleFilterChange}
className="mr-3 w-[18%]"
placeholder="全部"
/>
<FilterSelect
label="子类型"
name="subtype"
@@ -369,6 +393,7 @@ export default function RulesTestList() {
options={options.subtypes.map(subtype => ({ value: subtype, label: subtype }))}
onChange={handleFilterChange}
className="mr-3 w-[18%]"
placeholder={filters.mainType || options.mainTypes.length <= 1 ? '全部' : '请先选择业务类型'}
/>
<FilterSelect
+10
View File
@@ -53,6 +53,14 @@ function getMessage(payload: unknown, fallback: string): string {
}
function mapApiPackToRuleYamlPack(item: RuleConfigPackApi): RuleYamlPack {
const ruleTypeCode = String(item.ruleType || '').trim();
const businessType = (() => {
const segments = ruleTypeCode.split('.').map(segment => segment.trim()).filter(Boolean);
if (segments.length >= 2) {
return segments[1];
}
return item.mainType || item.documentType || '';
})();
const yamlSource = (item.yamlText || '').trim() ? String(item.yamlText) : EMPTY_RULE_YAML;
const sourceStatus = item.sourceStatus || ((item.yamlText || '').trim() ? 'ready' : 'empty');
@@ -64,6 +72,8 @@ function mapApiPackToRuleYamlPack(item: RuleConfigPackApi): RuleYamlPack {
moduleType: item.moduleType || (item.documentType ? `${item.documentType}评查` : '规则配置'),
mainType: item.mainType || item.documentType || '',
subtype: item.subtype || '通用',
businessType,
ruleTypeCode,
},
yamlSource,
sourceStatus,
+2
View File
@@ -7,6 +7,8 @@ export type RulePackScope = {
moduleType: string;
mainType: string;
subtype: string;
businessType?: string;
ruleTypeCode?: string;
};
export type RuleSummary = {