Forráskód Böngészése

feat: 组织结构添加父级+重命名

outaozhen 3 éve
szülő
commit
4781826b2b

+ 82 - 9
src/pages/Institutions/Company/Detail/components/Organization.tsx

@@ -1,15 +1,23 @@
-import { Table } from 'antd'
-import React, { useState, useEffect } from 'react'
+import { Breadcrumb, Button } from 'antd'
+import ProTable from '@ant-design/pro-table'
+import React, { useState, useEffect, useRef } from 'react'
 import { useRequest } from 'umi'
+import { DeleteOutlined } from '@ant-design/icons'
+import { queryOrganizationalStructureList } from '@/services/api/institution'
+import OrganizationModal, { ModalType } from './OrganizationModal'
 
 type OrganizationProps = {
   dataID: string
   structureType: string
 }
 const Organization: React.FC<OrganizationProps> = ({ dataID, structureType }) => {
+  const tRef = useRef<ActionType>(null)
   const [state, setState] = useState({
-    id: '',
-    organizationList: []
+    organizationList: [],
+    visible: false,
+    currentModalType: ModalType.ADD,
+    defaultFormData: null,
+    parentID: '9dddcc99-0c4f-4589-bd47-87e939f8f7c8'
   })
 
   const columns: ColumnType<API.OrganizationalStructureListItem>[] = [
@@ -25,8 +33,29 @@ const Organization: React.FC<OrganizationProps> = ({ dataID, structureType }) =>
     },
     {
       title: '操作',
-      dataIndex: 'operate',
-      key: 'operate'
+      dataIndex: 'operation',
+      key: 'operation',
+      render: (_, record) => (
+        <div className="divide-x divide-bg-gray-400 flex flex-row">
+          <div className="px-2 text-primary cursor-pointer hover:text-hex-967bbd">添加子项</div>
+          <div className="px-2 text-primary cursor-pointer hover:text-hex-967bbd">移动</div>
+          <div
+            className="px-2 text-primary cursor-pointer hover:text-hex-967bbd"
+            onClick={() => {
+              setState({
+                ...state,
+                visible: true,
+                currentModalType: ModalType.UPDATE,
+                defaultFormData: record
+              })
+            }}>
+            重命名
+          </div>
+          <div className="pl-2 text-hex-fd3995 cursor-pointer hover:text-hex-967bbd">
+            <DeleteOutlined />
+          </div>
+        </div>
+      )
     }
   ]
   const { run: tryOrganizationList } = useRequest(
@@ -34,17 +63,61 @@ const Organization: React.FC<OrganizationProps> = ({ dataID, structureType }) =>
     {
       // manual: true,
       onSuccess: result => {
-        setState({ ...state, organizationList: result.data })
+        setState({ ...state, organizationList: result })
       }
     }
   )
+
   useEffect(() => {
     // tryOrganizationList()
   }, [])
   return (
     <div>
-      {/* <span>组织架构</span> */}
-      <Table<API.OrganizationalStructureListItem> columns={columns} />
+      <div className="mb-2">
+        <Breadcrumb>
+          <Breadcrumb.Item>
+            <a href="/institutions/company">单位管理</a>
+          </Breadcrumb.Item>
+          <Breadcrumb.Item>组织架构</Breadcrumb.Item>
+        </Breadcrumb>
+      </div>
+      {state.organizationList && state.organizationList.length ? (
+        <ProTable<API.OrganizationalStructureListItem>
+          rowKey="ID"
+          actionRef={tRef}
+          columns={columns}
+          dataSource={state.organizationList}
+          defaultExpandAllRows={true}
+          search={false}
+          pagination={false}
+          toolbar={{
+            actions: [
+              <Button
+                onClick={() =>
+                  setState({
+                    ...state,
+                    visible: true,
+                    currentModalType: ModalType.ADD,
+                    defaultFormData: {
+                      dataID: dataID,
+                      structureType: structureType,
+                      parentID: state.parentID
+                    }
+                  })
+                }>
+                添加组织
+              </Button>
+            ]
+          }}
+        />
+      ) : null}
+      <OrganizationModal
+        type={state.currentModalType}
+        visible={state.visible}
+        setVisible={(visible: boolean) => setState({ ...state, visible })}
+        reloadTable={() => tRef.current?.reload()}
+        defaultFormData={state.defaultFormData}
+      />
     </div>
   )
 }

+ 92 - 0
src/pages/Institutions/Company/Detail/components/OrganizationModal.tsx

