浏览代码

烈士档案-生平信息

shaogen1995 1 周之前
父节点
当前提交
976fb5d9ae

+ 10 - 6
后台管理/src/components/ZRichTexts/index.tsx

@@ -37,10 +37,11 @@ type Props = {
   myUrl: string //上传的api地址
   isOne?: boolean //只显示单个富文本
   upAudioBtnNone?: boolean //是否能上传无障碍音频
+  imgOne?: boolean // 只上传图片
 }
 
 function ZRichTexts(
-  { check, dirCode, isLook, myUrl, isOne = false, upAudioBtnNone = false }: Props,
+  { check, dirCode, isLook, myUrl, isOne = false, upAudioBtnNone = false, imgOne }: Props,
   ref: any
 ) {
   const [sectionArr, setSectionArr] = useState<SectionArrType[]>([
@@ -91,14 +92,17 @@ function ZRichTexts(
         // 拿到files信息
         const filesInfo = e.target.files[0]
 
-        let type = ['image/jpeg', 'image/png', 'video/mp4']
+        let type = ['image/jpeg', 'image/png']
+
+        if (!imgOne) type.push('video/mp4')
+
         let size = 5
         let txt = '图片只支持png、jpg和jpeg格式!'
         let txt2 = '图片最大支持5M!'
 
         const isVideoFlag = filesInfo.name.endsWith('.mp4') || filesInfo.name.endsWith('.MP4')
 
-        if (isVideoFlag) {
+        if (!isOne && isVideoFlag) {
           // 上传视频
           size = 500
           txt = '视频只支持mp4格式!'
@@ -147,7 +151,7 @@ function ZRichTexts(
         }
       }
     },
-    [dirCode, myUrl, sectionArr]
+    [dirCode, imgOne, isOne, myUrl, sectionArr]
   )
 
   // 让父组件调用的 回显 富文本
@@ -264,7 +268,7 @@ function ZRichTexts(
       <input
         id='upInput'
         type='file'
-        accept='.png,.jpg,.jpeg,.mp4'
+        accept={`.png,.jpg,.jpeg${imgOne ? '' : ',.mp4'}`}
         ref={myInput}
         onChange={e => handeUpPhoto(e)}
       />
@@ -302,7 +306,7 @@ function ZRichTexts(
                   myInput.current?.click()
                 }}
               >
-                上传图片/视频
+                上传图片{imgOne ? '' : '/视频'}
               </Button>
             </div>
           </div>

+ 8 - 0
后台管理/src/pages/A1record/A1look/index.module.scss

@@ -58,6 +58,14 @@
       background-color: #fff;
       border-radius: 10px;
       padding: 15px;
+      position: relative;
+      .A1Tab1 {
+        margin-bottom: 10px;
+        border-bottom: 1px solid #ccc;
+        .ant-btn {
+          margin-right: 20px;
+        }
+      }
     }
   }
 }

+ 34 - 1
后台管理/src/pages/A1record/A1look/index.tsx

@@ -5,6 +5,18 @@ import { A1_APIgetInfo } from '@/store/action/A1record'
 import { A1ListType, jiGuanFu } from '../data'
 import ZupTypes from '@/components/ZupTypes'
 import ZupVideos from '@/components/ZupVideos'
+import { Button } from 'antd'
+import A1tab1life from '../A1tab/A1tab1life'
+import A2tab2clan from '../A1tab/A2tab2clan'
+import A3tab3clue from '../A1tab/A3tab3clue'
+import A4tab4antique from '../A1tab/A4tab4antique'
+
+const tabList = [
+  { id: 1, name: '生平信息' },
+  { id: 2, name: '亲属信息' },
+  { id: 3, name: '寻亲线索' },
+  { id: 4, name: '相关文物' }
+]
 
 type Props = {
   sId: number
@@ -45,6 +57,9 @@ function A1look({ sId }: Props) {
     getInfoFu(sId)
   }, [getInfoFu, sId])
 
