shaogen1995 5 місяців тому
батько
коміт
b05fcfaf2d

+ 77 - 0
src/components/Z3upFiles/data.ts

@@ -0,0 +1,77 @@
+import store from '@/store'
+import { baseURL } from '@/utils/http'
+
+// 查看 权限 图片 /视频 、音频
+export const authFilesLookFu = (name: string, url: string) => {
+  let flag = false
+
+  const nameRes = name ? name : ''
+
+  // pdf和txt 直接新窗口打开
+  const arr0: ('.pdf' | '.txt')[] = ['.pdf', '.txt']
+  arr0.forEach(v => {
+    if (nameRes.toLowerCase().endsWith(v)) {
+      if (url) window.open(baseURL + url)
+      flag = true
+    }
+  })
+
+  // 图片使用 antd的图片预览组件
+  const arr1 = ['.png', '.jpg', '.jpeg', '.gif']
+  arr1.forEach(v => {
+    if (nameRes.toLowerCase().endsWith(v)) {
+      if (url)
+        store.dispatch({
+          type: 'layout/lookBigImg',
+          payload: {
+            url: baseURL + url,
+            show: true
+          }
+        })
+
+      flag = true
+    }
+  })
+
+  // 视频和音频 使用自己的封装的组件
+  let type: '' | 'video' | 'audio' = ''
+  const arr2 = ['.mp3', '.wav']
+  arr2.forEach(v => {
+    if (nameRes.toLowerCase().endsWith(v)) {
+      type = 'audio'
+      flag = true
+    }
+  })
+
+  if (nameRes.toLowerCase().endsWith('.mp4')) {
+    type = 'video'
+    flag = true
+  }
+
+  if (type && url)
+    store.dispatch({
+      type: 'layout/lookDom',
+      payload: {
+        src: url,
+        type
+      }
+    })
+
+  // docx xlsx使用插件
+  // const arr3: (".docx" | ".xlsx")[] = [".docx", ".xlsx"];
+  // arr3.forEach((v) => {
+  //   if (nameRes.toLowerCase().endsWith(v)) {
+  //     if (url) {
+  //       noAuth
+  //         ? store.dispatch({
+  //             type: "layout/fileLookUrl",
+  //             payload: { url: baseURL + url, name: v },
+  //           })
+  //         : urlChangeFu(url, false, v, nameRes);
+  //     }
+  //     flag = true;
+  //   }
+  // });
+
+  return flag
+}

+ 72 - 0
src/components/Z3upFiles/index.module.scss

