浏览代码

feat: 对接三维模型上传

bill 3 年之前
父节点
当前提交
4f47ab155e
共有 6 个文件被更改,包括 111 次插入6 次删除
  1. 10 1
      src/api/instance.ts
  2. 27 1
      src/api/setup.ts
  3. 51 0
      src/components/loading/index.tsx
  4. 12 0
      src/components/loading/style.module.scss
  5. 4 3
      src/hook/paging.ts
  6. 7 1
      src/views/scene/content.tsx

+ 10 - 1
src/api/instance.ts

@@ -1,6 +1,7 @@
 import { axiosFactory } from './setup'
 import { message } from 'antd'
 import { LOGIN, ResCodeDesc } from 'constant'
+import { showLoading, hideLoading } from 'components/loading'
 
 const instance = axiosFactory()
 
@@ -14,7 +15,10 @@ export const {
   getToken,
   setToken,
   delToken,
-  setDefaultURI
+  setDefaultURI,
+  addHook,
+  delHook,
+  setHook
 } = instance
 
 addReqErrorHandler(err => {
@@ -32,6 +36,11 @@ addResErrorHandler(
   }
 )
 
+addHook({
+  before: showLoading,
+  after: hideLoading
+})
+
 addUnsetTokenURLS(LOGIN)
 setDefaultURI('/api')
 

+ 27 - 1
src/api/setup.ts

@@ -6,6 +6,10 @@ import type { AxiosResponse, AxiosRequestConfig } from 'axios'
 export type ResErrorHandler = <D, T extends ResData<D>>(response: AxiosResponse<T>, data?: T) => void
 export type ReqErrorHandler = <T>(err: Error, response: AxiosRequestConfig<T>) => void
 export type ResData<T> = { code: ResCode, message: string, data: T }
+export type Hook = {
+  before: (config: AxiosRequestConfig) => void
+  after: (config: AxiosRequestConfig) => void
+}
 
 export const axiosFactory = () => {
   const axiosRaw = Axios.create()
@@ -16,6 +20,8 @@ export const axiosFactory = () => {
     unResErrorSet: [] as string[],
     resErrorHandler: [] as ResErrorHandler[],
     reqErrorHandler: [] as ReqErrorHandler[],
+    unLoadingSet: [] as string[],
+    hook: [] as Hook[]
   }
 
 
@@ -97,6 +103,12 @@ export const axiosFactory = () => {
     del: delUnsetResErrorURLS
   } = getExponseApi('unResErrorSet')
 
+  const {
+    set: setHook,
+    add: addHook,
+    del: delHook
+  } = getExponseApi('hook')
+
   const setDefaultURI = (url: string) => {
     axiosRaw.defaults.baseURL = url
   }
@@ -114,6 +126,10 @@ export const axiosFactory = () => {
 
   axiosRaw.interceptors.request.use(
     config => {
+      for (const hook of axiosConfig.hook) {
+        hook.before(config)
+      }
+
       if (!matchURL(axiosConfig.unTokenSet, config)) {
         if (!axiosConfig.token) {
           if (!matchURL(axiosConfig.unReqErrorSet, config)) {
@@ -134,6 +150,10 @@ export const axiosFactory = () => {
 
   axiosRaw.interceptors.response.use(
     (response: AxiosResponse<ResData<any>>) => {
+      for (const hook of axiosConfig.hook) {
+        hook.after(response.config)
+      }
+
       if (matchURL(axiosConfig.unResErrorSet, response.config)) {
         return response
       }
@@ -152,6 +172,9 @@ export const axiosFactory = () => {
       }
     },
     (err) => {
+      for (const hook of axiosConfig.hook) {
+        hook.after(err.config)
+      }
       if (!matchURL(axiosConfig.unResErrorSet, err.config)) {
         callErrorHandler('res', err.response)
       }
@@ -202,7 +225,10 @@ export const axiosFactory = () => {
     setUnsetResErrorURLS,
     addUnsetResErrorURLS,
     delUnsetResErrorURLS,
-    setDefaultURI
+    setDefaultURI,
+    setHook,
+    addHook,
+    delHook,
   }
 }
 

+ 51 - 0
src/components/loading/index.tsx

@@ -0,0 +1,51 @@
+import { Spin } from 'antd'
+import { LoadingOutlined } from '@ant-design/icons'
+
+import ReactDOM from 'react-dom/client';
+import style from './style.module.scss'
+
+const loadingNode = (
+  <Spin 
+    tip="加载中..." 
+    style={{color: '#fff'}} 
+    indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />}
+  />
+)
+
+const loading = () => {
+  const el = document.createElement('div')
+  const root = ReactDOM.createRoot(el)
+  
+  root.render(loadingNode)
+  
+  el.classList.add(style['loading-layer'])
+  document.body.appendChild(el)
+
+  return () => {
+    if (showLoadCount && --showLoadCount === 0) {
+      root.unmount()
+      document.body.removeChild(el)
+      destory = null
+    }
+  }
+}
+
+let showLoadCount = 0
+let destory: (() => void) | null
+
+export const showLoading = () => {
+  if (showLoadCount === 0) {
+    destory = loading()
+  }
+  showLoadCount++
+  return destory
+}
+
+export const hideLoading = () => destory && destory()
+
+export const asyncLoading = <T extends Promise<any>>(promise: T): T => {
+  const hide = showLoading()
+  promise.then(hide)
+
+  return promise
+}

+ 12 - 0
src/components/loading/style.module.scss

@@ -0,0 +1,12 @@
+.loading-layer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  justify-content: center;
+  z-index: 9999;
+  padding-top: 100px;
+}

+ 4 - 3
src/hook/paging.ts

@@ -18,7 +18,7 @@ export type GetPagingData<T extends any[], R> = (...args: GetPagingDataParams<T>
 export type UsePagingStatesResult<T extends any[], R = [Paging, ...T]> = {
   [key in keyof R]: [R[key], ReturnType<QuickSetState<Dispatch<SetStateAction<R[key]>>>>]
 }
-export type UsePagingResult<T extends any[]> = [...UsePagingStatesResult<T>, () => void]
+export type UsePagingResult<T extends any[], R> = [...UsePagingStatesResult<T>, () => Promise<PagingResult<R>>]
 
 export const usePaging = <T extends any[], R>(
   getData: GetPagingData<T, R>,
@@ -34,6 +34,7 @@ export const usePaging = <T extends any[], R>(
       if (paging.total !== data.total) {
         setPaging(paging => ({ ...paging, total: data.total }))
       }
+      return data
     })
   }
 
@@ -46,7 +47,7 @@ export const usePaging = <T extends any[], R>(
     [paging, quickSetState(setPaging)],
     ...states.map(state => ([state[0], quickSetState(state[1])])),
     refresh
-  ] as unknown as UsePagingResult<T>
+  ] as unknown as UsePagingResult<T, R>
 }
 
 
@@ -54,7 +55,7 @@ export const usePaging = <T extends any[], R>(
 export const useThunkPaging = <T extends ParamsPagingRequest, R, U>(
   initParams: T | PagingRequest<T>,
   asyncThunk: AsyncThunk<PagingResult<R>, PagingRequest<T>, U>
-): UsePagingResult<[T]> => {
+): UsePagingResult<[T], R> => {
   const initPaging: BasePagingRequest = {
     pageNum: initParams.pageNum || 1,
     pageSize: initParams.pageSize || 10

+ 7 - 1
src/views/scene/content.tsx

@@ -3,6 +3,7 @@ import { Table, ActionsButton } from 'components'
 import { getSceneColumns, getSceneActions } from './columns'
 import { useThunkPaging } from 'hook'
 import { SceneHeader } from './header'
+import { confirm } from 'utils'
 import { 
   useSelector, 
   filterScenesSelector,
@@ -30,7 +31,12 @@ export const SceneTabContent = ({type}: {type: SceneType}) => {
       } else if (scene.type === SceneType.SWMX && scene.status !== ModelSceneStatus.RUN) {
         actions.push({ 
           text: '删除', 
-          action: () => dispatch(deleteModelScene(scene.id)), 
+          action: async () => {
+            if (await confirm('确定要删除此数据?')) {
+              await dispatch(deleteModelScene(scene.id)).unwrap()
+              await refresh()
+            }
+          }, 
           bind: { danger: true } 
         })
       }