+  // 下面4个tab切换
+  const [tabAc, setTabAc] = useState(1)
+
   return (
     <div className={styles.A1look}>
       {loding ? (
@@ -132,7 +147,25 @@ function A1look({ sId }: Props) {
             </div>
           </div>
 
-          <div className='A1Tab'></div>
+          <div className='A1Tab'>
+            <div className='A1Tab1'>
+              {tabList.map(v => (
+                <Button
+                  key={v.id}
+                  onClick={() => setTabAc(v.id)}
+                  type={tabAc === v.id ? 'primary' : 'default'}
+                  size='large'
+                >
+                  {v.name}
+                </Button>
+              ))}
+            </div>
+
+            {tabAc === 1 ? <A1tab1life sId={sId} /> : null}
+            {tabAc === 2 ? <A2tab2clan sId={sId} /> : null}
+            {tabAc === 3 ? <A3tab3clue sId={sId} /> : null}
+            {tabAc === 4 ? <A4tab4antique sId={sId} /> : null}
+          </div>
         </>
       ) : null}
     </div>

+ 44 - 0
后台管理/src/pages/A1record/A1tab/A1tab1life/A1tab1add/index.module.scss

@@ -0,0 +1,44 @@
+.A1tab1add {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal {
+      width: 1200px !important;
+    }
+    .A1t1Amain {
+      border-top: 1px solid #ccc;
+      padding-top: 15px;
+      .A1T1Arow {
+        display: flex;
+        margin-bottom: 24px;
+        & > div {
+          &:nth-of-type(1) {
+            width: 60px;
+            position: relative;
+            top: 3px;
+            text-align: right;
+            & > span {
+              color: #ff4d4f;
+            }
+          }
+          &:nth-of-type(2) {
+            width: calc(100% - 60px);
+          }
+        }
+        // 富文本
+        .formRightZWRR {
+          position: absolute;
+          left: 0;
+          & > div {
+            margin-left: 0 !important;
+          }
+        }
+      }
+    }
+    .A1T1Abtn {
+      margin-top: 20px;
+      text-align: center;
+    }
+  }
+}

+ 104 - 0
后台管理/src/pages/A1record/A1tab/A1tab1life/A1tab1add/index.tsx

@@ -0,0 +1,104 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, DatePicker, Modal } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import dayjs from 'dayjs'
+import ZRichTexts from '@/components/ZRichTexts'
+import { A1Tab1ListType } from '..'
+import { MessageFu } from '@/utils/message'
+import { A1_APIsaveTab1 } from '@/store/action/A1record'
+
+type Props = {
+  sId: number
+  sInfo: A1Tab1ListType
+  closeFu: () => void
+  upTableFu: () => void
+}
+
+function A1tab1add({ sInfo, closeFu, upTableFu, sId }: Props) {
+  // 富文本的ref
+  const ZRichTextRef = useRef<any>(null)
+
+  const [date, setDate] = useState('')
+
+  useEffect(() => {
+    if (sInfo.id > 0) {
+      setDate(sInfo.date)
+      // 设置富文本
+      if (sInfo.rtf) ZRichTextRef.current?.ritxtShowFu(JSON.parse(sInfo.rtf))
+    }
+  }, [sInfo])
+
+  const addBtn = useCallback(async () => {
+    // 富文本
+    const rtf = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
+
+    if (!date) return MessageFu.warning('请选择日期')
+
+    const obj = {
+      id: sInfo.id > 0 ? sInfo.id : null,
+      date,
+      martyrId: sId,
+      rtf: JSON.stringify(rtf.val || '')
+    }
+    const res = await A1_APIsaveTab1(obj)
+    if (res.code === 0) {
+      MessageFu.success(sInfo.id > 0 ? '编辑成功' : '新增成功')
+      upTableFu()
+      closeFu()
+    }
+  }, [closeFu, date, sId, sInfo.id, upTableFu])
+
+  return (
+    <Modal
+      wrapClassName={styles.A1tab1add}
+      open={true}
+      title={sInfo.id > 0 ? '编辑生平' : '新增生平'}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='A1t1Amain'>
+        <div className='A1T1Arow'>
+          <div>
+            <span>* </span> 日期:
+          </div>
+          <div>
+            <DatePicker
+              value={date ? dayjs(date) : null}
+              onChange={e => (e ? setDate(dayjs(e).format('YYYY-MM-DD')) : '')}
+            />
+          </div>
+        </div>
+
+        <div className='A1T1Arow'>
+          <div>简介:</div>
+          <div>
+            <ZRichTexts
+              check={false}
+              dirCode='A1tab1life'
+              myUrl='cms/life/upload'
+              isLook={false}
+              ref={ZRichTextRef}
+              isOne={true}
+              upAudioBtnNone={true}
+              imgOne
+            />
+          </div>
+        </div>
+      </div>
+
+      <div className='A1T1Abtn'>
+        <Button type='primary' onClick={addBtn}>
+          提交
+        </Button>
+        &emsp;
+        <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+      </div>
+    </Modal>
+  )
+}
+
+const MemoA1tab1add = React.memo(A1tab1add)
+
+export default MemoA1tab1add