@@ -0,0 +1,72 @@
+.Z3upFiles {
+  position: relative;
+  width: 100%;
+  height: 100%;
+
+  :global {
+
+    .Z3files {
+      width: 500px;
+      // padding-top: 6px;
+
+      .Z3filesRow {
+        display: flex;
+        margin-top: 5px;
+        justify-content: space-between;
+        align-items: center;
+        font-size: 16px;
+        border-bottom: 1px dashed #999;
+        padding-bottom: 5px;
+
+        .Z3files1 {
+          width: calc(100% - 130px);
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+
+        .Z3files2 {
+          display: flex;
+          width: 120px;
+          justify-content: flex-end;
+
+          &>span {
+            cursor: pointer;
+          }
+
+          a {
+            color: black;
+          }
+        }
+      }
+    }
+
+    .fileTit {
+      margin-top: 14px;
+      font-size: 14px;
+      color: rgb(126, 124, 124);
+
+      .noUpThumb {
+        position: relative;
+        overflow: hidden;
+        opacity: 0;
+        transition: top .2s;
+        color: #ff4d4f;
+        top: -10px;
+      }
+
+
+
+      .noUpThumbAc {
+        top: 0;
+        opacity: 1;
+      }
+    }
+
+    .lookNone {
+      position: relative;
+      top: 4px;
+      left: 10px;
+    }
+  }
+}

+ 197 - 0
src/components/Z3upFiles/index.tsx

@@ -0,0 +1,197 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { FileImgListType } from '@/types'
+import { API_upFile } from '@/store/action/layout'
+import { MessageFu } from '@/utils/message'
+import { fileDomInitialFu } from '@/utils/domShow'
+import { forwardRef, useImperativeHandle } from 'react'
+import { Button, Popconfirm } from 'antd'
+import { EyeOutlined, UploadOutlined, CloseOutlined, DownloadOutlined } from '@ant-design/icons'
+import classNames from 'classnames'
+import { baseURL } from '@/utils/http'
+import { authFilesLookFu } from './data'
+
+type Props = {
+  max: number //最多传多少个文件
+  isLook: boolean //是否是查看
+  ref: any //当前自己的ref,给父组件调用
+  fileCheck: boolean
+  dirCode: string //文件的code码
+  myUrl: string
+  fromData?: any
+  lookData: FileImgListType[] //编辑或者 查看 回显
+  accept?: string
+  // result:成果 | list:清单
+  type?: string
+  tips?: string
+  // 文件大小
+  size?: number
+}
+
+function Z3upFiles(
+  {
+    max,
+    isLook,
+    type = 'doc',
+    fileCheck,
+    dirCode,
+    myUrl,
+    fromData,
+    lookData,
+    accept = '*',
+    tips = '最多支持10个附件;单个附件不得超过500M',
+    size
+  }: Props,
+  ref: any
+) {
+  const [fileList, setFileList] = useState<FileImgListType[]>([])
+
+  useEffect(() => {
+    if (lookData && lookData.length > 0) setFileList(lookData)
+  }, [lookData])
+
+  const myInput = useRef<HTMLInputElement>(null)
+
+  // 上传文件
+  const handeUpPhoto = useCallback(
+    async (e: React.ChangeEvent<HTMLInputElement>) => {
+      if (e.target.files) {
+        // 拿到files信息
+        const filesInfo = e.target.files[0]
+
+        // 校验格式
+        if (!filesInfo.name.includes('.zip') && accept !== '*') {
+          e.target.value = ''
+          return MessageFu.warning(`只支持zip格式!`)
+        }
+
+        // 校验大小
+        if (size && filesInfo.size > size * 1024 * 1024) {
+          e.target.value = ''
+          return MessageFu.warning(`最大支持${size}M!`)
+        }
+
+        // 创建FormData对象
+        const fd = new FormData()
+        // 把files添加进FormData对象(‘photo’为后端需要的字段)
+        fd.append('type', type)
+        fd.append('dirCode', dirCode)
+        fd.append('file', filesInfo)
+
+        if (fromData) {
+          for (const k in fromData) {
+            if (fromData[k]) fd.append(k, fromData[k])
+          }
+        }
+
+        e.target.value = ''
+
+        try {
+          const res = await API_upFile(fd, myUrl)
+          if (res.code === 0) {
+            MessageFu.success('上传成功!')
+            setFileList([...fileList, res.data])
+          }
+          fileDomInitialFu()
+        } catch (error) {
+          fileDomInitialFu()
+        }
+      }
+    },
+    [accept, dirCode, fileList, fromData, myUrl, size, type]
+  )
+
+  // 列表删除某一个文件
+  const delImgListFu = useCallback(async (id: number) => {
+    //  待完善 删除
+  }, [])
+
+  // 让父组件调用,拿到 附件信息
+  const filesIdRes = useCallback(() => {
+    return fileList.map(v => v.id)
+  }, [fileList])
+
+  // 可以让父组件调用子组件的方法
+  useImperativeHandle(ref, () => ({
+    filesIdRes
+  }))
+
+  return (
+    <div className={styles.Z3upFiles}>
+      <input
+        id='upInput'
+        type='file'
+        accept={accept}
+        ref={myInput}
+        onChange={e => handeUpPhoto(e)}
+      />
+      <div className='Z3Btn'>
+        {fileList.length < max && !isLook ? (
+          <Button
+            onClick={() => myInput.current?.click()}
+            icon={<UploadOutlined rev={undefined} />}
+          >
+            上传
+          </Button>
+        ) : null}
+
+        <div className='Z3files'>
+          {fileList.map(v => (
+            <div className='Z3filesRow' key={v.id}>
+              <div className='Z3files1' title={v.fileName}>
+                {v.fileName}
+              </div>
+              <div className='Z3files2'>
+                {authFilesLookFu(v.fileName, '') ? (
+                  <>
+                    <EyeOutlined
+                      rev={undefined}
+                      title='查看'
+                      onClick={() => authFilesLookFu(v.fileName, v.filePath)}
+                    />
+                    &emsp;
+                  </>
+                ) : null}
+                <a
+                  title='下载'
+                  href={baseURL + v.filePath}
+                  download={v.fileName}
+                  target='_blank'
+                  rel='noreferrer'
+                >
+                  <DownloadOutlined rev={undefined} />
+                </a>
+                &emsp;
+                <Popconfirm
+                  title='删除后无法恢复,是否删除?'
+                  okText='删除'
+                  cancelText='取消'
+                  onConfirm={() => delImgListFu(v.id)}
+                  okButtonProps={{ loading: false }}
+                >
+                  <CloseOutlined rev={undefined} title='删除' hidden={isLook} />
+                </Popconfirm>
+              </div>
+            </div>
+          ))}
+        </div>
+
+        <div className='fileTit' hidden={isLook}>
+          {tips}
+          <br />
+          <div
+            className={classNames(
+              'noUpThumb',
+              fileList.length <= 0 && fileCheck ? 'noUpThumbAc' : ''
+            )}
+          >
+            请上传视频!
+          </div>
+        </div>
+      </div>
+      {isLook && fileList.length <= 0 ? <div className='lookNone'>(空)</div> : null}
+    </div>
+  )
+}
+
+export default forwardRef(Z3upFiles)

+ 97 - 111
src/components/ZRichText/index.tsx

@@ -1,216 +1,202 @@
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import styles from "./index.module.scss";
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
 
 // 引入编辑器组件
 
 // 安装---npm install braft-editor --save --force
 // npm install braft-utils --save --force
-import { ContentUtils } from "braft-utils";
-import BraftEditor from "braft-editor";
+import { ContentUtils } from 'braft-utils'
+import BraftEditor from 'braft-editor'
 // 引入编辑器样式
-import "braft-editor/dist/index.css";
+import 'braft-editor/dist/index.css'
 
-import classNames from "classnames";
-import { MessageFu } from "@/utils/message";
-import { fileDomInitialFu } from "@/utils/domShow";
-import { baseURL } from "@/utils/http";
+import classNames from 'classnames'
+import { MessageFu } from '@/utils/message'
+import { fileDomInitialFu } from '@/utils/domShow'
+import { baseURL } from '@/utils/http'
 
-import { forwardRef, useImperativeHandle } from "react";
-import { API_upFile } from "@/store/action/layout";
+import { forwardRef, useImperativeHandle } from 'react'
+import { API_upFile } from '@/store/action/layout'
 
 type Props = {
-  check: boolean; //表单校验,为fasle表示不校验
-  dirCode: string; //文件的code码
-  isLook: boolean; //是否是查看进来
-  ref: any; //当前自己的ref,给父组件调用
-  myUrl: string; //上传的api地址
-  full?: boolean;
-};
+  check: boolean //表单校验,为fasle表示不校验
+  dirCode: string //文件的code码
+  isLook: boolean //是否是查看进来
+  ref: any //当前自己的ref,给父组件调用
+  myUrl: string //上传的api地址
+  full?: boolean
+}
 
 function ZRichText({ check, dirCode, isLook, myUrl, full }: Props, ref: any) {
   // 添加 上传 图片的dom
   useEffect(() => {
     setTimeout(() => {
-      const dom = document.querySelector(".bf-controlbar")!;
-      const div = document.createElement("div");
-      div.className = "upImgBox";
+      const dom = document.querySelector('.bf-controlbar')!
+      const div = document.createElement('div')
+      div.className = 'upImgBox'
       // div.title = "上传图片";
-      div.innerHTML = "上传图片/视频";
+      div.innerHTML = '上传图片/视频'
       div.onclick = async () => {
-        myInput.current?.click();
-      };
-      dom.appendChild(div);
-    }, 20);
+        myInput.current?.click()
+      }
+      dom.appendChild(div)
+    }, 20)
 
     // 监听 富文本 的 class 变化,在全屏的时候会 富文本会添加上 fullscreen 的类
     // 修复顶部样式冲突问题
 
