shaogen1995 il y a 10 mois
Parent
commit
a2071a85db

+ 0 - 28
src/pages/A1manage/A1add/index.module.scss

@@ -23,19 +23,6 @@
         position: relative;
         width: 800px;
 
-        .A1_1Frow {
-          position: absolute;
-          top: 0px;
-          left: 600px;
-          width: 200px;
-        }
-
-        .A1_4Frow {
-          position: absolute;
-          left: 400px;
-          top: 4px;
-        }
-
         .A1_6Frow {
           position: absolute;
           left: 200px;
@@ -68,21 +55,6 @@
           .formRight {
             width: calc(100% - 100px);
           }
-
-          .formRight5Tit {
-            position: relative;
-            top: -10px;
-            transition: top 0.2s;
-            margin: 5px 0;
-            color: #ff4d4f;
-            opacity: 0;
-            pointer-events: none;
-          }
-
-          .formRight5TitErr {
-            opacity: 1;
-            top: 0;
-          }
         }
 
         .A1abtn {

+ 223 - 0
src/pages/A1manage/A1ying/A1Yadd.tsx

@@ -0,0 +1,223 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Form, FormInstance, Input, InputNumber, Modal } from 'antd'
+import { A1_APIgetInfoById, A1_APIsaveById } from '@/store/action/A1manage'
+import { MessageFu } from '@/utils/message'
+import ZupOne from '@/components/ZupOne'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import TextArea from 'antd/es/input/TextArea'
+
+type Props = {
+  type: 'img' | 'video'
+  id: number
+  bookId: number
+  closeFu: () => void
+  addTableFu: () => void
+  editTableFu: () => void
+}
+
+function A1Yadd({ type, id, closeFu, addTableFu, editTableFu, bookId }: Props) {
+  // 表单的ref
+  const FormBoxRef = useRef<FormInstance>(null)
+
+  // 封面图的ref
+  const ZupThumbRef = useRef<any>(null)
+
+  // 附件的ref
+  const ZupFileRef = useRef<any>(null)
+
+  // 编辑/查看 进入页面 获取信息
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A1_APIgetInfoById(id)
+    if (res.code === 0) {
+      const data = res.data
+      FormBoxRef.current?.setFieldsValue(data)
+
+      // 设置封面图
+      ZupThumbRef.current?.setFileComFileFu({
+        fileName: '',
+        filePath: data.thumb
+      })
+
+      // 设置附件
+      ZupFileRef.current?.setFileComFileFu({
+        fileName: data.fileName,
+        filePath: data.filePath
+      })
+    }
+  }, [])
+
+  // 附件 是否 已经点击过确定
+  const [fileCheck, setFileCheck] = useState(false)
+
+  useEffect(() => {
+    if (id > 0) {
+      getInfoFu(id)
+    } else {
+      FormBoxRef.current?.setFieldsValue({
+        sort: 999
+      })
+    }
+  }, [id, getInfoFu])
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    setFileCheck(true)
+  }, [])
+
+  //  通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      setFileCheck(true)
+
+      const coverUrl1 = ZupThumbRef.current?.fileComFileResFu()
+      // 没有传 封面图
+      if (!coverUrl1.filePath)
+        return MessageFu.warning(`请上传!${type === 'img' ? '图片' : '封面图'}!`)
+
+      let fileName = ''
+      let filePath = ''
+      // 附件
+      if (type === 'video') {
+        const ZupTxtRefObj = ZupFileRef.current?.fileComFileResFu()
+        fileName = ZupTxtRefObj.fileName
+        filePath = ZupTxtRefObj.filePath
+        if (!filePath) return MessageFu.warning('请上传附件!')
+      }
+
+      const obj = {
+        ...values,
+        id: id > 0 ? id : null,
+        thumb: coverUrl1.filePath,
+        fileName,
+        filePath,
+        type,
+        bookId
+      }
+
+      // if (obj) {
+      //   console.log(123, obj)
+      //   return
+      // }
+
+      const res = await A1_APIsaveById(obj)
+
+      if (res.code === 0) {
+        MessageFu.success(`${id > 0 ? '编辑' : '新增'}成功!`)
+        id > 0 ? editTableFu() : addTableFu()
+        closeFu()
+      }
+    },
+    [addTableFu, closeFu, editTableFu, id, type]
+  )
+
+  return (
+    <Modal
+      wrapClassName={styles.A1Yadd}
+      open={true}
+      title={id > 0 ? '编辑' : '新增'}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='A1Ymain'>
+        <Form
+          ref={FormBoxRef}
+          name='basic'
+          labelCol={{ span: 2 }}
+          onFinish={onFinish}
+          onFinishFailed={onFinishFailed}
+          autoComplete='off'
+          scrollToFirstError
+        >
+          {type === 'video' ? (
+            <Form.Item
+              label='标题'
+              name='name'
+              rules={[{ required: true, message: '请输入标题!' }]}
+            >
+              <Input placeholder='请输入内容' maxLength={20} showCount />
+            </Form.Item>
+          ) : null}
+
+          {/* 封面 */}
+          <div className='formRow'>
+            <div className='formLeft'>
+              <span>* </span>
+              {type === 'img' ? '图片' : '封面'}:
+            </div>
+            <div className='formRight'>
+              <ZupOne
+                ref={ZupThumbRef}
+                fileCheck={fileCheck}
+                size={5}
+                dirCode={'A1manageY'}
+                myUrl='cms/video/upload'
+                format={['image/jpeg', 'image/png']}
+                formatTxt='png、jpg和jpeg'
+                checkTxt={`请上传${type === 'img' ? '图片' : '封面图'}!`}
+                upTxt='最多1张'
+                myType='thumb'
+              />
+            </div>
+          </div>
+
+          <Form.Item label={type === 'img' ? '正文' : '简介'} name='description'>
+            <TextArea maxLength={type === 'img' ? 1000 : 200} showCount placeholder='请输入内容' />
+          </Form.Item>
+
+          {/* 附件 */}
+          {type === 'video' ? (
+            <div className='formRow'>
+              <div className='formLeft'>
+                <span>* </span>
+                附件:
+              </div>
+              <div className='formRight'>
+                <ZupOne
+                  ref={ZupFileRef}
+                  fileCheck={fileCheck}
+                  size={500}
+                  dirCode='A1manageY'
+                  myUrl='cms/video/upload'
+                  format={['video/mp4']}
+                  formatTxt='video'
+                  checkTxt='请上传video附件!'
+                  upTxt='最多1个'
+                  myType='video'
+                />
+              </div>
+            </div>
+          ) : null}
+
+          <div className='A1fromRow'>
+            <Form.Item
+              label='排序值'
+              name='sort'
+              rules={[{ required: true, message: '请输入排序值!' }]}
+            >
+              <InputNumber min={1} max={999} precision={0} placeholder='请输入' />
+            </Form.Item>
+            <div className='A1_6Frow'>
+              请输入1~999的数字。数字越小,排序越靠前。数字相同时,更新发布的内容排在前面
+            </div>
+          </div>
+
+          {/* 确定和取消按钮 */}
+          <Form.Item className='A1Ybtn'>
+            <Button type='primary' htmlType='submit'>
+              提交
+            </Button>
+            <br />
+            <br />
+            <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+          </Form.Item>
+        </Form>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoA1Yadd = React.memo(A1Yadd)
+
+export default MemoA1Yadd

+ 104 - 0
src/pages/A1manage/A1ying/index.module.scss

@@ -0,0 +1,104 @@
+.A1ying {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 12;
+  background-color: #fff;
+  border-radius: 10px;
+  :global {
+    .A1Ytop {
+      border-radius: 10px;
+      background-color: #fff;
+      padding: 15px 24px;
+      display: flex;
+      justify-content: space-between;
+      .A1YtopRow {
+        display: flex;
+        align-items: center;
+        .anticon-arrow-left {
+          cursor: pointer;
+          font-size: 30px;
+          margin-right: 24px;
+        }
+        .A1YtopBack {
+          color: var(--themeColor);
+          font-size: 18px;
+          font-weight: 700;
+          margin-right: 24px;
+        }
+      }
+    }
+  }
+}
+
+// 新增 、编辑弹窗
+.A1Yadd {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal {
+      width: 1000px !important;
+    }
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+      padding-top: 15px !important;
+    }
+
+    .A1Ymain {
+      width: 100%;
+      height: 100%;
+      overflow-y: auto;
+      position: relative;
+
+      textarea {
+        min-height: 150px !important;
+      }
+
+      .A1fromRow {
+        position: relative;
+        width: 800px;
+
+        .A1_6Frow {
+          position: absolute;
+          left: 180px;
+          top: 5px;
+          color: #999;
+          font-size: 12px;
+        }
+      }
+
+      .ant-form {
+        width: 800px;
+        .formRow {
+          display: flex;
+
+          .formLeft {
+            position: relative;
+            top: 3px;
+            width: 67px;
+            text-align: right;
+
+            & > span {
+              color: #ff4d4f;
+            }
+          }
+
+          .formRight {
+            width: calc(100% - 67px);
+          }
+        }
+
+        .A1Ybtn {
+          position: absolute;
+          z-index: 10;
+          right: 20px;
+          top: 50%;
+          transform: translateY(-50%);
+        }
+      }
+    }
+  }
+}

