shaogen1995 9 hónapja
szülő
commit
6deb51eba5

+ 4 - 0
src/assets/styles/base.css

@@ -176,3 +176,7 @@ textarea {
 .ant-image-preview-operations-wrapper {
   z-index: 9999 !important;
 }
+.ant-notification-notice {
+  max-height: 500px !important;
+  overflow-y: auto !important;
+}

+ 5 - 0
src/assets/styles/base.less

@@ -279,3 +279,8 @@ textarea {
 .ant-image-preview-operations-wrapper {
   z-index: 9999 !important;
 }
+
+.ant-notification-notice {
+  max-height: 500px !important;
+  overflow-y: auto !important;
+}

+ 21 - 20
src/components/MyPopconfirm.tsx

@@ -1,46 +1,47 @@
-import React, { useMemo } from "react";
-import { Button, Popconfirm } from "antd";
+import React, { useMemo } from 'react'
+import { Button, Popconfirm } from 'antd'
 
 type Props = {
-  txtK: "删除" | "取消" | "重置密码" | "退出登录";
-  onConfirm: () => void;
-  Dom?: React.ReactNode;
-  loc?: "bottom";
-};
+  txtK: '删除' | '取消' | '重置密码' | '退出登录' | '清空'
+  onConfirm: () => void
+  Dom?: React.ReactNode
+  loc?: 'bottom'
+}
 
 function MyPopconfirm({ txtK, onConfirm, Dom, loc }: Props) {
   const txt = useMemo(() => {
     const obj = {
-      删除: ["删除后无法恢复,是否删除?", "删除"],
-      取消: ["放弃编辑后,信息将不会保存!", "放弃"],
-      重置密码: ["密码重制后为123456,是否重置?", "重置"],
-      退出登录: ["确定退出吗?", "确定"],
-    };
-    return Reflect.get(obj, txtK) || ["", ""];
-  }, [txtK]);
+      删除: ['删除后无法恢复,是否删除?', '删除'],
+      取消: ['放弃编辑后,信息将不会保存!', '放弃'],
+      重置密码: ['密码重制后为123456,是否重置?', '重置'],
+      退出登录: ['确定退出吗?', '确定'],
+      清空: ['确定清空吗?', '确定']
+    }
+    return Reflect.get(obj, txtK) || ['', '']
+  }, [txtK])
 
   return (
     <Popconfirm
       placement={loc}
       title={txt[0]}
       okText={txt[1]}
-      cancelText="取消"
+      cancelText='取消'
       onConfirm={onConfirm}
       okButtonProps={{ loading: false }}
     >
       {Dom ? (
         Dom
-      ) : txtK === "删除" ? (
-        <Button size="small" type="text" danger>
+      ) : txtK === '删除' ? (
+        <Button size='small' type='text' danger>
           {txtK}
         </Button>
       ) : (
         <Button>{txtK}</Button>
       )}
     </Popconfirm>
-  );
+  )
 }
 
-const MemoMyPopconfirm = React.memo(MyPopconfirm);
+const MemoMyPopconfirm = React.memo(MyPopconfirm)
 
-export default MemoMyPopconfirm;
+export default MemoMyPopconfirm

+ 4 - 1
src/components/MyTable/index.module.scss

@@ -13,6 +13,9 @@
           }
         }
       }
+      .tabx {
+        color: #ff4d4d;
+      }
     }
   }
-}
+}

+ 19 - 11
src/components/MyTable/index.tsx