-    const editorDom = document.querySelector(".bf-container") as HTMLDivElement;
+    const editorDom = document.querySelector('.bf-container') as HTMLDivElement
 
     const observer = new MutationObserver(() => {
       // console.log("change");
-      const dom = document.querySelector(".layoutRightTop") as HTMLDivElement;
+      const dom = document.querySelector('.layoutRightTop') as HTMLDivElement
 
-      if (editorDom.className.includes("fullscreen")) dom.style.zIndex = "-1";
-      else dom.style.zIndex = "100";
-    });
+      if (editorDom.className.includes('fullscreen')) dom.style.zIndex = '-1'
+      else dom.style.zIndex = '100'
+    })
 
     observer.observe(editorDom, {
-      attributes: true,
-    });
+      attributes: true
+    })
 
     // 销毁监听
     return () => {
-      observer.disconnect();
-    };
-  }, []);
+      observer.disconnect()
+    }
+  }, [])
 
   useEffect(() => {
-    const controlbarDom = document.querySelectorAll(".txtBox .bf-controlbar ");
-    const contentDom = document.querySelectorAll(".txtBox .bf-content ");
+    const controlbarDom = document.querySelectorAll('.txtBox .bf-controlbar ')
+    const contentDom = document.querySelectorAll('.txtBox .bf-content ')
     if (controlbarDom) {
       controlbarDom.forEach((v: any) => {
-        v.style.display = isLook ? "none" : "block";
-      });
+        v.style.display = isLook ? 'none' : 'block'
+      })
       contentDom.forEach((v: any) => {
-        v.style.height = isLook ? "100%" : "";
-      });
+        v.style.height = isLook ? '100%' : ''
+      })
     }
-  }, [isLook]);
+  }, [isLook])
 
   // 编辑器文本
   const [editorValue, setEditorValue] = useState(
     // 初始内容
-    BraftEditor.createEditorState("")
-  );
+    BraftEditor.createEditorState('')
+  )
 
   // 判断 富文本是否为空
   const isTxtFlag = useMemo(() => {
-    const txt: string = editorValue.toHTML();
-    if (
-      txt.replaceAll("<p>", "").replaceAll("</p>", "").replaceAll(" ", "") ===
-      ""
-    ) {
-      return true;
-    } else return false;
-  }, [editorValue]);
+    const txt: string = editorValue.toHTML()
+    if (txt.replaceAll('<p>', '').replaceAll('</p>', '').replaceAll(' ', '') === '') {
+      return true
+    } else return false
+  }, [editorValue])
 
-  const myInput = useRef<HTMLInputElement>(null);
+  const myInput = useRef<HTMLInputElement>(null)
 
   // 上传图片
   const handeUpPhoto = useCallback(
     async (e: React.ChangeEvent<HTMLInputElement>) => {
       if (e.target.files) {
         // 拿到files信息
-        const filesInfo = e.target.files[0];
+        const filesInfo = e.target.files[0]
 
-        let type = ["image/jpeg", "image/png", "video/mp4"];
-        let size = 5;
-        let txt = "图片只支持png、jpg和jpeg格式!";
-        let txt2 = "图片最大支持5M!";
+        let type = ['image/jpeg', 'image/png', 'video/mp4']
+        let size = 5
+        let txt = '图片只支持png、jpg和jpeg格式!'
+        let txt2 = '图片最大支持5M!'
 
-        const isVideoFlag = filesInfo.name.endsWith(".mp4");
+        const isVideoFlag = filesInfo.name.endsWith('.mp4')
 
         // 校验格式
         if (!type.includes(filesInfo.type)) {
-          e.target.value = "";
+          e.target.value = ''
           if (isVideoFlag) {
             // 上传视频
-            size = 500;
-            txt = "视频只支持mp4格式!";
-            txt2 = "视频最大支持500M!";
+            size = 500
+            txt = '视频只支持mp4格式!'
+            txt2 = '视频最大支持500M!'
           }
 
-          return MessageFu.warning(txt);
+          return MessageFu.warning(txt)
         }
         // 校验大小
         if (filesInfo.size > size * 1024 * 1024) {
-          e.target.value = "";
-          return MessageFu.warning(txt2);
+          e.target.value = ''
+          return MessageFu.warning(txt2)
         }
         // 创建FormData对象
-        const fd = new FormData();
+        const fd = new FormData()
         // 把files添加进FormData对象(‘photo’为后端需要的字段)
-        fd.append("type", isVideoFlag ? "video" : "img");
-        fd.append("dirCode", dirCode);
-        fd.append("file", filesInfo);
+        fd.append('type', isVideoFlag ? 'video' : 'img')
+        fd.append('dirCode', dirCode)
+        fd.append('file', filesInfo)
 
-        e.target.value = "";
+        e.target.value = ''
 
         try {
-          const res = await API_upFile(fd, myUrl);
+          const res = await API_upFile(fd, myUrl)
           if (res.code === 0) {
-            MessageFu.success("上传成功!");
+            MessageFu.success('上传成功!')
             // 在光标位置插入图片
             const newTxt = ContentUtils.insertMedias(editorValue, [
               {
-                type: "IMAGE",
-                url: baseURL + res.data.filePath,
-              },
-            ]);
+                type: 'IMAGE',
+                url: baseURL + res.data.filePath
+              }
+            ])
 
-            setEditorValue(newTxt);
+            setEditorValue(newTxt)
           }
-          fileDomInitialFu();
+          fileDomInitialFu()
         } catch (error) {
-          fileDomInitialFu();
+          fileDomInitialFu()
         }
       }
     },
     [dirCode, editorValue, myUrl]