+ 173 - 0
src/pages/A1manage/A1ying/index.tsx

@@ -0,0 +1,173 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { A1_APIdelById, A1_APIgetListById } from '@/store/action/A1manage'
+import { ArrowLeftOutlined } from '@ant-design/icons'
+import { Button, Input } from 'antd'
+import MyTable from '@/components/MyTable'
+import { A1YType } from '@/types'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { MessageFu } from '@/utils/message'
+import { A2tableY1, A2tableY2 } from '@/utils/tableData'
+import A1Yadd from './A1Yadd'
+
+type FromDataType = {
+  searchKey: string
+  pageNum: number
+  pageSize: number
+  bookId: number
+  type: 'img' | 'video'
+}
+
+type Props = {
+  bookId: number
+  type: 'img' | 'video'
+  closeFu: () => void
+}
+
+function A1ying({ bookId, type, closeFu }: Props) {
+  const [fromData, setFromData] = useState({} as FromDataType)
+
+  useEffect(() => {
+    setFromData({
+      searchKey: '',
+      pageNum: 1,
+      pageSize: 10,
+      bookId,
+      type
+    })
+  }, [bookId, type])
+
+  const getListFu = useCallback(async () => {
+    if (fromData.bookId) {
+      const res = await A1_APIgetListById(fromData)
+
+      if (res.code === 0) {
+        const obj = {
+          list: res.data.records,
+          total: res.data.total
+        }
+        setTableInfo(obj)
+      }
+    }
+  }, [fromData])
+
+  useEffect(() => {
+    getListFu()
+  }, [getListFu])
+
+  // 输入框的输入
+  const [inputKey, setInputKey] = useState(1)
+  const timeRef = useRef(-1)
+  const txtChangeFu = useCallback(
+    (e: React.ChangeEvent<HTMLInputElement>, key: 'searchKey') => {
+      clearTimeout(timeRef.current)
+      timeRef.current = window.setTimeout(() => {
+        setFromData({ ...fromData, [key]: e.target.value.replaceAll("'", ''), pageNum: 1 })
+      }, 500)
+    },
+    [fromData]
+  )
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setInputKey(Date.now())
+    setFromData({
+      searchKey: '',
+      pageNum: 1,
+      pageSize: 10,
+      bookId,
+      type
+    })
+  }, [bookId, type])
+
+  // 表格数据
+  const [tableInfo, setTableInfo] = useState({
+    list: [] as A1YType[],
+    total: 0
+  })
+
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res = await A1_APIdelById(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功!')
+        getListFu()
+      }
+    },
+    [getListFu]
+  )
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: A1YType) => (
+          <>
+            <Button size='small' type='text' onClick={() => setAddId(item.id)}>
+              编辑
+            </Button>
+            <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+          </>
+        )
+      }
+    ]
+  }, [delTableFu])
+
+  // 新增和编辑
+  const [addId, setAddId] = useState(0)
+
+  return (
+    <div className={styles.A1ying}>
+      <div className='A1Ytop'>
+        <div className='A1YtopRow'>
+          <ArrowLeftOutlined onClick={closeFu} />
+          <div className='A1YtopBack'>{type === 'img' ? '影印资料' : '视频资料'}</div>
+          <span>搜索:</span>
+          <Input
+            key={inputKey}
+            maxLength={20}
+            style={{ width: 300 }}
+            placeholder={type === 'img' ? '请输入正文' : '请输入标题或简介'}
+            allowClear
+            onChange={e => txtChangeFu(e, 'searchKey')}
+          />
+        </div>
+        <div className='A1YtopRow'>
+          <Button onClick={resetSelectFu}>重置</Button>&emsp;
+          <Button type='primary' onClick={() => setAddId(-1)}>
+            新增
+          </Button>
+        </div>
+      </div>
+
+      <div className='A1tableBox'>
+        <MyTable
+          classKey='A1y'
+          yHeight={625}
+          list={tableInfo.list}
+          columnsTemp={type === 'img' ? A2tableY1 : A2tableY2}
+          lastBtn={tableLastBtn}
+          pageNum={fromData.pageNum}
+          pageSize={fromData.pageSize}
+          total={tableInfo.total}
+          onChange={(pageNum, pageSize) => setFromData({ ...fromData, pageNum, pageSize })}
+        />
+      </div>
+
+      {addId ? (
+        <A1Yadd
+          type={type}
+          bookId={bookId}
+          id={addId}
+          closeFu={() => setAddId(0)}
+          addTableFu={resetSelectFu}
+          editTableFu={getListFu}
+        />
+      ) : null}
+    </div>
+  )
+}
+
+const MemoA1ying = React.memo(A1ying)
+
+export default MemoA1ying