@@ -81,17 +81,25 @@ function MyTable({
 
       const obj = {
         index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize,
-        txt: (item: any) => item[v[2]] || isNull,
-        img: (item: any) => (
-          <div className='tableImgAuto'>
-            <ImageLazy
-              width={60}
-              height={60}
-              src={item[v[2]] || item.thumb}
-              offline={(item[v[2]] || item.thumb).includes('http')}
-            />
-          </div>
-        ),
+        txt: (item: any) =>
+          v[3] && !item[v[2]] ? (
+            <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
+          ) : (
+            item[v[2]] || isNull
+          ),
+        img: (item: any) =>
+          v[3] && !item[v[2]] ? (
+            <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
+          ) : (
+            <div className='tableImgAuto'>
+              <ImageLazy
+                width={60}
+                height={60}
+                src={item[v[2]] || item.thumb}
+                offline={(item[v[2]] || item.thumb).includes('http')}
+              />
+            </div>
+          ),
         txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
         text: (item: any) => {
           let tempCom: any = item[v[2]] || isNull

+ 149 - 0
src/components/UpXlsx.tsx

@@ -0,0 +1,149 @@
+import { API_upFile } from '@/store/action/layout'
+import { A1tableType } from '@/types'
+import { fileDomInitialFu } from '@/utils/domShow'
+import { MessageFu } from '@/utils/message'
+import { notification } from 'antd'
+import React, { useCallback, useRef } from 'react'
+import { forwardRef, useImperativeHandle } from 'react'
+
+type Props = {
+  url: string
+  xlsxResInfoFu: (arr: A1tableType[]) => void
+  ref: any //当前自己的ref,给父组件调用
+  dirCode: string
+  ISBNArr: string[] //ISBN编号集合,用来过滤表格
+}
+
+function UpXlsx({ url, xlsxResInfoFu, dirCode, ISBNArr }: Props, ref: any) {
+  const [api, contextHolder] = notification.useNotification()
+
+  // 点击上传附件按钮
+  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.endsWith('.xlsx')) {
+          e.target.value = ''
+          return MessageFu.warning('只支持.xlsx格式!')
+        }
+
+        // 校验大小
+        if (filesInfo.size > 5 * 1024 * 1024) {
+          e.target.value = ''
+          return MessageFu.warning('最大支持5M!')
+        }
+        // 创建FormData对象
+        const fd = new FormData()
+        // 把files添加进FormData对象(‘photo’为后端需要的字段)
+        fd.append('type', 'doc')
+        fd.append('dirCode', dirCode)
+        fd.append('file', filesInfo)
+        fd.append('isDb', 'false')
+
+        e.target.value = ''
+
+        const res = await API_upFile(fd, url)
+
+        try {
+          if (res.code === 0) {
+            MessageFu.success('上传成功!')
+            // const { msg, error } = res.data
+
+            // const errorTit = error && error.length ? JSON.stringify(error) : ''
+
+            // api.info({
+            //   message: msg,
+            //   description: errorTit,
+            //   duration: 0,
+            //   placement: 'topLeft'
+            // })
+
+            const arrTemp: A1tableType[] = res.data || []
+
+            const moreTit: number[] = []
+
+            const arr = arrTemp.filter((item, ind) => {
+              const indRes = ind === arrTemp.findIndex(item2 => item.num === item2.num)
+
+              if (!indRes) moreTit.push(ind)
+              return indRes
+            })
+
+            if (moreTit && moreTit.length) {
+              const moreTitTxt = moreTit.map(v => v + 1)
+
+              api.warning({
+                message: `第${JSON.stringify(moreTitTxt)}行ISBN编号重复,已过滤`,
+                duration: 0,
+                placement: 'bottomLeft'
+              })
+            }
+
+            if (ISBNArr.length + arr.length > 50) {
+              fileDomInitialFu()
+              return MessageFu.warning(
+                `最多支持50条数据,您本次可录入数据条数为${50 - ISBNArr.length}条!`
+              )
+            }
+
+            const temp: string[] = []
+            const arrRes: A1tableType[] = []
+
+            arr.forEach((v: any, i: number) => {
+              v.id = Date.now() + i
+              if (ISBNArr.includes(v.num) && v.num !== '') {
+                temp.push(v.num)
+              } else {
+                arrRes.push(v)
+              }
+            })
+
+            xlsxResInfoFu(arrRes)
+
+            if (temp.length) {
+              api.warning({
+                message: 'ISBN编号' + JSON.stringify(temp) + '重复,已过滤',
+                duration: 0,
+                placement: 'bottomLeft'
+              })
+            }
+          }
+          fileDomInitialFu()
+        } catch (error) {
+          fileDomInitialFu()
+        }
+      }
+    },
+    [api, dirCode, ISBNArr, url, xlsxResInfoFu]
+  )
+
+  const myInputClickFu = useCallback(() => {
+    myInput.current?.click()
+  }, [])
+
+  // 可以让父组件调用子组件的方法
+  useImperativeHandle(ref, () => ({
+    myInputClickFu
+  }))
+
+  return (
+    <>
+      {contextHolder}
+      <input
+        id='upInput'
+        type='file'
+        accept='.xlsx'
+        ref={myInput}
+        onChange={e => handeUpPhoto(e)}
+      />
+    </>
+  )
+}
+
+export default forwardRef(UpXlsx)