-  );
+  )
 
   // 让父组件调用的 回显 富文本
   const ritxtShowFu = useCallback((val: string) => {
-    setEditorValue(BraftEditor.createEditorState(val));
-  }, []);
+    setEditorValue(BraftEditor.createEditorState(val))
+  }, [])
 
   // 让父组件调用的返回 富文本信息 和 表单校验 isTxtFlag为ture表示未通过校验
   const fatherBtnOkFu = useCallback(() => {
-    return { val: editorValue.toHTML(), flag: isTxtFlag };
-  }, [editorValue, isTxtFlag]);
+    return { val: editorValue.toHTML(), flag: isTxtFlag }
+  }, [editorValue, isTxtFlag])
 
   // 可以让父组件调用子组件的方法
   useImperativeHandle(ref, () => ({
     ritxtShowFu,
-    fatherBtnOkFu,
-  }));
+    fatherBtnOkFu
+  }))
 
   return (
-    <div className={styles.ZRichText} style={{ width: full ? "100%" : "" }}>
+    <div className={styles.ZRichText} style={{ width: full ? '100%' : '' }}>
       <input
-        id="upInput"
-        type="file"
-        accept=".png,.jpg,.jpeg,.mp4"
+        id='upInput'
+        type='file'
+        accept='.png,.jpg,.jpeg,.mp4'
         ref={myInput}
-        onChange={(e) => handeUpPhoto(e)}
+        onChange={e => handeUpPhoto(e)}
       />
 
-      <div className="txtBox">
+      <div className='txtBox'>
         <BraftEditor
           readOnly={isLook}
-          placeholder="请输入内容"
+          placeholder='请输入内容'
           value={editorValue}
-          onChange={(e) => setEditorValue(e)}
-          imageControls={["remove"]}
+          onChange={e => setEditorValue(e)}
+          imageControls={['remove']}
         />
       </div>
-      <div
-        className={classNames(
-          "noUpThumb",
-          check && isTxtFlag ? "noUpThumbAc" : ""
-        )}
-      >
+      <div className={classNames('noUpThumb', check && isTxtFlag ? 'noUpThumbAc' : '')}>
         请输入正文!
       </div>
     </div>
-  );
+  )
 }
 
-export default forwardRef(ZRichText);
+export default forwardRef(ZRichText)

+ 65 - 0
src/pages/B_enterTibet/B3_4page/B3add/B3aTop/index.module.scss

@@ -0,0 +1,65 @@
+.B3aTop {
+  width: 100%;
+  height: calc(100% - 70px);
+  overflow-y: auto;
+  :global {
+    .B3aTit {
+      font-size: 18px;
+      font-weight: 700;
+      padding-bottom: 10px;
+      padding-left: 18px;
+      border-bottom: 1px solid #ccc;
+      margin-bottom: 17px;
+      .ant-btn {
+        margin-left: 15px;
+        pointer-events: none;
+      }
+    }
+    .B3aRow {
+      display: flex;
+      justify-content: space-between;
+      align-items: self-start;
+      font-size: 16px;
+      flex-wrap: wrap;
+      overflow: hidden;
+      .B3aR1 {
+        width: 48%;
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        .B3aRll {
+          width: 100px;
+          text-align: right;
+          font-weight: 700;
+          & > span {
+            color: #ff4d4f;
+          }
+        }
+        .B3aRrr {
+          width: calc(100% - 100px);
+          .ant-input-affix-wrapper {
+            width: 300px;
+          }
+        }
+      }
+      .B3aR2 {
+        align-items: self-start;
+        .B3aRll {
+          position: relative;
+          top: 3px;
+        }
+      }
+
+      .B3aFull {
+        width: 100%;
+        margin-top: -20px;
+        align-items: self-start;
+        margin-bottom: 0;
+        .B3aRll {
+          position: relative;
+          top: 3px;
+        }
+      }
+    }
+  }
+}

+ 118 - 0
src/pages/B_enterTibet/B3_4page/B3add/B3aTop/index.tsx