+ 59 - 0
后台管理/src/pages/A1record/A1tab/A1tab1life/index.module.scss

@@ -0,0 +1,59 @@
+.A1tab1life {
+  :global {
+    .A1t1btn {
+      position: absolute;
+      right: 10px;
+      top: 12px;
+      z-index: 10;
+    }
+
+    .A1t1Row {
+      border: 1px solid #ccc;
+      border-radius: 4px;
+      padding: 15px 0 0;
+      font-size: 16px;
+      margin-bottom: 24px;
+
+      .A1t1Row1 {
+        display: flex;
+        margin-bottom: 20px;
+        position: relative;
+
+        .A1t1Row1Btn {
+          position: absolute;
+          right: 15px;
+          top: 0px;
+          z-index: 15;
+          .ant-btn-sm {
+            font-size: 18px;
+          }
+        }
+
+        & > div {
+          &:nth-of-type(1) {
+            width: 82px;
+            text-align: right;
+            font-weight: 700;
+          }
+          &:nth-of-type(2) {
+            width: calc(100% - 82px);
+            p {
+              min-height: 20px;
+            }
+            .image-wrap {
+              text-align: center;
+            }
+          }
+        }
+      }
+
+      .A1t1Rowll {
+        width: 120px;
+        text-align: center;
+      }
+      .A1t1Rowrr {
+        width: calc(100% - 140px);
+      }
+    }
+  }
+}

+ 111 - 0
后台管理/src/pages/A1record/A1tab/A1tab1life/index.tsx

@@ -0,0 +1,111 @@
+import React, { useCallback, useEffect, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Empty } from 'antd'
+import { A1_APIdelTab1, A1_APIgetTab1List } from '@/store/action/A1record'
+import A1tab1add from './A1tab1add'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { MessageFu } from '@/utils/message'
+import { textFu } from '@/utils/history'
+
+export type A1Tab1ListType = {
+  id: number
+  date: string
+  rtf: string
+}
+
+type Props = {
+  sId: number
+}
+
+function A1tab1life({ sId }: Props) {
+  const [data, setData] = useState<{ list: A1Tab1ListType[]; flag: boolean }>({
+    list: [],
+    flag: false
+  })
+
+  const getInfoFu = useCallback(async () => {
+    const res = await A1_APIgetTab1List(sId)
+    if (res.code === 0) {
+      setData({ list: res.data || [], flag: true })
+    }
+  }, [sId])
+
+  useEffect(() => {
+    getInfoFu()
+  }, [getInfoFu])
+
+  const [addInfo, setAddInfo] = useState({} as A1Tab1ListType)
+
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res = await A1_APIdelTab1(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功!')
+        getInfoFu()
+      }
+    },
+    [getInfoFu]
+  )
+
+  return (
+    <div className={styles.A1tab1life}>
+      <div className='A1t1btn'>
+        <Button type='primary' onClick={() => setAddInfo({ id: -1 } as A1Tab1ListType)}>
+          新增生平
+        </Button>
+      </div>
+
+      {data.flag && data.list.length === 0 ? (
+        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
+      ) : (
+        <>
+          {data.list.map(item => (
+            <div className='A1t1Row' key={item.id}>
+              <div className='A1t1Row1'>
+                <div>日期:</div>
+                <div>{item.date}</div>
+                <div className='A1t1Row1Btn'>
+                  <Button size='small' type='text' onClick={() => setAddInfo(item)}>
+                    编辑
+                  </Button>
+                  <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+                </div>
+              </div>
+
+              <div className='A1t1Row1'>
+                <div>简介:</div>
+                <div dangerouslySetInnerHTML={{ __html: textFu(item.rtf) || '(空)' }}></div>
+              </div>
+
+              {/* <div className='A1t1Rowll'>
+                {item.date}
+                <p>
+                  <Button size='small' type='text' onClick={() => setAddInfo(item)}>
+                    编辑
+                  </Button>
+                  <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+                </p>
+              </div>
+              <div
+                className='A1t1Rowrr'
+                dangerouslySetInnerHTML={{ __html: textFu(item.rtf) || '(空)' }}
+              ></div> */}
+            </div>
+          ))}
+        </>
+      )}
+      {addInfo.id ? (
+        <A1tab1add
+          sId={sId}
+          sInfo={addInfo}
+          closeFu={() => setAddInfo({} as A1Tab1ListType)}
+          upTableFu={getInfoFu}
+        />
+      ) : null}
+    </div>
+  )
+}
+
+const MemoA1tab1life = React.memo(A1tab1life)
+
+export default MemoA1tab1life

