5 Commits 9b2cd8359c ... 7249c4226d

Author SHA1 Message Date
  yourname 7249c4226d fix(ui): 修复编辑表单照片显示问题 2 days ago
  yourname 72fe1cc0e7 fix(api): 修复文件实体uploadUser关联查询 2 days ago
  yourname 9ef799e7bf 📝 docs(schema): 修正文件导入路径 2 days ago
  yourname c832ac5a08 fix(api): 修复残疾人聚合API文件实体关联查询 2 days ago
  yourname 9db02f7409 fix(tailwind): 修复Tailwind CSS v4配置,确保UI包样式正确生成 2 days ago

+ 35 - 0
allin-packages/disability-module/src/schemas/disabled-person.schema.ts

@@ -1,4 +1,5 @@
 import { z } from '@hono/zod-openapi';
 import { z } from '@hono/zod-openapi';
+import { FileSchema } from '@d8d/file-module/schemas';
 
 
 // 基础字段定义
 // 基础字段定义
 const BaseDisabledPersonSchema = z.object({
 const BaseDisabledPersonSchema = z.object({
@@ -326,6 +327,23 @@ export const DisabledBankCardSchema = z.object({
     description: '银行卡照片文件ID',
     description: '银行卡照片文件ID',
     example: 1
     example: 1
   }),
   }),
+  file: FileSchema.nullable().optional().openapi({
+    description: '银行卡照片文件实体信息',
+    example: {
+      id: 2,
+      name: '银行卡照片.jpg',
+      type: 'image/jpeg',
+      size: 102400,
+      path: '/uploads/2024/01/bank-card.jpg',
+      fullUrl: 'https://minio.example.com/d8dai/uploads/2024/01/bank-card.jpg',
+      description: '银行卡正面照片',
+      uploadUserId: 1,
+      uploadTime: '2024-01-01T10:30:00Z',
+      lastUpdated: null,
+      createdAt: '2024-01-01T10:30:00Z',
+      updatedAt: '2024-01-01T10:30:00Z'
+    }
+  }),
   isDefault: z.number().int().min(0).max(1).default(0).openapi({
   isDefault: z.number().int().min(0).max(1).default(0).openapi({
     description: '是否默认:1-是,0-否',
     description: '是否默认:1-是,0-否',
     example: 1
     example: 1
@@ -350,6 +368,23 @@ export const DisabledPhotoSchema = z.object({
     description: '照片文件ID',
     description: '照片文件ID',
     example: 1
     example: 1
   }),
   }),
+  file: FileSchema.nullable().optional().openapi({
+    description: '文件实体信息',
+    example: {
+      id: 1,
+      name: '身份证照片.jpg',
+      type: 'image/jpeg',
+      size: 102400,
+      path: '/uploads/2024/01/id-photo.jpg',
+      fullUrl: 'https://minio.example.com/d8dai/uploads/2024/01/id-photo.jpg',
+      description: '身份证正面照片',
+      uploadUserId: 1,
+      uploadTime: '2024-01-01T10:30:00Z',
+      lastUpdated: null,
+      createdAt: '2024-01-01T10:30:00Z',
+      updatedAt: '2024-01-01T10:30:00Z'
+    }
+  }),
   uploadTime: z.coerce.date().openapi({
   uploadTime: z.coerce.date().openapi({
     description: '上传时间',
     description: '上传时间',
     example: '2024-01-01T00:00:00Z'
     example: '2024-01-01T00:00:00Z'

+ 2 - 2
allin-packages/disability-module/src/services/aggregated.service.ts

@@ -241,7 +241,7 @@ export class AggregatedService {
     // 检查残疾人是否存在
     // 检查残疾人是否存在
     const existingPerson = await this.personRepository.findOne({
     const existingPerson = await this.personRepository.findOne({
       where: { id: personId },
       where: { id: personId },
-      relations: ['bankCards', 'photos', 'remarks', 'visits']
+      relations: ['bankCards', 'bankCards.file', 'bankCards.file.uploadUser', 'photos', 'photos.file', 'photos.file.uploadUser', 'remarks', 'visits']
     });
     });
 
 
     if (!existingPerson) {
     if (!existingPerson) {
@@ -303,7 +303,7 @@ export class AggregatedService {
     // 获取更新后的完整数据
     // 获取更新后的完整数据
     const updatedPerson = await this.personRepository.findOne({
     const updatedPerson = await this.personRepository.findOne({
       where: { id: personId },
       where: { id: personId },
-      relations: ['bankCards', 'photos', 'remarks', 'visits']
+      relations: ['bankCards', 'bankCards.file', 'bankCards.file.uploadUser', 'photos', 'photos.file', 'photos.file.uploadUser', 'remarks', 'visits']
     });
     });
 
 
     if (!updatedPerson) {
     if (!updatedPerson) {

+ 1 - 1
allin-packages/disability-module/src/services/disabled-person.service.ts

@@ -91,7 +91,7 @@ export class DisabledPersonService extends GenericCrudService<DisabledPerson> {
   async findOne(id: number): Promise<DisabledPerson | null> {
   async findOne(id: number): Promise<DisabledPerson | null> {
     const person = await this.repository.findOne({
     const person = await this.repository.findOne({
       where: { id },
       where: { id },
-      relations: ['bankCards', 'photos', 'photos.file', 'remarks', 'visits']
+      relations: ['bankCards', 'bankCards.file', 'bankCards.file.uploadUser', 'photos', 'photos.file', 'photos.file.uploadUser', 'remarks', 'visits']
     });
     });
 
 
     if (person && person.photos) {
     if (person && person.photos) {

+ 7 - 0
allin-packages/disability-module/tests/integration/disability.integration.test.ts

@@ -792,6 +792,13 @@ describe('残疾人管理API集成测试', () => {
         }
         }
       });
       });
 
 
+      // 调试:打印响应状态和错误信息
+      console.debug('响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorText = await response.text();
+        console.debug('错误响应:', errorText);
+      }
+
       expect(response.status).toBe(200);
       expect(response.status).toBe(200);
 
 
       if (response.status === 200) {
       if (response.status === 200) {

+ 6 - 4
allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx

@@ -409,7 +409,7 @@ const DisabilityPersonManagement: React.FC = () => {
 
 
       {/* 创建/编辑模态框 */}
       {/* 创建/编辑模态框 */}
       <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
       <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
-        <DialogContent className="w-[95vw] max-w-4xl max-h-[80vh] flex flex-col">
+        <DialogContent className="w-[95vw] max-w-4xl max-h-[85vh] flex flex-col overflow-hidden">
           <DialogHeader>
           <DialogHeader>
             <DialogTitle data-testid={isCreateForm ? 'create-disabled-person-dialog-title' : 'edit-disabled-person-dialog-title'}>
             <DialogTitle data-testid={isCreateForm ? 'create-disabled-person-dialog-title' : 'edit-disabled-person-dialog-title'}>
               {isCreateForm ? '新增残疾人' : '编辑残疾人信息'}
               {isCreateForm ? '新增残疾人' : '编辑残疾人信息'}
@@ -418,7 +418,7 @@ const DisabilityPersonManagement: React.FC = () => {
               {isCreateForm ? '填写残疾人基本信息,带*的为必填项' : '修改残疾人信息'}
               {isCreateForm ? '填写残疾人基本信息,带*的为必填项' : '修改残疾人信息'}
             </DialogDescription>
             </DialogDescription>
           </DialogHeader>
           </DialogHeader>
-          <div className="flex-1 overflow-y-auto pr-2 overscroll-contain touch-auto">
+          <div className="flex-1 overflow-y-auto pr-2 overscroll-contain touch-auto py-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100 hover:scrollbar-thumb-gray-400">
             {isCreateForm ? (
             {isCreateForm ? (
               <Form {...createForm}>
               <Form {...createForm}>
                 <form id="create-form" onSubmit={createForm.handleSubmit(onSubmitCreate, (errors) => console.debug('创建表单验证错误:', errors))} className="space-y-4">
                 <form id="create-form" onSubmit={createForm.handleSubmit(onSubmitCreate, (errors) => console.debug('创建表单验证错误:', errors))} className="space-y-4">
@@ -895,14 +895,15 @@ const DisabilityPersonManagement: React.FC = () => {
 
 
       {/* 查看详情模态框 */}
       {/* 查看详情模态框 */}
       <Dialog open={viewDialogOpen} onOpenChange={setViewDialogOpen}>
       <Dialog open={viewDialogOpen} onOpenChange={setViewDialogOpen}>
-        <DialogContent className="max-w-4xl">
+        <DialogContent className="max-w-4xl max-h-[85vh] flex flex-col overflow-hidden">
           <DialogHeader>
           <DialogHeader>
             <DialogTitle>残疾人详情</DialogTitle>
             <DialogTitle>残疾人详情</DialogTitle>
             <DialogDescription>查看残疾人详细信息</DialogDescription>
             <DialogDescription>查看残疾人详细信息</DialogDescription>
           </DialogHeader>
           </DialogHeader>
 
 
           {viewData && (
           {viewData && (
-            <div className="space-y-4">
+            <div className="flex-1 overflow-y-auto pr-2 overscroll-contain touch-auto py-2">
+              <div className="space-y-4">
               <div className="grid grid-cols-2 gap-4">
               <div className="grid grid-cols-2 gap-4">
                 <div>
                 <div>
                   <label className="text-sm font-medium">姓名</label>
                   <label className="text-sm font-medium">姓名</label>
@@ -985,6 +986,7 @@ const DisabilityPersonManagement: React.FC = () => {
                 </div>
                 </div>
               )}
               )}
             </div>
             </div>
+            </div>
           )}
           )}
 
 
           <DialogFooter>
           <DialogFooter>

+ 6 - 1
allin-packages/disability-person-management-ui/src/components/PhotoUploadField.tsx

@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
 import { Button } from '@d8d/shared-ui-components/components/ui/button';
 import { Button } from '@d8d/shared-ui-components/components/ui/button';
 import { Card, CardContent } from '@d8d/shared-ui-components/components/ui/card';
 import { Card, CardContent } from '@d8d/shared-ui-components/components/ui/card';
 import { Label } from '@d8d/shared-ui-components/components/ui/label';
 import { Label } from '@d8d/shared-ui-components/components/ui/label';
@@ -30,6 +30,11 @@ export const PhotoUploadField: React.FC<PhotoUploadFieldProps> = ({
 }) => {
 }) => {
   const [photos, setPhotos] = useState<PhotoItem[]>(value);
   const [photos, setPhotos] = useState<PhotoItem[]>(value);
 
 
+  // 同步外部value变化
+  useEffect(() => {
+    setPhotos(value);
+  }, [value]);
+
   const handleAddPhoto = () => {
   const handleAddPhoto = () => {
     if (photos.length >= maxPhotos) {
     if (photos.length >= maxPhotos) {
       toast.warning(`最多只能上传 ${maxPhotos} 张照片`);
       toast.warning(`最多只能上传 ${maxPhotos} 张照片`);

+ 4 - 0
web/src/style.css

@@ -1,3 +1,7 @@
+/* 配置Tailwind扫描路径,包含UI包 */
+@source "../../allin-packages/**/*.{ts,tsx}";
+@source "../../packages/**/*.{ts,tsx}";
+
 @import "tailwindcss";
 @import "tailwindcss";
 @import "tw-animate-css";
 @import "tw-animate-css";