@@ -0,0 +1,118 @@
+import { useCallback, useRef } from 'react'
+import styles from './index.module.scss'
+import { Button, DatePicker, Input } from 'antd'
+import dayjs from 'dayjs'
+import { B3aForm1 } from '../data'
+import Z3upFiles from '@/components/Z3upFiles'
+import ZRichTexts from '@/components/ZRichTexts'
+import { forwardRef, useImperativeHandle } from 'react'
+import { TypeB3PageSta } from '../../type'
+
+type Props = {
+  info: any
+  pageSta: TypeB3PageSta
+  ref: any //当前自己的ref,给父组件调用
+  Dom?: React.ReactNode
+}
+
+function B3aTop({ info, pageSta, Dom }: Props, ref: any) {
+  const timeChange = useCallback((e: any) => {
+    console.log(123, e)
+  }, [])
+
+  // 上传附件的ref
+  const filesRef = useRef<any>(null)
+  // const filesRes = filesRef.current.filesIdRes();
+
+  // 富文本的ref
+  const ZRichTextRef = useRef<any>(null)
+
+  // 设置富文本
+  //  ZRichTextRef.current?.ritxtShowFu(JSON.parse(data.rtf))
+  // 富文本校验不通过
+  // const rtf = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
+  // rtf: JSON.stringify(rtf.val || ''),
+
+  // 可以让父组件调用子组件的方法
+
+  const resData = useCallback(() => {
+    return { xxx: 'xxxx' }
+  }, [])
+
+  useImperativeHandle(ref, () => ({
+    resData
+  }))
+
+  return (
+    <div className={styles.B3aTop} id='B3aTop'>
+      <div className='B3aTit'>申请信息{pageSta !== '新增' ? <Button>草稿</Button> : null}</div>
+
+      <div className='B3aRow'>
+        <div className='B3aR1'>
+          <div className='B3aRll'>
+            <span> * </span>申请名称:
+          </div>
+          <div className='B3aRrr'>
+            <Input placeholder='请输入内容' maxLength={30} showCount />
+          </div>
+        </div>
+        <div className='B3aR1'>
+          <div className='B3aRll'>
+            <span> * </span>业务日期:
+          </div>
+          <div className='B3aRrr'>
+            <DatePicker allowClear={false} value={dayjs()} onChange={timeChange} />
+          </div>
+        </div>
+
+        {B3aForm1.map(v => (
+          <div className='B3aR1' key={v.name}>
+            <div className='B3aRll'>{v.name}:</div>
+            <div className='B3aRrr'>这是一段文本</div>
+          </div>
+        ))}
+
+        <div className='B3aR1 B3aR2'>
+          <div className='B3aRll'>附件:</div>
+          <div className='B3aRrr'>
+            <Z3upFiles
+              max={10}
+              isLook={['查看', '审批'].includes(pageSta)}
+              ref={filesRef}
+              fileCheck={false}
+              dirCode={'xxxxxxx'}
+              myUrl='xxxxxxxxxxxx'
+              lookData={[]}
+              size={500}
+            />
+          </div>
+        </div>
+
+        <div className='B3aR1'>
+          <div className='B3aRll'>原因事由:</div>
+          <div className='B3aRrr'>
+            <Input placeholder='请输入内容' maxLength={30} showCount />
+          </div>
+        </div>
+
+        <div className='B3aR1 B3aFull'>
+          <div className='B3aRll'>备注:</div>
+          <div className='B3aRrr'>
+            <ZRichTexts
+              check={false}
+              dirCode={'xxxxxxxx'}
+              isLook={['查看', '审批'].includes(pageSta)}
+              ref={ZRichTextRef}
+              myUrl='xxxxxxxxxx'
+              isOne={true}
+              upAudioBtnNone={true}
+            />
+          </div>
+        </div>
+      </div>
+      {Dom ? Dom : null}
+    </div>
+  )
+}
+
+export default forwardRef(B3aTop)

+ 6 - 0
src/pages/B_enterTibet/B3_4page/B3add/data.ts

@@ -0,0 +1,6 @@
+export const B3aForm1 = [
+  { name: '业务名称', key: '' },
+  { name: '发起人', key: '' },
+  { name: '发起部门', key: '' },
+  { name: '业务单号', key: '' }
+]

+ 17 - 0
src/pages/B_enterTibet/B3_4page/B3add/index.module.scss

@@ -0,0 +1,17 @@
+.B3add {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 15px 24px 0px;
+  position: relative;
+
+  :global {
+    .B3aBtn {
+      position: absolute;
+      bottom: 20px;
+      left: 124px;
+      .ant-btn {
+        margin-right: 20px;
+      }
+    }
+  }
+}

+ 67 - 0
src/pages/B_enterTibet/B3_4page/B3add/index.tsx

@@ -0,0 +1,67 @@
+import React, { useCallback, useRef } from 'react'
+import styles from './index.module.scss'
+import { useParams } from 'react-router-dom'
+import { Button } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import history from '@/utils/history'
+import { MessageFu } from '@/utils/message'
+import B3aTop from './B3aTop'
+
+const objUrl = {
+  1: '/entering_edit',
+  2: '/enterTibet_edit',
+  3: '/register_edit'
+}
+
+function B3add() {
+  const { key } = useParams<any>()
+
+  // 待完善,各种功能
+
+  // 点击下方按钮
+  const btnClickFu = useCallback(
+    (val: number) => {
+      // 从顶部组件中拿到数据
+      const resData = topRef.current?.resData()
+      console.log('从子组件获取数据', resData)
+
+      if (val === 2) {
+        // 存草稿 当前页保存 不跳转
+        MessageFu.success('草稿保存成功')
+      } else {
+        const url = Reflect.get(objUrl, key)
+        history.push(`${url}/${key}/${99}`)
+      }
+    },
+    [key]
+  )
+
+  // 点击按钮调用子组件的方法获取数据
+  const topRef = useRef<any>(null)
+
+  return (
+    <div className={styles.B3add}>
+      <div className='pageTitle'>
+        藏品{key === '1' ? '入馆' : key === '2' ? '入藏' : '登记'}-新增
+      </div>
+      <B3aTop info='xx' pageSta='新增' ref={topRef} />
+      {/* 底部按钮 */}
+      <div className='B3aBtn'>
+        <Button type='primary' onClick={() => btnClickFu(1)}>
+          添加藏品
+        </Button>
+        <Button type='primary' onClick={() => btnClickFu(1)}>
+          创建
+        </Button>
+        <Button type='primary' onClick={() => btnClickFu(2)}>
+          存草稿
+        </Button>
+        <MyPopconfirm txtK='取消' onConfirm={() => history.go(-1)} />
+      </div>
+    </div>
+  )
+}
+
+const MemoB3add = React.memo(B3add)
+
+export default MemoB3add

