Ver Fonte

修复用户编辑 硬件图片上传等接口传参问题

pm há 5 meses atrás
pai
commit
50c9df98cb

+ 6 - 2
src/api/file.ts

@@ -3,14 +3,18 @@ import axiosInstance from '../utils/axios';
 // 文件上传 API
 export const fileApi = {
   // 上传文件
-  upload: (file: File): Promise<string> => {
+  upload: async (file: File): Promise<string> => {
     const formData = new FormData();
     formData.append('file', file);
-    return axiosInstance.post<string>('/system/file/upload', formData, {
+    // axios 拦截器已经处理了响应格式,会返回 data.data(即 URL 字符串)
+    const response = await axiosInstance.post<string>('/infra/file/upload', formData, {
       headers: {
         'Content-Type': 'multipart/form-data',
       },
     });
+    
+    // 响应拦截器已经处理了 { code: 0, data: "url" } 格式,直接返回 URL 字符串
+    return response as string;
   },
 };
 

+ 3 - 1
src/components/KeyManagement.tsx

@@ -442,7 +442,9 @@ function KeyFormModal({ visible, editingKey, onCancel, onSave }: KeyFormModalPro
     >
       <Form
         form={form}
-        layout="vertical"
+        layout="horizontal"
+        labelCol={{ span: 6 }}
+        wrapperCol={{ span: 18 }}
         className="mt-4"
       >
         <Form.Item

+ 63 - 10
src/components/PadLockManagement.tsx

@@ -209,10 +209,19 @@ export default function PadLockManagement({ subMenu }: PadLockManagementProps) {
   const savePadLock = async (formData: PadLockVO) => {
     try {
       if (editingPadLock?.lockId || editingPadLock?.id) {
-        await padLockApi.updatePadLock({
+        // 编辑模式下,合并原始数据和表单数据,确保所有必要字段都被传递
+        const updateData: PadLockVO = {
+          // 保留原始数据中的字段(这些字段用户不能编辑但需要传递)
+          ...editingPadLock,
+          // 用表单数据覆盖可编辑字段
           ...formData,
+          // 确保 id 和 lockId 都存在
+          id: editingPadLock.id || editingPadLock.lockId,
           lockId: editingPadLock.lockId || editingPadLock.id,
-        });
+        };
+        
+        console.log('提交的挂锁数据:', updateData); // 调试用
+        await padLockApi.updatePadLock(updateData);
         toast.success('修改成功');
       } else {
         await padLockApi.addPadLock(formData);
@@ -296,10 +305,19 @@ export default function PadLockManagement({ subMenu }: PadLockManagementProps) {
   const saveType = async (formData: PadLockTypeVO) => {
     try {
       if (editingType?.lockTypeId || editingType?.id) {
-        await padLockTypeApi.updatePadLockType({
+        // 编辑模式下,合并原始数据和表单数据,确保所有必要字段都被传递
+        const updateData: PadLockTypeVO = {
+          // 保留原始数据中的字段(这些字段用户不能编辑但需要传递)
+          ...editingType,
+          // 用表单数据覆盖可编辑字段
           ...formData,
+          // 确保 id 和 lockTypeId 都存在
+          id: editingType.id || editingType.lockTypeId,
           lockTypeId: editingType.lockTypeId || editingType.id,
-        });
+        };
+        
+        console.log('提交的挂锁类型数据:', updateData); // 调试用
+        await padLockTypeApi.updatePadLockType(updateData);
         toast.success('修改成功');
       } else {
         await padLockTypeApi.addPadLockType(formData);
@@ -614,6 +632,17 @@ export default function PadLockManagement({ subMenu }: PadLockManagementProps) {
               </div>
             </div>
           )}
+
+          {/* 挂锁表单弹窗 */}
+          <PadLockFormModal
+            visible={showPadLockForm}
+            editingPadLock={editingPadLock}
+            onCancel={() => {
+              setShowPadLockForm(false);
+              setEditingPadLock(null);
+            }}
+            onSave={savePadLock}
+          />
         </>
       ) : (
         <>
@@ -782,10 +811,21 @@ function TypeFormModal({ visible, editingType, parentTypeId, typeList, onCancel,
       const values = await form.validateFields();
       setFormLoading(true);
       
-      const submitData: PadLockTypeVO = {
+      // 编辑模式下,合并原始数据和表单数据,确保所有必要字段都被传递
+      const submitData: PadLockTypeVO = editingType ? {
+        // 保留原始数据中的字段(这些字段用户不能编辑但需要传递)
+        ...editingType,
+        // 用表单数据覆盖可编辑字段
+        ...values,
+        // 确保 parentTypeId 存在(如果表单中没有,使用原始数据或默认值 0)
+        parentTypeId: values.parentTypeId !== undefined ? (values.parentTypeId || 0) : (editingType.parentTypeId || 0),
+        // 确保 id 和 lockTypeId 都存在
+        id: editingType.id || editingType.lockTypeId,
+        lockTypeId: editingType.lockTypeId || editingType.id,
+      } : {
+        // 新增模式下,只传递表单数据
         ...values,
         parentTypeId: values.parentTypeId || 0,
-        lockTypeId: editingType?.lockTypeId || editingType?.id,
       };
       
       onSave(submitData);
@@ -809,7 +849,9 @@ function TypeFormModal({ visible, editingType, parentTypeId, typeList, onCancel,
     >
       <Form
         form={form}
-        layout="vertical"
+        layout="horizontal"
+        labelCol={{ span: 6 }}
+        wrapperCol={{ span: 18 }}
         className="mt-4"
       >
         {editingType?.parentTypeId !== 0 && (
@@ -968,9 +1010,18 @@ function PadLockFormModal({ visible, editingPadLock, onCancel, onSave }: PadLock
       const values = await form.validateFields();
       setFormLoading(true);
       
-      const submitData: PadLockVO = {
+      // 编辑模式下,合并原始数据和表单数据,确保所有必要字段都被传递
+      const submitData: PadLockVO = editingPadLock ? {
+        // 保留原始数据中的字段(这些字段用户不能编辑但需要传递)
+        ...editingPadLock,
+        // 用表单数据覆盖可编辑字段
+        ...values,
+        // 确保 id 和 lockId 都存在
+        id: editingPadLock.id || editingPadLock.lockId,
+        lockId: editingPadLock.lockId || editingPadLock.id,
+      } : {
+        // 新增模式下,只传递表单数据
         ...values,
-        lockId: editingPadLock?.lockId || editingPadLock?.id,
       };
       
       onSave(submitData);
@@ -994,7 +1045,9 @@ function PadLockFormModal({ visible, editingPadLock, onCancel, onSave }: PadLock
     >
       <Form
         form={form}
-        layout="vertical"
+        layout="horizontal"
+        labelCol={{ span: 6 }}
+        wrapperCol={{ span: 18 }}
         className="mt-4"
       >
         <Form.Item

+ 20 - 8
src/components/UserManagement.tsx

@@ -395,18 +395,30 @@ export default function UserManagement({ subMenu }: UserManagementProps) {
             </UIButton>
             <Dropdown
               menu={{ items: menuItems }}
-              trigger={['click']}
-              getPopupContainer={(triggerNode) => triggerNode.parentElement || document.body}
+              trigger={['hover']}
+              getPopupContainer={() => document.body}
               placement="bottomRight"
+              popupStyle={{ zIndex: 1050 }}
+              mouseEnterDelay={0.1}
+              mouseLeaveDelay={0.1}
             >
-              <UIButton
-                variant="ghost"
-                size="sm"
-                className="h-8 px-2"
+              <a
+                onClick={(e) => {
+                  e.stopPropagation();
+                }}
+                style={{ 
+                  display: 'inline-flex', 
+                  alignItems: 'center', 
+                  gap: '4px',
+                  padding: '4px 8px',
+                  cursor: 'pointer',
+                  color: 'inherit',
+                  textDecoration: 'none'
+                }}
               >
                 <MoreVertical className="w-4 h-4" />
-                <span className="ml-1">更多</span>
-              </UIButton>
+                <span>更多</span>
+              </a>
             </Dropdown>
           </div>
         );

+ 73 - 2
src/components/user/UserForm.tsx

@@ -27,6 +27,7 @@ const UserForm = forwardRef<UserFormRef, UserFormProps>(({ onSuccess }, ref) =>
   const [deptList, setDeptList] = useState<any[]>([]);
   const [postList, setPostList] = useState<PostVO[]>([]);
   const [sexOptions, setSexOptions] = useState<Array<{ label: string; value: number }>>([]);
+  const [originalUserData, setOriginalUserData] = useState<UserVO | null>(null); // 保存原始用户数据
 
   // 打开弹窗
   const open = async (type: string, id?: number) => {
@@ -76,6 +77,8 @@ const UserForm = forwardRef<UserFormRef, UserFormProps>(({ onSuccess }, ref) =>
       setFormLoading(true);
       try {
         const userData = await userApi.getUser(id);
+        // 保存原始用户数据,以便提交时包含所有字段
+        setOriginalUserData(userData);
         form.setFieldsValue({
           ...userData,
           workstationIds: userData.workstationIds || [],
@@ -88,6 +91,7 @@ const UserForm = forwardRef<UserFormRef, UserFormProps>(({ onSuccess }, ref) =>
       }
     } else {
       // 新增时设置默认值
+      setOriginalUserData(null);
       form.setFieldsValue({
         status: 0,
         workstationIds: [],
@@ -110,7 +114,46 @@ const UserForm = forwardRef<UserFormRef, UserFormProps>(({ onSuccess }, ref) =>
           await userApi.createUser(values as UserVO);
           message.success('创建成功');
         } else {
-          await userApi.updateUser(values as UserVO);
+          // 编辑模式下,合并原始数据和表单数据,确保所有必要字段都被传递
+          const updateData: any = {
+            // 保留原始数据中的字段(这些字段用户不能编辑但需要传递)
+            ...(originalUserData || {}),
+            // 用表单数据覆盖可编辑字段
+            ...values,
+            // 确保 id 存在
+            id: originalUserData?.id || values.id,
+          };
+          
+          // 如果密码为空,则移除密码字段
+          if (!updateData.password || updateData.password.trim() === '') {
+            delete updateData.password;
+          }
+          
+          // 处理字段名映射:workstationIds -> postIds(如果后端需要 postIds)
+          // 如果后端需要 postIds,则使用 workstationIds 的值
+          if (updateData.workstationIds && !updateData.postIds) {
+            updateData.postIds = updateData.workstationIds;
+          }
+          
+          // 确保必要字段存在
+          if (!updateData.avatar && originalUserData?.avatar) {
+            updateData.avatar = originalUserData.avatar;
+          }
+          if (!updateData.createTime && originalUserData?.createTime) {
+            updateData.createTime = originalUserData.createTime;
+          }
+          if (!updateData.loginDate && originalUserData?.loginDate) {
+            updateData.loginDate = originalUserData.loginDate;
+          }
+          if (!updateData.loginIp && originalUserData?.loginIp) {
+            updateData.loginIp = originalUserData.loginIp;
+          }
+          if (updateData.status === undefined && originalUserData?.status !== undefined) {
+            updateData.status = originalUserData.status;
+          }
+          
+          console.log('提交的用户数据:', updateData); // 调试用
+          await userApi.updateUser(updateData as UserVO);
           message.success('更新成功');
         }
         setDialogVisible(false);
@@ -154,7 +197,7 @@ const UserForm = forwardRef<UserFormRef, UserFormProps>(({ onSuccess }, ref) =>
           workstationIds: [],
         }}
       >
-        {formType === 'create' && (
+        {formType === 'create' ? (
           <>
             <Row gutter={16}>
               <Col span={12}>
@@ -177,6 +220,34 @@ const UserForm = forwardRef<UserFormRef, UserFormProps>(({ onSuccess }, ref) =>
               </Col>
             </Row>
           </>
+        ) : (
+          // 编辑模式下,隐藏必要字段以确保提交时包含这些字段
+          <>
+            <Form.Item name="id" hidden>
+              <Input />
+            </Form.Item>
+            <Form.Item name="username" hidden>
+              <Input />
+            </Form.Item>
+            <Form.Item name="password" hidden>
+              <Input.Password />
+            </Form.Item>
+            <Form.Item name="avatar" hidden>
+              <Input />
+            </Form.Item>
+            <Form.Item name="createTime" hidden>
+              <Input />
+            </Form.Item>
+            <Form.Item name="loginDate" hidden>
+              <Input />
+            </Form.Item>
+            <Form.Item name="loginIp" hidden>
+              <Input />
+            </Form.Item>
+            <Form.Item name="status" hidden>
+              <Input />
+            </Form.Item>
+          </>
         )}
 
         <Row gutter={16}>