+ 34 - 3
src/pages/A1manage/index.tsx

@@ -12,6 +12,7 @@ import { A2_APIgetList1, A2_APIgetList2 } from '@/store/action/A2classify'
 import MyTable from '@/components/MyTable'
 import { A1tableC } from '@/utils/tableData'
 import A1add from './A1add'
+import A1ying from './A1ying'
 
 const fromDataBase: A1FromDataType = {
   searchKey: '',
@@ -47,13 +48,13 @@ function A1manage() {
     }
     if (fromData.storageArr && fromData.storageArr.length)
       obj.storageId = fromData.storageArr[fromData.storageArr.length - 1]
-    dispatch(A1_APIgetList(fromData))
+
+    dispatch(A1_APIgetList(obj))
   }, [dispatch, fromData])
 
   useEffect(() => {
     getListFu()
   }, [getListFu])
-
   const [inputKey, setInputKey] = useState(1)
 
   // 输入框的输入
@@ -62,7 +63,7 @@ function A1manage() {
     (e: React.ChangeEvent<HTMLInputElement>, key: 'searchKey' | 'num') => {
       clearTimeout(timeRef.current)
       timeRef.current = window.setTimeout(() => {
-        setFromData({ ...fromData, [key]: e.target.value, pageNum: 1 })
+        setFromData({ ...fromData, [key]: e.target.value.replaceAll("'", ''), pageNum: 1 })
       }, 500)
     },
     [fromData]
@@ -107,6 +108,21 @@ function A1manage() {
             >
               编辑
             </Button>
+            <Button
+              size='small'
+              type='text'
+              onClick={() => setBookYing({ bookId: item.id, type: 'img' })}
+            >
+              影印
+            </Button>
+            <Button
+              size='small'
+              type='text'
+              onClick={() => setBookYing({ bookId: item.id, type: 'video' })}
+            >
+              视频
+            </Button>
+
             <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
           </>
         )
@@ -120,6 +136,12 @@ function A1manage() {
     txt: ''
   })
 