+ 1 - 1
src/components/ZRichTexts/index.module.scss

@@ -9,7 +9,7 @@
       position: relative;
       display: flex;
       align-items: center;
-      justify-content: space-between;
+      // justify-content: space-between;
       height: 32px;
 
       .formRightZWRR {

+ 1 - 1
src/components/ZRichTexts/index.tsx

@@ -286,7 +286,7 @@ function ZRichTexts(
               />
             )}
 
-            <div hidden={isLook} style={{ marginLeft: 20 }}>
+            <div hidden={isLook}>
               <Button
                 onClick={() => {
                   nowIndexRef.current = 0

+ 94 - 0
src/pages/A1manage/A1Import/index.module.scss

@@ -0,0 +1,94 @@
+.A1Import {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+  background-color: #ecedf1;
+
+  :global {
+    .A1top {
+      .anticon-arrow-left {
+        cursor: pointer;
+        font-size: 30px;
+        margin-right: 24px;
+      }
+      h1 {
+        line-height: 30px;
+        font-size: 16px;
+      }
+      & > div {
+        display: flex;
+        align-items: center;
+        .A1iInco {
+          width: 24px;
+          height: 24px;
+          border-radius: 50%;
+          cursor: pointer;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          border: 1px solid #ccc;
+        }
+      }
+    }
+    .A1tableBox {
+      position: relative;
+      // height: calc(100% - 180px);
+      .ant-table-tbody .ant-table-cell {
+        padding: 4px !important;
+      }
+      .A1Ibtn {
+        position: absolute;
+        bottom: 10px;
+        left: 50%;
+        transform: translateX(-50%);
+        & > span {
+          width: 500px;
+          position: absolute;
+          top: -8px;
+          left: 80px;
+          opacity: 0;
+          pointer-events: none;
+          transition: all 0.3s;
+          color: #ff4d4d;
+        }
+        .A1IbtnTit {
+          top: 8px;
+          opacity: 1;
+        }
+      }
+    }
+
+    .A1Iedit {
+      position: absolute;
+      top: 0;
+      left: 0;
+      z-index: 10;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.6);
+      border-radius: 10px;
+      padding: 50px 100px;
+      & > div {
+        width: 100%;
+        height: 100%;
+        position: relative;
+      }
+    }
+  }
+}
+
+.A1Imo {
+  :global {
+    .ant-modal-body {
+      padding-top: 20px !important;
+      border-top: 1px solid #ccc;
+    }
+    .A1ImoRow {
+      margin-bottom: 20px;
+      font-size: 16px;
+    }
+  }
+}

+ 179 - 0
src/pages/A1manage/A1Import/index.tsx

@@ -0,0 +1,179 @@
+import React, { useCallback, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { ArrowLeftOutlined, QuestionOutlined } from '@ant-design/icons'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { Button, Modal } from 'antd'
+import MyTable from '@/components/MyTable'
+import { A1tableType, A2tableType, A2TreeType } from '@/types'
+import { A1tableCimp } from '@/utils/tableData'
+import UpXlsx from '@/components/UpXlsx'
+import { baseURL } from '@/utils/http'
+import classNames from 'classnames'
+import A1add from '../A1add'
+import { A1_APIimport } from '@/store/action/A1manage'
+import { MessageFu } from '@/utils/message'
+
+type Props = {
+  closeFu: () => void
+  addTableFu: () => void
+  storageArr: A2TreeType[]
+  exhibitTypeArr: A2tableType[]
+}
+
+function A1Import({ closeFu, addTableFu, storageArr, exhibitTypeArr }: Props) {
+  const [list, setList] = useState<A1tableType[]>([])
+
+  const [tit, setTit] = useState(false)
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: A1tableType) => (
+          <>
+            <Button size='small' type='text' onClick={() => setEditInfo(item)}>
+              编辑
+            </Button>
+
+            <MyPopconfirm
+              txtK='删除'
+              onConfirm={() => setList(list.filter(v => v.id !== item.id))}
+            />
+          </>
+        )
+      }
+    ]
+  }, [list])
+
+  // 编辑
+  const [editInfo, setEditInfo] = useState({} as A1tableType)
+
+  // 上传xlsx 的ref
+  const upXlsxRef = useRef<any>(null)
+
+  // 消息提示(完善待填入)
+  const titShow = useMemo(() => {
+    return list.some(v => !v.thumb || !v.storageId || !v.exhibitTypeId || !v.filePath)
+  }, [list])
+
+  // 编辑完返回的信息
+  const editFu = useCallback(
+    (info: A1tableType) => {
+      const index = list.findIndex(v => v.id === info.id)
+      const arr = [...list]
+      arr[index] = info
+      setList(arr)
+    },
+    [list]
+  )
+
+  // 点击导入
+  const impFu = useCallback(async () => {
+    const res = await A1_APIimport(list.map(v => ({ ...v, id: null })))
+    if (res.code === 0) {
+      MessageFu.success('导入成功!')
+      addTableFu()
+      closeFu()
+    }
+
+    // else if(res.code===-2){
+    //   MessageFu.warning()
+    // }
+  }, [addTableFu, closeFu, list])
+
+  return (
+    <div className={styles.A1Import}>
+      <div className='A1top'>
+        <div>
+          <ArrowLeftOutlined onClick={closeFu} />
+          <h1>图书批量导入</h1>
+        </div>
+        <div>
+          关于导入规则&nbsp;
+          <span className='A1iInco' onClick={() => setTit(true)}>
+            <QuestionOutlined />
+          </span>
+          &emsp;
+          <MyPopconfirm txtK='清空' onConfirm={() => setList([])} Dom={<Button>清空</Button>} />
+          &emsp;
+          <a href={baseURL + '/baseData/tp_book.xlsx'} download>
+            <Button>下载模板</Button>
+          </a>
+          &emsp;
+          <UpXlsx
+            url='cms/book/upload/excel'
+            ref={upXlsxRef}
+            xlsxResInfoFu={arr => setList([...arr, ...list])}
+            dirCode='cameraXlsx'
+            ISBNArr={list.map(v => v.num)}
+          />
+          {/* 上传xlsx */}
+          <Button type='primary' onClick={() => upXlsxRef.current?.myInputClickFu()}>
+            上传
+          </Button>
+        </div>
+      </div>
+
+      {/* 表格主体 */}
+      <div className='A1tableBox'>
+        <MyTable
+          classKey='A1Itable'
+          yHeight={610}
+          list={list}
+          columnsTemp={A1tableCimp}
+          lastBtn={tableLastBtn}
+          pagingInfo={false}
+        />
+
+        {/* 底部导入按钮 */}
+        <div className='A1Ibtn'>
+          <Button disabled={list.length === 0 || titShow} type='primary' onClick={impFu}>
+            导入
+          </Button>
+          <span className={classNames(list.length && titShow ? 'A1IbtnTit' : '')}>
+            请先完善代填入字段
+          </span>
+        </div>
+      </div>
+
+      {/* 复用编辑 */}
+      {editInfo.id ? (
+        <div className='A1Iedit'>
+          <div>
+            <A1add
+              editInfo={{ id: editInfo.id, txt: '编辑', info: editInfo }}
+              closeFu={() => setEditInfo({} as A1tableType)}
+              addTableFu={() => {}}
+              editTableFu={() => {}}
+              storageArr={storageArr}
+              exhibitTypeArr={exhibitTypeArr}
+              isImportFu={info => editFu(info)}
+              ISBNArr={list.filter(v => v.id !== editInfo.id).map(v => v.num)}
+            />
+          </div>
+        </div>
+      ) : null}
+
+      {/* 导入规则 */}
+      <Modal
+        wrapClassName={styles.A1Imo}
+        open={tit}
+        title='导入规则'
+        onCancel={() => setTit(false)}
+        footer={
+          [] // 设置footer为空,去掉 取消 确定默认按钮
+        }
+      >
+        <div className='A1ImoRow'>1:下载模板</div>
+        <div className='A1ImoRow'>2:在模板中填入内容,注意必填项和填入要求</div>
+        <div className='A1ImoRow'>3:上传已填写的模板文件</div>
+        <div className='A1ImoRow'>4:在当前列表中,完善图书信息,包括上传封面,附件等</div>
+        <div className='A1ImoRow'>5:导入内容</div>
+      </Modal>
+    </div>
+  )
+}
+
+const MemoA1Import = React.memo(A1Import)
+
+export default MemoA1Import