@@ -0,0 +1,92 @@
+import { useRequest } from 'umi'
+import React, { useRef, useEffect } from 'react'
+import { Modal, message } from 'antd'
+import type { FormInstance } from 'antd'
+import ProForm, { ProFormText } from '@ant-design/pro-form'
+import {
+  addOrganizationalStructure,
+  updateOrganizationalStructure
+} from '@/services/api/institution'
+
+export enum ModalType {
+  ADD = 0,
+  UPDATE = 1
+}
+
+type OrganizationModalProps = {
+  visible: boolean
+  setVisible: (visible: boolean) => void
+  type: ModalType
+  reloadTable: () => void
+  defaultFormData?: {
+    structureType: string
+    dataID: string
+    name: string
+    parentID: string
+  }
+}
+const OrganizationModal: React.FC<OrganizationModalProps> = ({
+  visible,
+  type,
+  setVisible,
+  defaultFormData,
+  reloadTable
+}) => {
+  console.log(defaultFormData)
+
+  const ref = useRef<FormInstance>(null)
+  useEffect(() => {
+    defaultFormData && ref.current?.setFieldsValue({ ...defaultFormData })
+  }, [defaultFormData])
+  const { run: tryUpdateOrganization } = useRequest(updateOrganizationalStructure, {
+    manual: true,
+    onSuccess: () => {
+      message.success('更新成功')
+    }
+  })
+  const { run: tryAddOrganization } = useRequest(addOrganizationalStructure, {
+    manual: true,
+    onSuccess: () => {
+      message.success('创建成功')
+    }
+  })
+  const handleOnFinish = () => {
+    ref.current?.validateFields().then(async values => {
+      try {
+        // 执行表单提交
+        if (type === ModalType.ADD) {
+          await tryAddOrganization(values)
+        } else {
+          await tryUpdateOrganization(values)
+        }
+        setVisible(false)
+        reloadTable()
+        ref.current?.resetFields()
+      } catch (error) {
+        message.error(error)
+      }
+    })
+  }
+  return (
+    <Modal
+      width="35vw"
+      visible={visible}
+      title={type === ModalType.ADD ? '添加父级组织' : '重命名'}
+      onCancel={() => {
+        ref.current?.resetFields()
+        setVisible(false)
+      }}
+      onOk={() => handleOnFinish()}>
+      <ProForm formRef={ref} submitter={{ render: false }}>
+        {type === ModalType.UPDATE ? <ProFormText name="ID" hidden /> : null}
+        <ProFormText
+          name="name"
+          label="组织架构名称"
+          rules={[{ required: true, message: '请输入组织架构名称' }]}
+        />
+      </ProForm>
+    </Modal>
+  )
+}
+
+export default OrganizationModal

+ 1 - 1
src/pages/Institutions/Company/Detail/index.tsx

@@ -22,7 +22,7 @@ export enum TabEnum {
 type CompanyDetailProps = RouteComponentProps
 
 const CompanyDetail: React.FC<CompanyDetailProps> = ({ location }) => {
-  const { dataID, structureType } = location.query
+  const { dataID, structureType } = location.state
 
   const menuMap: Record<string, React.ReactNode> = {
     [TabEnum.STAFF]: '人员管理',

+ 6 - 0
src/pages/Institutions/Company/Detail/style.less

@@ -19,10 +19,16 @@
       }
     }
   }
+  :global {
+    .ant-card-body {
+      padding: 0 0 24px;
+    }
+  }
   .right {
     flex: 1;
     padding: 8px 40px;
     .title {
+      display: none;
       margin-bottom: 12px;
       color: @heading-color;
       font-weight: 500;

+ 3 - 3
src/pages/Institutions/Company/List/index.tsx

@@ -2,8 +2,8 @@ import ProTable from '@ant-design/pro-table'
 import type { ProColumnType, ActionType } from '@ant-design/pro-table'
 import { Button } from 'antd'
 import consts from '@/utils/consts'
-import { useRef, useState, useEffect, useCallback, useMemo } from 'react'
-import { connect, history, useModel } from 'umi'
+import { useRef, useState, useEffect } from 'react'
+import { connect, history } from 'umi'
 import type { ConnectProps } from 'umi'
 import type { ProjectModelState } from '../../model'
 import CompanyModal, { ModalType } from '../Detail/components/CompanyModal'
@@ -42,7 +42,7 @@ const CompanyList: React.FC<ListProps> = ({ dispatch, pTypeList }) => {
     // return history.push(`/institutions/company/companyname`)
     return history.push({
       pathname: '/institutions/company/detail',
-      query: params
+      state: params
     })
   }
 

+ 34 - 0
src/services/api/institution.ts

@@ -64,3 +64,37 @@ export async function queryOrganizationalStructureList(
     data: params
   })
 }
+
+/** 新增组织结构 */
+export async function addOrganizationalStructure(params: API.OrganizationalStructureAddParams) {
+  return request('OrganizationalStructure/add', {
+    method: 'POST',
+    data: params
+  })
+}
+
+/** 编辑组织结构 */
+export async function updateOrganizationalStructure(
+  params: API.OrganizationalStructureUpdateParams
+) {
+  return request('/OrganizationalStructure/update', {
+    method: 'POST',
+    data: params
+  })
+}
+
+/** 移动组织结构 */
+export async function moveOrganizationalStructure(params: API.OrganizationalStructureMoveParams) {
+  return request('/OrganizationalStructure/move', {
+    method: 'POST',
+    data: params
+  })
+}
+
+/** 删除组织结构 */
+export async function delOrganizationalStructure(params: API.OrganizationalStructureDelParams) {
+  return request('/OrganizationalStructure/delete', {
+    method: 'POST',
+    data: params
+  })
+}

+ 21 - 0
src/services/api/typings.d.ts

@@ -147,4 +147,25 @@ declare namespace API {
     children: OrganizationalStructureListItem[]
     isLeaf: boolean
   }
+
+  type OrganizationalStructureAddParams = {
+    structureType: string
+    dataID: string
+    name: string
+    parentID: string
+  }
+
+  type OrganizationalStructureUpdateParams = {
+    ID: string
+    name: string
+  }
+
+  type OrganizationalStructureMoveParams = {
+    ID: string
+    moveID: string
+  }
+
+  type OrganizationalStructureDelParams = {
+    ID: string
+  }
 }