Kaynağa Gözat

feat: add global feature unavailable feedback for archivelist/bin/output

- Create FeatureNotAvailableFeedback component in src/components/FeatureNotAvailableFeedback.tsx
- Create featureNotAvailableSlice in src/states/featureNotAvailableSlice.ts
- Integrate component in src/app.tsx
- Register reducer in src/states/store.ts
- Add interception logic in src/states/businessFlowMiddlewareLogic.ts
dengdx 6 gün önce
ebeveyn
işleme
a4d9cdfa81

+ 9 - 0
src/app.tsx

@@ -11,6 +11,8 @@ import { lightTheme, darkTheme } from './themes';
 import ProductSelector from './components/ProductSelector';
 import QuotaAlertModal from './pages/security/QuotaAlertModal';
 import AcquisitionTracer from './pages/exam/components/acquisitionTracer';
+import FeatureNotAvailableFeedback from './components/FeatureNotAvailableFeedback';
+import { setFeatureNotAvailableOpen } from './states/featureNotAvailableSlice';
 import { logger } from './log/logger';
 console.log = logger.log;
 console.warn = logger.warn;
@@ -36,6 +38,9 @@ function AppContent({ children }: { children: ReactNode }): JSX.Element {
   const { messages, loading, error, currentLocale } = useAppSelector(
     (state) => state.i18n
   );
+  const isFeatureNotAvailableOpen = useAppSelector(
+    (state) => state.featureNotAvailable.isOpen
+  );
   const [currentTheme, setCurrentTheme] = useState(darkTheme); // 默认使用 light 主题
   const [isI18nReady, setIsI18nReady] = useState(false);
 
@@ -140,6 +145,10 @@ function AppContent({ children }: { children: ReactNode }): JSX.Element {
         >
           <AcquisitionTracer />
           <QuotaAlertModal />
+          <FeatureNotAvailableFeedback
+            open={isFeatureNotAvailableOpen}
+            onClose={() => dispatch(setFeatureNotAvailableOpen(false))}
+          />
           {children}
           {process.env.NODE_ENV === 'development' && <ProductSelector />}
           <div

+ 47 - 0
src/components/FeatureNotAvailableFeedback.tsx

@@ -0,0 +1,47 @@
+import React from 'react';
+import { Modal, Button } from 'antd';
+import { InfoCircleFilled } from '@ant-design/icons';
+
+export interface FeatureNotAvailableFeedbackProps {
+  /** 是否显示组件 */
+  open: boolean;
+  /** 点击"我知道了"按钮的处理函数 */
+  onClose: () => void;
+  /** 自定义标题 */
+  title?: string;
+  /** 自定义提示内容 */
+  message?: string;
+}
+
+const FeatureNotAvailableFeedback: React.FC<
+  FeatureNotAvailableFeedbackProps
+> = ({
+  open,
+  onClose,
+  title = '功能开发中',
+  message = '该功能正在开发中,敬请期待。',
+}) => {
+  return (
+    <Modal
+      title={
+        <span>
+          <InfoCircleFilled style={{ color: '#1890ff', marginRight: 8 }} />
+          {title}
+        </span>
+      }
+      open={open}
+      onCancel={onClose}
+      footer={
+        <Button type="primary" onClick={onClose}>
+          我知道了
+        </Button>
+      }
+      centered
+      closable={false}
+    >
+      <p>{message}</p>
+    </Modal>
+  );
+};
+
+export default FeatureNotAvailableFeedback;

+ 12 - 0
src/states/businessFlowMiddlewareLogic.ts

@@ -2,6 +2,7 @@ import { Middleware, PayloadAction } from '@reduxjs/toolkit';
 import prepare, { unprepare } from '../domain/exam/prepare';
 import { BusinessFlowState, setBusinessFlow } from './BusinessFlowSlice';
 import { setFeedbackOpen } from './exam/largeScreenSlice';
+import { setFeatureNotAvailableOpen } from './featureNotAvailableSlice';
 import { suspendOrCompleteStudy } from '@/API/patient/workActions';
 import { RootState } from './store';
 import { getQuota } from '@/API/security/quotaActions';
@@ -243,6 +244,17 @@ const businessFlowMiddlewareLogic: Middleware =
         return next(action);
       }
     }
+    if (
+      action.payload === 'archivelist' ||
+      action.payload === 'bin' ||
+      action.payload === 'outputlist'
+    ) {
+      console.log(
+        `[businessFlowMiddleware] Feature not available: ${action.payload}`
+      );
+      store.dispatch(setFeatureNotAvailableOpen(true));
+      return;
+    }
 
     if (
       isExitingExam(action.payload, currentKey) &&

+ 22 - 0
src/states/featureNotAvailableSlice.ts

@@ -0,0 +1,22 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+
+interface FeatureNotAvailableState {
+  isOpen: boolean;
+}
+
+const initialState: FeatureNotAvailableState = {
+  isOpen: false,
+};
+
+const featureNotAvailableSlice = createSlice({
+  name: 'featureNotAvailable',
+  initialState,
+  reducers: {
+    setFeatureNotAvailableOpen: (state, action: PayloadAction<boolean>) => {
+      state.isOpen = action.payload;
+    },
+  },
+});
+
+export const { setFeatureNotAvailableOpen } = featureNotAvailableSlice.actions;
+export default featureNotAvailableSlice.reducer;

+ 2 - 0
src/states/store.ts

@@ -57,6 +57,7 @@ import imageSelectionReducer from './patient/DiagnosticReport/imageSelectionSlic
 import diagnosticReportReducer from './patient/DiagnosticReport/slice';
 import permissionReducer from './permissionSlice';
 import i18nReducer from './i18nSlice';
+import featureNotAvailableReducer from './featureNotAvailableSlice';
 
 const store = configureStore({
   reducer: {
@@ -108,6 +109,7 @@ const store = configureStore({
     diagnosticReport: diagnosticReportReducer,
     permission: permissionReducer,
     i18n: i18nReducer,
+    featureNotAvailable: featureNotAvailableReducer,
   },
   middleware: (getDefaultMiddleware) =>
     getDefaultMiddleware().concat(