+ 94 - 35
src/pages/A1manage/A1add/index.tsx

@@ -8,9 +8,10 @@ import { MessageFu } from '@/utils/message'
 import ZupOne from '@/components/ZupOne'
 import TextArea from 'antd/es/input/TextArea'
 import dayjs from 'dayjs'
-import { A2tableType, A2TreeType } from '@/types'
+import { A1tableType, A2tableType, A2TreeType } from '@/types'
 import MyPopconfirm from '@/components/MyPopconfirm'
 import { A5_APIgetInfo } from '@/store/action/A5bookAudit'
+import { treeResIdFu } from '@/pages/A2classify/data'
 
 type Props = {
   editInfo: A1EditInfoType
@@ -20,6 +21,8 @@ type Props = {
   storageArr: A2TreeType[]
   exhibitTypeArr: A2tableType[]
   isAudit?: boolean //从图书审核页面进来
+  isImportFu?: (info: A1tableType) => void // 从批量导入里面进来
+  ISBNArr?: string[] //ISBN编号集合,用来判断当前填写的ISBN是否已经存在了(外层表格中)
 }
 
 function A1add({
@@ -29,7 +32,9 @@ function A1add({
   editTableFu,
   storageArr,
   exhibitTypeArr,
-  isAudit
+  isAudit,
+  isImportFu,
+  ISBNArr
 }: Props) {
   // 表单的ref
   const FormBoxRef = useRef<FormInstance>(null)
@@ -40,40 +45,47 @@ function A1add({
   // txt的ref
   const ZupTxtRef = useRef<any>(null)
 
+  // 回显数据的方法调用
+  const dataShow = useCallback((info: A1tableType) => {
+    let storageIds: any[] = []
+    if (info.ancestor) storageIds = info.ancestor.split(',').map((v: string) => Number(v))
+
+    if (info.storageId) storageIds.push(Number(info.storageId))
+
+    const obj = {
+      ...info,
+      storageIds,
+      exhibitTypeId: info.exhibitTypeId ? Number(info.exhibitTypeId) : null,
+      year: info.year ? info.year : null
+    }
+
+    FormBoxRef.current?.setFieldsValue(obj)
+
+    // 设置封面图
+    ZupThumbRef.current?.setFileComFileFu({
+      fileName: '',
+      filePath: info.thumb
+    })
+
+    // 设置附件
+    ZupTxtRef.current?.setFileComFileFu({
+      fileName: info.fileName,
+      filePath: info.filePath
+    })
+  }, [])
+
   // 编辑/查看 进入页面 获取信息
   const getInfoFu = useCallback(
     async (id: number) => {
-      const res = isAudit ? await A5_APIgetInfo(id) : await A1_APIgetInfo(id)
-      if (res.code === 0) {
-        const data = res.data
-
-        let storageIds = []
-        if (data.ancestor) storageIds = data.ancestor.split(',').map((v: string) => Number(v))
-        storageIds.push(Number(data.storageId))
-
-        const obj = {
-          ...data,
-          storageIds,
-          exhibitTypeId: Number(data.exhibitTypeId),
-          year: data.year ? data.year : null
+      if (isImportFu && editInfo.info) dataShow(editInfo.info)
+      else {
+        const res = isAudit ? await A5_APIgetInfo(id) : await A1_APIgetInfo(id)
+        if (res.code === 0) {
+          dataShow(res.data)
         }
-
-        FormBoxRef.current?.setFieldsValue(obj)
-
-        // 设置封面图
-        ZupThumbRef.current?.setFileComFileFu({
-          fileName: '',
-          filePath: data.thumb
-        })
-
-        // 设置附件
-        ZupTxtRef.current?.setFileComFileFu({
-          fileName: data.fileName,
-          filePath: data.filePath
-        })
       }
     },
-    [isAudit]
+    [dataShow, editInfo.info, isAudit, isImportFu]
   )
 
   // 附件 是否 已经点击过确定
@@ -112,6 +124,9 @@ function A1add({
       filePath = ZupTxtRefObj.filePath
       if (!filePath) return MessageFu.warning('请上传epub附件!')
 
+      if (ISBNArr && ISBNArr.includes(values.num) && values.num !== '')
+        return MessageFu.warning(`ISBN编号 ${values.num} 重复!`)
+
       let storageId: null | number = null
 
       if (values.storageIds && values.storageIds.length) {
@@ -132,15 +147,59 @@ function A1add({
       //   return;
       // }
 
-      const res = await A1_APIsave(obj)
+      if (isImportFu && editInfo.info) {
+        const info = editInfo.info
+
+        // 多级筛选的 映射字段回显
+        let ancestor = ''
+        let storageName = ''
+
+        const storageArrAc = treeResIdFu(storageArr, storageId!)
+        if (storageArrAc) {
+          ancestor = storageArrAc.ancestor
+          storageName = storageArrAc.name
+        }
+
+        // 下拉框 映射字段回显
+        let exhibitTypeName = ''
 
-      if (res.code === 0) {
-        MessageFu.success(isAudit ? '创建成功!' : `${editInfo.txt}成功!`)
-        editInfo.id > 0 ? editTableFu() : addTableFu()
+        const exhibitTypeArrAc = exhibitTypeArr.find(v => v.id === values.exhibitTypeId)
+
+        if (exhibitTypeArrAc) exhibitTypeName = exhibitTypeArrAc.name
+        const ImpObj = {
+          ...obj,
+          id: info.id,
+          ancestor,
+          storageName,
+          exhibitTypeName
+        }
+
+        isImportFu(ImpObj)
+        MessageFu.success('编辑成功!')
         closeFu()
+      } else {
+        const res = await A1_APIsave(obj)
+
+        if (res.code === 0) {
+          MessageFu.success(isAudit ? '创建成功!' : `${editInfo.txt}成功!`)
+          editInfo.id > 0 ? editTableFu() : addTableFu()
+          closeFu()
+        }
       }
     },
-    [addTableFu, closeFu, editInfo.id, editInfo.txt, editTableFu, isAudit]
+    [
+      ISBNArr,
+      addTableFu,
+      closeFu,
+      editInfo.id,
+      editInfo.info,
+      editInfo.txt,
+      editTableFu,
+      exhibitTypeArr,
+      isAudit,
+      isImportFu,
+      storageArr
+    ]
   )
 
   // 年份

+ 3 - 0
src/pages/A1manage/data.ts

@@ -1,3 +1,5 @@
+import { A1tableType } from '@/types'
+
 export type A1FromDataType = {
   searchKey: string
   num: string
@@ -13,4 +15,5 @@ export type A1FromDataType = {
 export type A1EditInfoType = {
   id: number
   txt: '新增' | '编辑' | '查看' | ''
+  info?: A1tableType
 }

+ 15 - 2
src/pages/A1manage/index.tsx

@@ -13,6 +13,7 @@ import MyTable from '@/components/MyTable'
 import { A1tableC } from '@/utils/tableData'
 import A1add from './A1add'
 import A1ying from './A1ying'
+import A1Import from './A1Import'
 
 const fromDataBase: A1FromDataType = {
   searchKey: '',
@@ -146,6 +147,9 @@ function A1manage() {
     }
   )
 
+  // 批量导入
+  const [imp, setImp] = useState(false)
+
   return (
     <div className={styles.A1manage}>
       <div className='pageTitle'>图书管理 {editInfo.id ? ` - ${editInfo.txt}` : ''}</div>
@@ -205,8 +209,7 @@ function A1manage() {
           </div>
         </div>
         <div>
-          {/* 待完善 */}
-          <Button>批量导入</Button>&emsp;
+          <Button onClick={() => setImp(true)}>批量导入</Button>&emsp;
           <Button onClick={resetSelectFu}>重置</Button>&emsp;
           <Button type='primary' onClick={() => setEditInfo({ id: -1, txt: '新增' })}>
             新增
@@ -249,6 +252,16 @@ function A1manage() {
           closeFu={() => setBookYing({ bookId: 0, type: 'img', name: '' })}
         />
       ) : null}
+
+      {/* 批量导入 */}
+      {imp ? (
+        <A1Import
+          storageArr={storageArr}
+          exhibitTypeArr={exhibitTypeObj.list}
+          closeFu={() => setImp(false)}
+          addTableFu={resetSelectFu}
+        />
+      ) : null}
     </div>
   )
 }

+ 0 - 2
src/pages/A7notice/A7add/index.tsx

@@ -32,8 +32,6 @@ function A7add({ editInfo, closeFu, addTableFu, editTableFu }: Props) {
     if (res.code === 0) {
       const data = res.data
 
-      console.log('--------', data.description)
-
       // 设置富文本
       ZRichTextRef.current?.ritxtShowFu(JSON.parse(data.description || '{}'))
 

+ 7 - 0
src/store/action/A1manage.ts

@@ -67,3 +67,10 @@ export const A1_APIgetInfoById = (id: number) => {
 export const A1_APIsaveById = (data: any) => {
   return http.post('cms/video/save', data)
 }
+
+/**
+ * 导入------------
+ */
+export const A1_APIimport = (data: any) => {
+  return http.post('cms/book/import', data)
+}

+ 13 - 0
src/utils/tableData.ts

@@ -27,6 +27,19 @@ export const A1tableC = [
   ['txt', '编辑时间', 'updateTime']
 ]
 
+export const A1tableCimp = [
+  ['txt', '书名', 'name'],
+  ['img', '封面(png、jpg)', 'thumb', `<span class='tabx'>(待填入)</span>`],
+  ['txt', '作者', 'author'],
+  ['txt', '出版社', 'press'],
+  ['txt', '出版年份', 'year'],
+  ['txt', '中图法分类', 'storageName', `<span class='tabx'>(待填入)</span>`],
+  ['txt', '展示分类', 'exhibitTypeName', `<span class='tabx'>(待填入)</span>`],
+  ['txt', 'ISBN编号', 'num'],
+  ['txt', '排序值', 'sort'],
+  ['txt', '附件(equb格式)', 'fileName', `<span class='tabx'>(待填入)</span>`]
+]
+
 export const A2tableY1 = [
   ['img', '封面', 'thumb'],
   ['text', '正文', 'description', 50],