+ 9 - 0
src/pages/B_enterTibet/B3_4page/B3edit/audit.tsx

@@ -0,0 +1,9 @@
+import React from 'react'
+import B3editMain from './main'
+function audit() {
+  return <B3editMain pageSta='审批' />
+}
+
+const MemoBaudit = React.memo(audit)
+
+export default MemoBaudit

+ 36 - 0
src/pages/B_enterTibet/B3_4page/B3edit/index.module.scss

@@ -0,0 +1,36 @@
+.B3editMain {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 15px 24px 0px;
+  :global {
+    // #B3aTop {
+    //   height: 100%;
+    //   padding-bottom: 30px;
+    // }
+    .ant-table-cell {
+      padding: 8px !important;
+    }
+    .B3eGoodTab {
+      padding-right: 20px;
+      .B3eGtop {
+        display: flex;
+        justify-content: space-between;
+        padding-bottom: 10px;
+        margin-bottom: 17px;
+        .B3eGtop1 {
+          font-size: 18px;
+          font-weight: 700;
+          padding-left: 18px;
+        }
+      }
+    }
+    .B3eBtn {
+      position: absolute;
+      bottom: 20px;
+      left: 124px;
+      .ant-btn {
+        margin-right: 20px;
+      }
+    }
+  }
+}

+ 9 - 0
src/pages/B_enterTibet/B3_4page/B3edit/index.tsx

@@ -0,0 +1,9 @@
+import React from 'react'
+import B3editMain from './main'
+function B3edit() {
+  return <B3editMain pageSta='编辑' />
+}
+
+const MemoB3edit = React.memo(B3edit)
+
+export default MemoB3edit

+ 9 - 0
src/pages/B_enterTibet/B3_4page/B3edit/look.tsx

@@ -0,0 +1,9 @@
+import React from 'react'
+import B3editMain from './main'
+function look() {
+  return <B3editMain pageSta='审批' />
+}
+
+const MemoBlook = React.memo(look)
+
+export default MemoBlook

+ 105 - 0
src/pages/B_enterTibet/B3_4page/B3edit/main.tsx

@@ -0,0 +1,105 @@
+import React, { useCallback, useMemo, useRef } from 'react'
+import styles from './index.module.scss'
+import { useParams } from 'react-router-dom'
+import B3aTop from '../B3add/B3aTop'
+import { TypeB3PageSta } from '../type'
+import { Button } from 'antd'
+import MyTable from '@/components/MyTable'
+import { B3eTableC } from '@/utils/tableData'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import history from '@/utils/history'
+
+type Props = {
+  pageSta: TypeB3PageSta
+}
+
+function B3editMain({ pageSta }: Props) {
+  const { key, id } = useParams<any>()
+
+  // 点击按钮调用子组件的方法获取数据
+  const topRef = useRef<any>(null)
+
+  // 点击删除
+  const delTableFu = useCallback(async (id: number) => {}, [])
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: any) => {
+          return (
+            <>
+              <Button size='small' type='text'>
+                查看
+              </Button>
+              <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+            </>
+          )
+        }
+      }
+    ]
+  }, [delTableFu])
+
+  // 点击保存
+  const btnOk = useCallback(async () => {
+    // 从顶部组件中拿到数据
+    // const resData = topRef.current?.resData()
+  }, [])
+
+  // 点击取消
+  const btnX = useCallback(() => {
+    let url = '/entering'
+    if (key === '2') url = '/enterTibet'
+    else if (key === '3') url = '/register'
+    history.push(url)
+  }, [key])
+
+  return (
+    <div className={styles.B3editMain}>
+      <div className='pageTitle'>
+        藏品{key === '1' ? '入馆' : key === '2' ? '入藏' : '登记'}-{pageSta}
+        {id}
+      </div>
+
+      <B3aTop
+        info='xx'
+        pageSta={pageSta}
+        ref={topRef}
+        Dom={
+          <>
+            {/* 藏品清单 */}
+            <div className='B3eGoodTab'>
+              <div className='B3eGtop'>
+                <div className='B3eGtop1'>藏品清单</div>
+                <div>
+                  <Button type='primary'>从已鉴定的藏品中新增</Button>&emsp;
+                  <Button type='primary'>新增</Button>
+                </div>
+              </div>
+              {/* 表格 */}
+              <MyTable
+                list={[{ id: 1, thumb: '' }]}
+                columnsTemp={B3eTableC}
+                lastBtn={tableLastBtn}
+                pagingInfo={false}
+              />
+            </div>
+          </>
+        }
+      />
+
+      {/* 底部按钮 */}
+      <div className='B3eBtn'>
+        <Button type='primary' onClick={btnOk}>
+          保存
+        </Button>
+
+        <MyPopconfirm txtK='取消' onConfirm={() => btnX()} />
+      </div>
+    </div>
+  )
+}
+
+const MemoB3editMain = React.memo(B3editMain)
+
+export default MemoB3editMain

