From 1ebf700cf2f689ee629596439b3477cf37120514 Mon Sep 17 00:00:00 2001 From: tangweijie <877588133@qq.com> Date: Thu, 15 Jan 2026 10:57:50 +0800 Subject: [PATCH] feat(prison): Enhance area and cell management with tree structure and improved forms - Updated AreaApi to support search parameters in getAreaTree method. - Modified CellForm and Cell index views to use tree-select for area selection. - Added areaName to Cell and Prisoner interfaces for better data representation. - Refactored prisoner forms to remove subAreaId and streamline area selection. - Improved image path validation in utility functions. - Enhanced prisoner detail and list views to display area and cell names correctly. - Added loading functionality for area tree data in relevant components. --- src/api/prison/area/index.ts | 10 +-- src/api/prison/cell/index.ts | 1 + src/api/prison/prisoner/index.ts | 3 - src/utils/__tests__/is.test.ts | 9 +- src/utils/is.ts | 8 +- src/views/prison/area/index.vue | 21 ++++- src/views/prison/cell/CellForm.vue | 66 +++++++++++---- src/views/prison/cell/index.vue | 32 +++++-- src/views/prison/prisoner/PrisonerDetail.vue | 4 +- src/views/prison/prisoner/PrisonerForm.vue | 89 +++++--------------- src/views/prison/prisoner/index.vue | 65 ++++++++++---- 11 files changed, 182 insertions(+), 126 deletions(-) diff --git a/src/api/prison/area/index.ts b/src/api/prison/area/index.ts index 6d95e68a..dee8a032 100644 --- a/src/api/prison/area/index.ts +++ b/src/api/prison/area/index.ts @@ -72,8 +72,8 @@ export const AreaApi = { }, // 查询监区树形结构 - getAreaTree: async () => { - return await request.get({ url: `/prison/area/tree` }) + getAreaTree: async (params?: { name?: string; type?: number; level?: number; status?: number }) => { + return await request.get({ url: `/prison/area/tree`, params }) }, // 查询父级监区列表(用于新增/编辑时选择) @@ -106,8 +106,8 @@ export const AreaApi = { return await request.download({ url: `/prison/area/export-excel`, params }) }, - // 同步监区人数 - syncCurrentCount: async (id: number) => { - return await request.put({ url: `/prison/area/sync-count?id=` + id }) + // 同步监区当前人数 + syncCurrentCount: async (areaId: number) => { + return await request.post({ url: `/prison/area/sync-current-count?areaId=` + areaId }) } } \ No newline at end of file diff --git a/src/api/prison/cell/index.ts b/src/api/prison/cell/index.ts index 834e9095..182f2e81 100644 --- a/src/api/prison/cell/index.ts +++ b/src/api/prison/cell/index.ts @@ -5,6 +5,7 @@ import type { Dayjs } from 'dayjs'; export interface Cell { id: number; // 监室ID areaId?: number; // 所属监区ID + areaName?: string; // 所属监区名称 name?: string; // 监室名称 code?: string; // 监室编码 capacity: number; // 床位数量 diff --git a/src/api/prison/prisoner/index.ts b/src/api/prison/prisoner/index.ts index f66365a9..257aeb49 100644 --- a/src/api/prison/prisoner/index.ts +++ b/src/api/prison/prisoner/index.ts @@ -31,8 +31,6 @@ export interface PrisonerVO { riskLevelName?: string // 风险等级名称 prisonAreaId: number prisonAreaName?: string // 监区名称 - subAreaId?: number // 分监区ID - subAreaName?: string // 分监区名称 prisonCellId: number prisonCellName?: string // 监室名称 status: number @@ -71,7 +69,6 @@ export interface PrisonerCreateVO { supervisionLevel: number riskLevel: number prisonAreaId: number - subAreaId?: number // 分监区ID prisonCellId: number photo?: string // 照片URL remark: string diff --git a/src/utils/__tests__/is.test.ts b/src/utils/__tests__/is.test.ts index 5346e58b..59ac5576 100644 --- a/src/utils/__tests__/is.test.ts +++ b/src/utils/__tests__/is.test.ts @@ -1,4 +1,9 @@ import { describe, it, expect } from 'vitest' + +// Mock document for isElement test +const div = { tagName: 'DIV' } +global.document = { createElement: () => div } + import { is, isDef, @@ -27,7 +32,7 @@ describe('is', () => { describe('is()', () => { it('should return true for matching type', () => { expect(is({}, 'Object')).toBe(true) - expect(is([], 'Object')).toBe(true) + expect(is([], 'Array')).toBe(true) expect(is('test', 'String')).toBe(true) expect(is(123, 'Number')).toBe(true) }) @@ -263,7 +268,7 @@ describe('is', () => { expect(isImgPath('https://example.com/image.png')).toBe(true) expect(isImgPath('http://example.com/photo.jpg')).toBe(true) expect(isImgPath('/path/to/image.gif')).toBe(true) - expect(isImgPath('data:image/png;base64,abc123')).toBe(true) + expect(isImgPath('data:image/png;base64,iVBOR')).toBe(true) }) it('should return false for non-image paths', () => { diff --git a/src/utils/is.ts b/src/utils/is.ts index 24d7191f..968e2ca4 100644 --- a/src/utils/is.ts +++ b/src/utils/is.ts @@ -2,7 +2,7 @@ const toString = Object.prototype.toString -export const is = (val: unknown, type: string) => { +export const is = (val: unknown, type: string): boolean => { return toString.call(val) === `[object ${type}]` } @@ -46,7 +46,7 @@ export const isNull = (val: unknown): val is null => { } export const isNullAndUnDef = (val: unknown): val is null | undefined => { - return isUnDef(val) && isNull(val) + return isUnDef(val) || isNull(val) } export const isNullOrUnDef = (val: unknown): val is null | undefined => { @@ -86,7 +86,7 @@ export const isWindow = (val: any): val is Window => { } export const isElement = (val: unknown): val is Element => { - return isObject(val) && !!val.tagName + return isObject(val) && typeof (val as any).tagName === 'string' } export const isMap = (val: unknown): val is Map => { @@ -110,7 +110,7 @@ export const isDark = (): boolean => { // 是否是图片链接 export const isImgPath = (path: string): boolean => { - return /(https?:\/\/|data:image\/).*?\.(png|jpg|jpeg|gif|svg|webp|ico)/gi.test(path) + return /\.(png|jpg|jpeg|gif|svg|webp|ico)(\?.*)?$/i.test(path) || /^data:image\//i.test(path) } export const isEmptyVal = (val: any): boolean => { diff --git a/src/views/prison/area/index.vue b/src/views/prison/area/index.vue index 8f7ed2ca..8a46d47f 100644 --- a/src/views/prison/area/index.vue +++ b/src/views/prison/area/index.vue @@ -294,7 +294,22 @@ const getParentName = (parentId: number) => { return findParent(treeData.value) || '-' } -/** 获取树形数据 */ +/** 获取树形数据(带搜索条件) */ +const getTreeListWithSearch = async () => { + treeLoading.value = true + try { + treeData.value = await AreaApi.getAreaTree({ + name: queryParams.name, + type: queryParams.type, + level: queryParams.level, + status: queryParams.status + }) + } finally { + treeLoading.value = false + } +} + +/** 获取树形数据(默认) */ const getTreeList = async () => { treeLoading.value = true try { @@ -320,11 +335,15 @@ const getList = async () => { const handleQuery = () => { queryParams.pageNo = 1 getList() + // 刷新树形结构(带搜索条件) + getTreeListWithSearch() } /** 重置按钮操作 */ const resetQuery = () => { queryFormRef.value.resetFields() + // 刷新树形结构(使用默认条件,不带搜索参数) + getTreeList() handleQuery() } diff --git a/src/views/prison/cell/CellForm.vue b/src/views/prison/cell/CellForm.vue index 6caa85ff..e021364d 100644 --- a/src/views/prison/cell/CellForm.vue +++ b/src/views/prison/cell/CellForm.vue @@ -7,8 +7,17 @@ label-width="100px" v-loading="formLoading" > - - + + @@ -16,15 +25,18 @@ - - - - - - - - - + + + + + + + + + + + + - +