2
0
Эх сурвалжийг харах

✨ feat(area): 增加街道/乡镇层级支持

- 添加街道/乡镇(层级4)的显示和管理功能
- 调整区域树节点显示逻辑,支持省级、市级和区县级节点展开子节点
- 更新区域名称显示,在区县级下新增"街道/乡镇"选项
- 修改表单验证规则,支持层级4的区域数据处理
- 修复TypeScript类型定义缺失问题,为childNodes添加AreaNode类型注解
yourname 1 сар өмнө
parent
commit
ba14baebe1

+ 2 - 0
packages/area-management-ui-mt/src/components/AreaForm.tsx

@@ -34,6 +34,8 @@ const getLevelDisplayName = (level: number | undefined): string => {
       return '市';
     case AreaLevel.DISTRICT:
       return '区/县';
+    case AreaLevel.TOWN:
+      return '街道/乡镇';
     default:
       return '未知层级';
   }

+ 5 - 2
packages/area-management-ui-mt/src/components/AreaManagement.tsx

@@ -404,12 +404,15 @@ export const AreaManagement: React.FC = () => {
         <DialogContent className="max-w-2xl">
           <DialogHeader>
             <DialogTitle>
-              {parentAreaForChild?.level === 1 ? '新增市' : '新增区'}
+              {parentAreaForChild?.level === 1 ? '新增市' :
+               parentAreaForChild?.level === 2 ? '新增区' : '新增乡镇'}
             </DialogTitle>
             <DialogDescription>
               {parentAreaForChild?.level === 1
                 ? `在省份 "${parentAreaForChild?.name}" 下新增市`
-                : `在城市 "${parentAreaForChild?.name}" 下新增区/县`}
+                : parentAreaForChild?.level === 2
+                ? `在城市 "${parentAreaForChild?.name}" 下新增区/县`
+                : `在区县 "${parentAreaForChild?.name}" 下新增街道/乡镇`}
             </DialogDescription>
           </DialogHeader>
           <AreaForm

+ 6 - 4
packages/area-management-ui-mt/src/components/AreaTreeAsync.tsx

@@ -94,7 +94,7 @@ const SubTreeLoader: React.FC<SubTreeLoaderProps> = ({
 
   return (
     <div>
-      {childNodes.map((node) => (
+      {childNodes.map((node: AreaNode) => (
         <TreeNode
           key={node.id}
           node={node}
@@ -135,7 +135,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
 }) => {
   const isExpanded = expandedNodes.has(node.id);
   const isDisabled = node.isDisabled === 1;
-  const hasChildren = node.level < 3; // 省级和市级节点可能有子节点
+  const hasChildren = node.level < 4; // 省级、市级和区县级节点可能有子节点
 
   return (
     <div key={node.id} className="select-none">
@@ -196,7 +196,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
         {/* 操作按钮 */}
         <div className="flex gap-1 opacity-100 transition-opacity">
           {/* 新增子节点按钮 - 根据层级显示不同文本 */}
-          {node.level < 3 && (
+          {node.level < 4 && (
             <Button
               variant="outline"
               size="sm"
@@ -205,7 +205,8 @@ const TreeNode: React.FC<TreeNodeProps> = ({
                 onAddChild(node);
               }}
             >
-              {node.level === 1 ? '新增市' : '新增区'}
+              {node.level === 1 ? '新增市' :
+               node.level === 2 ? '新增区' : '新增乡镇'}
             </Button>
           )}
           <Button
@@ -294,6 +295,7 @@ const getLevelName = (level: number) => {
     case 1: return '省/直辖市';
     case 2: return '市';
     case 3: return '区/县';
+    case 4: return '街道/乡镇';
     default: return '未知';
   }
 };

+ 7 - 7
packages/geo-areas-mt/src/modules/areas/area.schema.mt.ts

@@ -8,7 +8,7 @@ export const createAreaSchemaMt = z.object({
   parentId: z.number().int().min(0, '父级ID不能为负数').nullable().default(null),
   name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符'),
   level: z.nativeEnum(AreaLevel, {
-    message: '层级必须是1(省/直辖市)、2(市)或3(区/县)'
+    message: '层级必须是1(省/直辖市)、2(市)、3(区/县)或4(街道/乡镇)'
   }),
   code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符'),
   isDisabled: z.nativeEnum(DisabledStatus).default(DisabledStatus.ENABLED),
@@ -22,7 +22,7 @@ export const createAreaSchemaMt = z.object({
   }
   return true;
 }, {
-  message: '层级和父级ID关系不正确:省/直辖市(parentId=null),市/区县(parentId>0)',
+  message: '层级和父级ID关系不正确:省/直辖市(parentId=null),市/区县/乡镇(parentId>0)',
   path: ['parentId'],
 });
 
@@ -32,7 +32,7 @@ export const updateAreaSchemaMt = z.object({
   parentId: z.number().int().min(0, '父级ID不能为负数').nullable().optional(),
   name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符').optional(),
   level: z.nativeEnum(AreaLevel, {
-    message: '层级必须是1(省/直辖市)、2(市)或3(区/县)'
+    message: '层级必须是1(省/直辖市)、2(市)、3(区/县)或4(街道/乡镇)'
   }).optional(),
   code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符').optional(),
   isDisabled: z.nativeEnum(DisabledStatus).optional(),
@@ -49,7 +49,7 @@ export const updateAreaSchemaMt = z.object({
   }
   return true;
 }, {
-  message: '层级和父级ID关系不正确:省/直辖市(parentId=null),市/区县(parentId>0)',
+  message: '层级和父级ID关系不正确:省/直辖市(parentId=null),市/区县/乡镇(parentId>0)',
   path: ['parentId'],
 });
 
@@ -60,7 +60,7 @@ export const getAreaSchemaMt = z.object({
   parentId: z.number().int().min(0, '父级ID不能为负数').nullable(),
   name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符'),
   level: z.nativeEnum(AreaLevel, {
-    message: '层级必须是1(省/直辖市)、2(市)或3(区/县)'
+    message: '层级必须是1(省/直辖市)、2(市)、3(区/县)或4(街道/乡镇)'
   }),
   code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符'),
   isDisabled: z.nativeEnum(DisabledStatus),
@@ -91,7 +91,7 @@ export const areaListResponseSchemaMt = z.object({
   parentId: z.coerce.number().int().min(0, '父级ID不能为负数').nullable(),
   name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符'),
   level: z.nativeEnum(AreaLevel, {
-    message: '层级必须是1(省/直辖市)、2(市)或3(区/县)'
+    message: '层级必须是1(省/直辖市)、2(市)、3(区/县)或4(街道/乡镇)'
   }),
   code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符'),
   isDisabled: z.nativeEnum(DisabledStatus),
@@ -119,7 +119,7 @@ export const toggleAreaStatusSchemaMt = z.object({
 export const getAreasByLevelSchemaMt = z.object({
   tenantId: z.number().int().positive('租户ID必须为正整数'),
   level: z.nativeEnum(AreaLevel, {
-    message: '层级必须是1(省/直辖市)、2(市)或3(区/县)'
+    message: '层级必须是1(省/直辖市)、2(市)、3(区/县)或4(街道/乡镇)'
   }),
 });