+ 37 - 7
src/pages/B_enterTibet/B3_4page/index.tsx

@@ -1,7 +1,7 @@
 import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import styles from './index.module.scss'
 import { Button, DatePicker, Input, Select } from 'antd'
-import { TypeB3Form } from './type'
+import { TypeB3Form, TypeB3PageSta } from './type'
 import { useDispatch, useSelector } from 'react-redux'
 import { Z5_APIgetList } from '@/store/action/Z5role'
 import { RootState } from '@/store'
@@ -9,10 +9,17 @@ import dayjs from 'dayjs'
 import MyTable from '@/components/MyTable'
 import MyPopconfirm from '@/components/MyPopconfirm'
 import { B3tableC } from '@/utils/tableData'
+import history from '@/utils/history'
 const { RangePicker } = DatePicker
 
 type InputKeyType = 'aaaa' | 'bbbb' | 'cccc' | 'dddd'
 
+const objUrl = {
+  入馆: '/entering_',
+  入藏: '/enterTibet_',
+  登记: '/register_'
+}
+
 export const B3_4inputKeyArr: {
   name: string
   key: InputKeyType
@@ -37,7 +44,7 @@ const baseFormData: TypeB3Form = {
 }
 
 type Props = {
-  pageSta: '入馆' | '入藏'
+  pageSta: '入馆' | '入藏' | '登记'
 }
 
 // 没有接入后端 待完善
@@ -136,6 +143,26 @@ function B34page({ pageSta }: Props) {
     [getListFu]
   )
 
+  // 点击各种操作按钮
+  const btnFu = useCallback(
+    (val: TypeB3PageSta, id: number) => {
+      const url = Reflect.get(objUrl, pageSta)
+
+      const key = pageSta === '入馆' ? '1' : pageSta === '入藏' ? '2' : '3'
+
+      if (val === '新增') {
+        history.push(`${url}add/${key}`)
+      } else if (val === '编辑') {
+        history.push(`${url}edit/${key}/${id}`)
+      } else if (val === '审批') {
+        history.push(`${url}audit/${key}/${id}`)
+      } else {
+        history.push(`${url}look/${key}/${id}`)
+      }
+    },
+    [pageSta]
+  )
+
   const tableLastBtn = useMemo(() => {
     return [
       {
@@ -143,13 +170,13 @@ function B34page({ pageSta }: Props) {
         render: (item: any) => {
           return (
             <>
-              <Button size='small' type='text'>
+              <Button size='small' type='text' onClick={() => btnFu('编辑', item.id)}>
                 编辑
               </Button>
-              <Button size='small' type='text'>
+              <Button size='small' type='text' onClick={() => btnFu('审批', item.id)}>
                 审批
               </Button>
-              <Button size='small' type='text'>
+              <Button size='small' type='text' onClick={() => btnFu('查看', item.id)}>
                 查看
               </Button>
               <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
@@ -158,7 +185,7 @@ function B34page({ pageSta }: Props) {
         }
       }
     ]
-  }, [delTableFu])
+  }, [btnFu, delTableFu])
 
   return (
     <div className={styles.B34page}>
@@ -179,7 +206,10 @@ function B34page({ pageSta }: Props) {
           ))}
         </div>
         <div className='B3toprr'>
-          <Button type='primary'>批量导出</Button>&emsp;<Button type='primary'>新增</Button>
+          <Button type='primary'>批量导出</Button>&emsp;
+          <Button type='primary' onClick={() => btnFu('新增', 0)}>
+            新增
+          </Button>
         </div>
       </div>
       <div className='B3top'>

+ 2 - 0
src/pages/B_enterTibet/B3_4page/type.d.ts

@@ -10,3 +10,5 @@ export type TypeB3Form = {
   eeee: string
   ffff: string
 }
+
+export type TypeB3PageSta = '新增' | '编辑' | '查看' | '审批'

+ 0 - 4
src/pages/C_goodsManage/C5register/index.module.scss

@@ -1,4 +0,0 @@
-.C4import {
-  :global {
-  }
-}

+ 2 - 7
src/pages/C_goodsManage/C5register/index.tsx

@@ -1,12 +1,7 @@
+import B34page from '@/pages/B_enterTibet/B3_4page'
 import React from 'react'
-import styles from './index.module.scss'
 function C5register() {
-  return (
-    <div className={styles.C5register}>
-      <div className='pageTitle'>藏品登记</div>
-      <p>待开发</p>
-    </div>
-  )
+  return <B34page pageSta='登记' />
 }
 
 const MemoC5register = React.memo(C5register)

+ 128 - 54
src/pages/Layout/data.ts

@@ -56,60 +56,60 @@ const tabLeftArr: RouterType = [
       }
     ]
   },