+ 4 - 0
后台管理/src/pages/A1record/A1tab/A2tab2clan/index.module.scss

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

+ 18 - 0
后台管理/src/pages/A1record/A1tab/A2tab2clan/index.tsx

@@ -0,0 +1,18 @@
+import React from 'react'
+import styles from './index.module.scss'
+
+type Props = {
+  sId: number
+}
+
+function A2tab2clan({ sId: number }: Props) {
+  return (
+    <div className={styles.A2tab2clan}>
+      <h1>A2tab2clan</h1>
+    </div>
+  )
+}
+
+const MemoA2tab2clan = React.memo(A2tab2clan)
+
+export default MemoA2tab2clan

+ 4 - 0
后台管理/src/pages/A1record/A1tab/A3tab3clue/index.module.scss

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

+ 18 - 0
后台管理/src/pages/A1record/A1tab/A3tab3clue/index.tsx

@@ -0,0 +1,18 @@
+import React from 'react'
+import styles from './index.module.scss'
+
+type Props = {
+  sId: number
+}
+
+function A3tab3clue({ sId: number }: Props) {
+  return (
+    <div className={styles.A3tab3clue}>
+      <h1>A3tab3clue</h1>
+    </div>
+  )
+}
+
+const MemoA3tab3clue = React.memo(A3tab3clue)
+
+export default MemoA3tab3clue

+ 4 - 0
后台管理/src/pages/A1record/A1tab/A4tab4antique/index.module.scss

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

+ 18 - 0
后台管理/src/pages/A1record/A1tab/A4tab4antique/index.tsx

@@ -0,0 +1,18 @@
+import React from 'react'
+import styles from './index.module.scss'
+
+type Props = {
+  sId: number
+}
+
+function A4tab4antique({ sId: number }: Props) {
+  return (
+    <div className={styles.A4tab4antique}>
+      <h1>A4tab4antique</h1>
+    </div>
+  )
+}
+
+const MemoA4tab4antique = React.memo(A4tab4antique)
+
+export default MemoA4tab4antique

+ 13 - 0
后台管理/src/store/action/A1record.ts

@@ -64,3 +64,16 @@ export const A1_APIgetRRlist = (id: number) => {
 export const A1_APIsaveRR = (data: any) => {
   return http.post('cms/martyr/relation/save', data)
 }
+
+// --------------生平信息--------------------
+export const A1_APIgetTab1List = (id: number) => {
+  return http.get(`cms/life/getList/${id}`)
+}
+
+export const A1_APIsaveTab1 = (data: any) => {
+  return http.post('cms/life/save', data)
+}
+
+export const A1_APIdelTab1 = (id: number) => {
+  return http.get(`cms/life/remove/${id}`)
+}

+ 20 - 0
后台管理/src/utils/history.ts

@@ -9,3 +9,23 @@ type Option = {
 }
 
 export const myCity: Option[] = myCityTemp
+
+// -------------------富文本回显-------------------
+export const textFu = (val: string) => {
+  let TxtRes = ''
+  try {
+    if (val) {
+      let txt = JSON.parse(val)
+
+      if (txt.txtArr && txt.txtArr.length) {
+        let txt2: string = txt.txtArr[0].txt
+        if (txt2) {
+          const txt3 = txt2.replaceAll('<p></p>', '')
+          if (txt3) TxtRes = txt2
+        }
+      }
+    }
+  } catch (error) {}
+
+  return TxtRes
+}