Selaa lähdekoodia

feat: 步骤设置抽屉退出前二次提示功能

lanjianrong 2 vuotta sitten
vanhempi
commit
a939407c08

+ 2 - 1
config/config.ts

@@ -23,7 +23,8 @@ export default defineConfig({
   dva: {},
   srcTranspiler: 'esbuild',
   mfsu: {
-    esbuild: true
+    esbuild: true,
+    strategy: 'normal'
   },
   fastRefresh: true,
   unocss: {

+ 8 - 7
src/components/Drawer/index.tsx

@@ -6,15 +6,16 @@ import React, {
   useCallback,
   useState,
   useImperativeHandle,
-  useId
+  useId,
+  isValidElement
 } from 'react'
 import { Drawer, PageHeader } from 'antd'
 import { useModel } from '@umijs/max'
 import type { DrawerProps } from 'antd'
-
-import styles from './index.less'
 import classNames from 'classnames'
 import { isDef } from '@/utils/is'
+import styles from './index.less'
+
 type DrawerHocProps = {
   mode?: 'default' | 'innerEdge'
   beforeOnClose?: () => void
@@ -84,10 +85,10 @@ const DrawerHoc = memo(
       ...reset
     } = drawerProps
 
-    const mergedTitle = useMemo(
-      () => (mode === 'innerEdge' ? <PageHeader title={title} onBack={onClose} /> : title),
-      [mode, title]
-    )
+    const mergedTitle = useMemo(() => {
+      if (isValidElement(title)) return title
+      return mode === 'innerEdge' ? <PageHeader title={title} onBack={onClose} /> : title
+    }, [mode, title])
     const mergedClassName = useMemo(
       () => classNames(className, mode === 'innerEdge' ? styles.pageContainer : null),
       [className, mode]

+ 1 - 0
src/enums/emit.ts

@@ -1,5 +1,6 @@
 export enum EmitterType {
   BUSINESS_STEP_REFRESH = 'refresh:businessStep',
+  STEP_DETAIL_CHANGE = 'change:stepDetail',
   BUSINESS_MATTER_REFRESH = 'refresh:businessMatter',
   MATTER_DETAIL_REFRESH = 'refresh:matterDetail'
 }

+ 1 - 1
src/pages/Business/Condition/components/Designable/ActionsWidget.tsx

@@ -40,7 +40,7 @@ export const ActionsWidget = observer(({ schema }) => {
   }
   return (
     <Space style={{ marginRight: 10 }}>
-      <Button onClick={() => history.replace('/schema/budget')}>
+      <Button onClick={() => history.replace('/business/condition/list')}>
         <TextWidget>返回</TextWidget>
       </Button>
       <Button type="primary" onClick={() => saveSchema(designer)}>

+ 3 - 1
src/pages/Business/Step/components/Flow/components/Drawer/Auditor/index.tsx

@@ -6,6 +6,7 @@ import { useContext, useEffect, useState } from 'react'
 import { FlowContext } from '../../../context'
 import { Edge, isNode } from 'react-flow-renderer'
 import { findNodeById, updateNodeData } from '../../Edge/utils'
+import { EmitterType } from '@/enums/emit'
 
 type AuditorProps = {
   nodeId: string
@@ -20,7 +21,7 @@ const Auditor: React.FC<AuditorProps> = ({ nodeId, nodeData: { name, participant
   const [form] = Form.useForm()
   const [stepMatters, setStepMatters] = useState(participantInfo?.stepMatters || [])
   const {
-    flowStore: { dataID, executorList, process, drawer, elements, matterList },
+    flowStore: { dataID, executorList, process, drawer, elements, matterList, event$ },
     dispatch
   } = useContext(FlowContext)
 
@@ -152,6 +153,7 @@ const Auditor: React.FC<AuditorProps> = ({ nodeId, nodeData: { name, participant
           payload: updateNodeData(process, needUpdatedNodes)
         })
         drawer.close()
+        event$.emit(EmitterType.STEP_DETAIL_CHANGE)
       })
       .catch()
   }

+ 2 - 0
src/pages/Business/Step/components/Flow/components/Drawer/Condition/index.tsx

@@ -1,3 +1,4 @@
+import { EmitterType } from '@/enums/emit'
 import consts from '@/utils/consts'
 import { isString } from '@/utils/is'
 import { FormItem, Editable, Input, Select, Radio, DatePicker, ArrayItems, Space } from '@formily/antd'
@@ -109,6 +110,7 @@ const Condition: React.FC<ConditionProps> = ({ nodeId, nodeData }) => {
           payload: updateNodeData(flowStore.process, needUpdatedNodes)
         })
         flowStore.drawer.close()
+        flowStore.event$.emit(EmitterType.STEP_DETAIL_CHANGE)
       })
     } catch (error) {}
   }

+ 2 - 0
src/pages/Business/Step/components/Flow/components/Edge/BaseEdge.tsx

@@ -8,6 +8,7 @@ import { NodeType } from '@/components/Flow/src/enum'
 import { addNodes } from './utils'
 import { createUid } from '@/utils/util'
 import { ConfigureType } from '@/enums'
+import { EmitterType } from '@/enums/emit'
 export type BaseEdgeProps = Pick<EdgeProps, 'style' | 'markerEnd'> & {
   path: string
   sourceX: number
@@ -94,6 +95,7 @@ export default ({ id, source, target, path, centerY, sourceX, style }: BaseEdgeP
       type: 'set_flow_process',
       payload: addNodes(flowStore.process, source, insertNodes)
     })
+    flowStore.event$.emit(EmitterType.STEP_DETAIL_CHANGE)
     // flowStore.flowInstance?.fitView({ duration: 280 })
   }
 

+ 2 - 0
src/pages/Business/Step/components/Flow/components/Node/BaseNode.tsx

@@ -1,3 +1,4 @@
+import { EmitterType } from '@/enums/emit'
 import { CloseOutlined, RightOutlined } from '@ant-design/icons'
 import classNames from 'classnames'
 import { memo, useContext } from 'react'
@@ -46,6 +47,7 @@ export const BaseNode = memo(({ id, data = {} }: BaseNodeProps) => {
       type: 'set_flow_process',
       payload: updatedProcess
     })
+    flowStore.event$.emit(EmitterType.STEP_DETAIL_CHANGE)
     // flowStore.flowInstance?.fitView({ duration: 80 })
   }
 

+ 2 - 1
src/pages/Business/Step/components/Flow/components/Node/ConditionNode.tsx

@@ -13,6 +13,7 @@ import Condition from '../Drawer/Condition'
 import { prettySchema } from '../Drawer/Condition/schema'
 import { delNode, findNodeById } from '../Edge/utils'
 import consts from '@/utils/consts'
+import { EmitterType } from '@/enums/emit'
 const SchemaField = createSchemaField({
   components: {
     Select,
@@ -60,7 +61,7 @@ export const ConditionNode = connect(({ business }: { business: BusinessModelSta
         type: 'set_flow_process',
         payload: updatedProcess
       })
-      flowStore.flowInstance?.fitView({ duration: 80 })
+      flowStore.event$.emit(EmitterType.STEP_DETAIL_CHANGE)
     }
 
     // 优先级

+ 39 - 3
src/pages/Business/Step/index.tsx

@@ -3,10 +3,11 @@ import { EmitterType } from '@/enums/emit'
 import { queryApprovalDetail } from '@/services/api/project'
 import consts from '@/utils/consts'
 import useEventEmitter from '@/utils/emit'
+import { ArrowLeftOutlined } from '@ant-design/icons'
 import { PageContainer } from '@ant-design/pro-layout'
 import ProTable, { ProColumns } from '@ant-design/pro-table'
 import { connect } from '@umijs/max'
-import { Button } from 'antd'
+import { Button, Modal } from 'antd'
 import { Dispatch, useEffect, useState } from 'react'
 import { BusinessModelState } from '../model'
 import LeftMenu from '../RuleCode/components/LeftMenu'
@@ -39,6 +40,8 @@ type iState = {
   }
   subjectName?: string
 }
+let stepChanged = false
+
 const Step: React.FC<StepProps> = ({ executorMap, matterMap, conditionSchema, dispatch }) => {
   const [drawer, DrawerDOM] = useDrawer()
   const [state, setState] = useState<iState>({
@@ -52,7 +55,8 @@ const Step: React.FC<StepProps> = ({ executorMap, matterMap, conditionSchema, di
       data: { process = [], processList = [] }
     } = await queryApprovalDetail(params)
     if (code === consts.RET_CODE.SUCCESS) {
-      setState({ ...state, process: { detail: process, list: processList, changed: false } })
+      setState({ ...state, process: { detail: process, list: processList } })
+      stepChanged = false
     }
   }
 
@@ -62,6 +66,10 @@ const Step: React.FC<StepProps> = ({ executorMap, matterMap, conditionSchema, di
 
     initData({ gatherID, businessType })
   })
+  event$.useSubscription(EmitterType.STEP_DETAIL_CHANGE, () => {
+    stepChanged = true
+  })
+
   useEffect(() => {
     if (state.activeKey) {
       const [gatherID, businessType] = state.activeKey.split('_')
@@ -110,10 +118,38 @@ const Step: React.FC<StepProps> = ({ executorMap, matterMap, conditionSchema, di
     }
   ]
 
+  const customBackHandler = () => {
+    console.log(stepChanged)
+
+    if (stepChanged) {
+      return Modal.confirm({
+        okText: '确定',
+        title: '温馨提示',
+        cancelText: '取消',
+        content: '当前数据未保存,是否跳转?',
+        onOk() {
+          stepChanged = false
+          drawer.close()
+        }
+      })
+    }
+    drawer.close()
+  }
   const handleBtnClick = () => {
+    const title = (
+      <div className="ant-page-header-heading-left">
+        <div className="ant-page-header-back" onClick={customBackHandler}>
+          <div className="ant-page-header-back-button">
+            <ArrowLeftOutlined />
+          </div>
+        </div>
+        <span>{state.subjectName}</span>
+      </div>
+    )
     drawer.open({
-      title: state.subjectName,
+      title,
       destroyOnClose: true,
+      closeIcon: null,
       children: (
         <ApprovalFlow
           executorList={executorMap[state.activeKey]}