-  // {
-  //   id: 3,
-  //   name: '藏品管理',
-  //   son: [
-  //     {
-  //       id: 310,
-  //       name: '藏品总账',
-  //       path: '/ledger',
-  //       Com: React.lazy(() => import('../C_goodsManage/C1ledger'))
-  //     },
-  //     {
-  //       id: 320,
-  //       name: '藏品附件',
-  //       path: '/files',
-  //       Com: React.lazy(() => import('../C_goodsManage/C2files'))
-  //     },
-  //     {
-  //       id: 330,
-  //       name: '藏品关注',
-  //       path: '/focus',
-  //       Com: React.lazy(() => import('../C_goodsManage/C3focus'))
-  //     },
-  //     {
-  //       id: 340,
-  //       name: '藏品导入',
-  //       path: '/import',
-  //       Com: React.lazy(() => import('../C_goodsManage/C4import'))
-  //     },
-  //     {
-  //       id: 350,
-  //       name: '藏品登记',
-  //       path: '/register',
-  //       Com: React.lazy(() => import('../C_goodsManage/C5register'))
-  //     },
-  //     {
-  //       id: 360,
-  //       name: '藏品编辑',
-  //       path: '/edit',
-  //       Com: React.lazy(() => import('../C_goodsManage/C6edit'))
-  //     },
-  //     {
-  //       id: 370,
-  //       name: '藏品删除',
-  //       path: '/delete',
-  //       Com: React.lazy(() => import('../C_goodsManage/C7delete'))
-  //     },
-  //     {
-  //       id: 380,
-  //       name: '回收站',
-  //       path: '/recycleBin',
-  //       Com: React.lazy(() => import('../C_goodsManage/C8recycleBin'))
-  //     }
-  //   ]
-  // },
+  {
+    id: 3,
+    name: '藏品管理',
+    son: [
+      // {
+      //   id: 310,
+      //   name: '藏品总账',
+      //   path: '/ledger',
+      //   Com: React.lazy(() => import('../C_goodsManage/C1ledger'))
+      // },
+      // {
+      //   id: 320,
+      //   name: '藏品附件',
+      //   path: '/files',
+      //   Com: React.lazy(() => import('../C_goodsManage/C2files'))
+      // },
+      // {
+      //   id: 330,
+      //   name: '藏品关注',
+      //   path: '/focus',
+      //   Com: React.lazy(() => import('../C_goodsManage/C3focus'))
+      // },
+      // {
+      //   id: 340,
+      //   name: '藏品导入',
+      //   path: '/import',
+      //   Com: React.lazy(() => import('../C_goodsManage/C4import'))
+      // },
+      {
+        id: 350,
+        name: '藏品登记',
+        path: '/register',
+        Com: React.lazy(() => import('../C_goodsManage/C5register'))
+      }
+      // {
+      //   id: 360,
+      //   name: '藏品编辑',
+      //   path: '/edit',
+      //   Com: React.lazy(() => import('../C_goodsManage/C6edit'))
+      // },
+      // {
+      //   id: 370,
+      //   name: '藏品删除',
+      //   path: '/delete',
+      //   Com: React.lazy(() => import('../C_goodsManage/C7delete'))
+      // },
+      // {
+      //   id: 380,
+      //   name: '回收站',
+      //   path: '/recycleBin',
+      //   Com: React.lazy(() => import('../C_goodsManage/C8recycleBin'))
+      // }
+    ]
+  },
   {
     id: 4,
     name: '库存管理',
@@ -268,5 +268,79 @@ export const routerSon: RouterTypeRow = [
     name: '库房管理-查看藏品详情',
     path: '/storage_look/:id',
     Com: React.lazy(() => import('../Y_goodsDetails/Y2look'))
+  },
+  {
+    id: 4,
+    name: '藏品入馆-新增',
+    path: '/entering_add/:key',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3add'))
+  },
+  {
+    id: 5,
+    name: '藏品入藏-新增',
+    path: '/enterTibet_add/:key',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3add'))
+  },
+  {
+    id: 6,
+    name: '藏品登记-新增',
+    path: '/register_add/:key',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3add'))
+  },
+  {
+    id: 7,
+    name: '藏品入馆-编辑',
+    path: '/entering_edit/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit'))
+  },
+  {
+    id: 8,
+    name: '藏品入藏-编辑',
+    path: '/enterTibet_edit/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit'))
+  },
+  {
+    id: 9,
+    name: '藏品登记-编辑',
+    path: '/register_edit/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit'))
+  },
+
+  {
+    id: 10,
+    name: '藏品入馆-审批',
+    path: '/entering_audit/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit/audit'))
+  },
+  {
+    id: 11,
+    name: '藏品入藏-审批',
+    path: '/enterTibet_audit/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit/audit'))
+  },
+  {
+    id: 12,
+    name: '藏品登记-审批',
+    path: '/register_audit/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit/audit'))
+  },
+
+  {
+    id: 13,
+    name: '藏品入馆-查看',
+    path: '/entering_look/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit/look'))
+  },
+  {
+    id: 14,
+    name: '藏品入藏-查看',
+    path: '/enterTibet_look/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit/look'))
+  },
+  {
+    id: 15,
+    name: '藏品登记-查看',
+    path: '/register_look/:key/:id',
+    Com: React.lazy(() => import('../B_enterTibet/B3_4page/B3edit/look'))
   }
 ]

+ 15 - 0
src/utils/tableData.ts

@@ -15,6 +15,21 @@
 //   ];
 
 // 待完善
+export const B3eTableC = [
+  ['img', '封面图', 'thumb'],
+  ['txt', '编号类型', 'description'],
+  ['txt', '藏品编号', 'description'],
+  ['txt', '藏品名称', 'description'],
+  ['txt', '文物级别', 'description'],
+  ['txt', '文物类别', 'description'],
+  ['txt', '年代', 'description'],
+  ['txt', '数量', 'description'],
+  ['txt', '质地', 'description'],
+  ['txt', '完残程度', 'description'],
+  ['txt', '来源', 'description']
+]
+
+// 待完善
 export const D1GtableC = [
   ['img', '封面图', 'thumb'],
   ['txt', '藏品编号', 'userName'],