+  // 影印和视频
+  const [bookYing, setBookYing] = useState<{ bookId: number; type: 'img' | 'video' }>({
+    bookId: 0,
+    type: 'img'
+  })
+
   return (
     <div className={styles.A1manage}>
       <div className='pageTitle'>图书管理 {editInfo.id ? ` - ${editInfo.txt}` : ''}</div>
@@ -211,6 +233,15 @@ function A1manage() {
           exhibitTypeArr={exhibitTypeObj.list}
         ></A1add>
       ) : null}
+
+      {/* 影印和视频 */}
+      {bookYing.bookId ? (
+        <A1ying
+          bookId={bookYing.bookId}
+          type={bookYing.type}
+          closeFu={() => setBookYing({ bookId: 0, type: 'img' })}
+        />
+      ) : null}
     </div>
   )
 }

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

@@ -37,3 +37,33 @@ export const A1_APIgetInfo = (id: number) => {
 export const A1_APIsave = (data: any) => {
   return http.post('cms/book/save', data)
 }
+
+// ----------------------影印/视频资料-------------------
+
+/**
+ * 图书管理-影印/视频资料 列表
+ */
+export const A1_APIgetListById = (data: any) => {
+  return http.post('cms/video/pageList', data)
+}
+
+/**
+ * 图书管理-影印/视频资料-删除
+ */
+export const A1_APIdelById = (id: number) => {
+  return http.get(`cms/video/remove/${id}`)
+}
+
+/**
+ * 图书管理-影印/视频资料-获取详情
+ */
+export const A1_APIgetInfoById = (id: number) => {
+  return http.get(`cms/video/detail/${id}`)
+}
+
+/**
+ * 图书管理-影印/视频资料-新增、编辑
+ */
+export const A1_APIsaveById = (data: any) => {
+  return http.post('cms/video/save', data)
+}

+ 15 - 0
src/types/api/A1manage.d.ts

@@ -23,3 +23,18 @@ export type A1tableType = {
   updateTime: string
   year: string
 }
+export type A1YType = {
+  bookId: number
+  createTime: string
+  creatorId: number
+  creatorName: string
+  description: string
+  fileName: string
+  filePath: string
+  id: number
+  name: string
+  sort: number
+  thumb: string
+  type: string
+  updateTime: string
+}

+ 18 - 0
src/utils/tableData.ts

@@ -27,6 +27,24 @@ export const A1tableC = [
   ['txt', '编辑时间', 'updateTime']
 ]
 
+export const A2tableY1 = [
+  ['img', '封面', 'thumb'],
+  ['text', '正文', 'description', 50],
+  ['txt', '排序值', 'sort'],
+  ['txt', '编辑人', 'creatorName'],
+  ['txt', '编辑时间', 'updateTime']
+]
+
+export const A2tableY2 = [
+  ['txt', '标题', 'name'],
+  ['img', '视频封面', 'thumb'],
+  ['text', '简介', 'description', 50],
+  ['txt', '附件', 'fileName'],
+  ['txt', '排序值', 'sort'],
+  ['txt', '编辑人', 'creatorName'],
+  ['txt', '编辑时间', 'updateTime']
+]
+
 export const A2tableC = [
   ['txt', '分类名称', 'name'],
   ['txt', '排序值', 'sort'],