shaogen1995 пре 1 недеља
родитељ
комит
371cdf1869

+ 21 - 1
后台管理/src/pages/A1record/A1echarts/index.module.scss

@@ -1,5 +1,25 @@
 .A1echarts {
   width: 100%;
   height: 100%;
-  color: aqua;
+  position: relative;
+  :global {
+    #A1echarts {
+      width: 100%;
+      height: 100%;
+    }
+    .A1ECtop {
+      position: absolute;
+      top: 0px;
+      left: 0;
+      z-index: 11;
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      & > div {
+        font-size: 16px;
+        color: var(--themeColor);
+      }
+    }
+  }
 }

+ 128 - 132
后台管理/src/pages/A1record/A1echarts/index.tsx

@@ -1,157 +1,153 @@
-import React, { useCallback, useEffect } from 'react'
+import React, { useCallback, useEffect, useState } from 'react'
 import styles from './index.module.scss'
 
 import * as echarts from 'echarts/core'
 import { TitleComponent, TooltipComponent } from 'echarts/components'
 import { GraphChart } from 'echarts/charts'
 import { CanvasRenderer } from 'echarts/renderers'
+import { Button } from 'antd'
+import A1relation from '../A1relation'
+import { A1_APIgetRRlist } from '@/store/action/A1record'
+import { A1RRlistType } from '../data'
 
 echarts.use([TitleComponent, TooltipComponent, GraphChart, CanvasRenderer])
 
-function A1echarts() {
-  const initFu = useCallback(() => {
-    const dom: HTMLDivElement = document.querySelector('#A1echarts')!
-
-    const myChart = echarts.getInstanceByDom(dom) || echarts.init(dom)
-
-    const option = {
-      series: [
-        {
-          type: 'graph', // 图表类型为关系图
-          layout: 'force', // 使用力导向布局
-          emphasis: { focus: 'adjacency' }, // 高亮时显示相邻节点和边
-          force: {
-            repulsion: 1000, // 节点之间的斥力大小
-            edgeLength: 100 // 边的理想长度
-          },
-          symbolSize: 70, // 默认节点大小
-          roam: true, // 允许缩放和平移
-          // draggable: true, // 允许节点拖动(已注释)
-          edgeSymbol: ['arrow'], // 边的箭头样式
-          label: {
-            show: true, // 显示节点标签
-            position: 'inside', // 标签显示在节点内部
-            color: 'gold' // 标签默认颜色
-          },
-          edgeLabel: {
-            show: true, // 显示边标签
-            fontSize: 12, // 边标签字体大小
-            color: 'red', // 边标签颜色
-            formatter: '{c}', // 显示边的value值
-            rotate: 0 // 强制边标签文字水平显示(新增)
-          },
-          itemStyle: {
-            borderColor: '#04f2a7', // 节点边框颜色
-            borderWidth: 2, // 节点边框宽度
-            shadowBlur: 10, // 阴影模糊大小
-            shadowColor: '#04f2a7', // 阴影颜色
-            color: '#001c43' // 节点默认颜色
-          },
-          lineStyle: {
-            opacity: 0.9, // 边透明度
-            width: 2, // 边宽度
-            curveness: 0.3, // 边弯曲度
-            color: {
-              // 边颜色使用线性渐变
-              type: 'linear',
-              colorStops: [
-                {
-                  offset: 0,
-                  color: '#e0f55a'
-                },
-                {
-                  offset: 1,
-                  color: '#639564'
-                }
-              ]
-            }
-          },
-          data: [
-            // 节点数据
+type Props = {
+  sId: number
+  sName: string
+}
+
+function A1echarts({ sId, sName }: Props) {
+  const [oldList, setOldList] = useState<A1RRlistType[]>([])
+
+  const initFu = useCallback(async () => {
+    const res = await A1_APIgetRRlist(sId)
+    if (res.code === 0) {
+      const listTemp: A1RRlistType[] = res.data || []
+
+      setOldList(listTemp)
+
+      const list1: any[] = []
+      const list2: any[] = []
+
+      listTemp.forEach((v, i) => {
+        list1.push({ name: v.moduleName, symbolSize: [60, 60] })
+
+        list2.push({ source: 0, target: i + 1, value: v.relationModule })
+        list2.push({ source: i + 1, target: 0, value: v.relationMartyr })
+      })
+
+      setTimeout(() => {
+        const dom: HTMLDivElement = document.querySelector('#A1echarts')!
+        const myChart = echarts.getInstanceByDom(dom) || echarts.init(dom)
+
+        const option = {
+          series: [
             {
-              name: '鸡哥', // 节点名称
-              symbolSize: [60, 60], // 节点大小(宽高)
+              type: 'graph', // 图表类型为关系图
+              layout: 'force', // 使用力导向布局
+              emphasis: { focus: 'adjacency' }, // 高亮时显示相邻节点和边
+              force: {
+                repulsion: 1000, // 节点之间的斥力大小
+                edgeLength: 150 // 边的理想长度
+              },
+              symbolSize: 70, // 默认节点大小
+              roam: true, // 允许缩放和平移
+              // draggable: true, // 允许节点拖动(已注释)
+              edgeSymbol: ['arrow'], // 边的箭头样式
               label: {
-                color: '#fff', // 标签颜色
-                fontSize: 16, // 标签字体大小
-                fontWeight: 'bold' // 标签字体粗细
+                show: true, // 显示节点标签
+                position: 'inside', // 标签显示在节点内部
+                color: 'black' // 标签默认颜色
+              },
+              edgeLabel: {
+                show: true, // 显示边标签
+                fontSize: 14, // 边标签字体大小
+                color: 'red', // 边标签颜色
+                formatter: '{c}', // 显示边的value值
+                rotate: 0 // 强制边标签文字水平显示(新增)
               },
               itemStyle: {
-                color: 'red' // 节点颜色
-              }
-            },
-            {
-              name: '傻星',
-              symbolSize: [40, 40]
-            },
-            {
-              name: '王大锤',
-              symbolSize: [40, 40]
-            },
-            {
-              name: '彭于晏',
-              symbolSize: [40, 40]
-            },
-            {
-              name: '笑嘻嘻',
-              symbolSize: [40, 40]
-            }
-          ],
-          links: [
-            // 边数据
-            {
-              source: 0, // 源节点索引
-              target: 1, // 目标节点索引
-              value: '孙子' // 边显示的值
-            },
-            {
-              source: 1,
-              target: 0,
-              value: '爷爷'
-            },
-            {
-              source: 0,
-              target: 2,
-              value: '儿子'
-            },
-            {
-              source: 2,
-              target: 0,
-              value: '父亲'
-            },
-            {
-              source: 0,
-              target: 3,
-              value: '小弟'
-            },
-            {
-              source: 3,
-              target: 0,
-              value: '老大'
-            },
-            {
-              source: 0,
-              target: 4,
-              value: '小弟'
-            },
-            {
-              source: 4,
-              target: 0,
-              value: '老大'
+                borderColor: '#d9622c', // 节点边框颜色
+                borderWidth: 2, // 节点边框宽度
+                shadowBlur: 10, // 阴影模糊大小
+                shadowColor: '#d9622c', // 阴影颜色
+                color: '#fff' // 节点默认颜色
+              },
+              lineStyle: {
+                opacity: 0.9, // 边透明度
+                width: 2, // 边宽度
+                curveness: 0.3, // 边弯曲度
+                color: {
+                  // 边颜色使用线性渐变
+                  type: 'linear',
+                  colorStops: [
+                    {
+                      offset: 0,
+                      color: '#e99a75ff'
+                    },
+                    {
+                      offset: 1,
+                      color: '#d9622c'
+                    }
+                  ]
+                }
+              },
+              data: [
+                // 节点数据
+                {
+                  name: sName, // 节点名称
+                  symbolSize: [80, 80], // 节点大小(宽高)
+                  label: {
+                    color: '#fff', // 标签颜色
+                    fontSize: 16, // 标签字体大小
+                    fontWeight: 'bold' // 标签字体粗细
+                  },
+                  itemStyle: {
+                    color: '#d9622c' // 节点颜色
+                  }
+                },
+                ...list1
+              ],
+              links: list2
             }
           ]
         }
-      ]
-    }
 
-    option && myChart.setOption(option)
-  }, [])
+        option && myChart.setOption(option)
+      }, 200)
+    }
+  }, [sId, sName])
 
   useEffect(() => {
     initFu()
   }, [initFu])
 
-  return <div className={styles.A1echarts} id='A1echarts'></div>
+  // 编辑关系图
+  const [showId, setShowId] = useState(0)
+
+  return (
+    <div className={styles.A1echarts}>
+      <div id='A1echarts'></div>
+
+      <div className='A1ECtop'>
+        <div>人物关系图</div>
+        <Button type='primary' onClick={() => setShowId(sId)}>
+          编辑
+        </Button>
+      </div>
+
+      {showId ? (
+        <A1relation
+          sId={showId}
+          sName={sName}
+          closeFu={() => setShowId(0)}
+          upDataFu={initFu}
+          oldList={oldList}
+        />
+      ) : null}
+    </div>
+  )
 }
 
 const MemoA1echarts = React.memo(A1echarts)

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

@@ -20,9 +20,33 @@
       .A1Top1 {
         width: calc(100% - 600px);
         margin-right: 20px;
+
+        .A1topRow {
+          display: flex;
+          font-size: 16px;
+          margin-bottom: 10px;
+          .A1top1LL {
+            font-weight: 700;
+            width: 82px;
+            text-align: right;
+          }
+          .A1top1RR {
+            width: calc(100% - 82px);
+            word-wrap: break-word;
+            white-space: pre-wrap;
+            // 图片查看调整
+            .ZTboxImgMain {
+              margin-top: 0;
+            }
+            .ZcheckTxt {
+              display: none;
+            }
+          }
+        }
       }
       .A1Top2 {
         width: 580px;
+        height: auto;
         display: flex;
         justify-content: center;
         align-items: center;
@@ -30,6 +54,7 @@
     }
 
     .A1Tab {
+      min-height: calc(100% - 415px);
       background-color: #fff;
       border-radius: 10px;
       padding: 15px;

+ 133 - 44
后台管理/src/pages/A1record/A1look/index.tsx

@@ -1,51 +1,140 @@
-import React from 'react'
+import React, { useCallback, useEffect, useRef, useState } from 'react'
 import styles from './index.module.scss'
 import A1echarts from '../A1echarts'
-function A1look() {
+import { A1_APIgetInfo } from '@/store/action/A1record'
+import { A1ListType, jiGuanFu } from '../data'
+import ZupTypes from '@/components/ZupTypes'
+import ZupVideos from '@/components/ZupVideos'
+
+type Props = {
+  sId: number
+}
+
+function A1look({ sId }: Props) {
+  // 多张图片的ref
+  const ZupImgsRef = useRef<any>(null)
+
+  // 多个视频的ref
+  const ZupVideosRef = useRef<any>(null)
+
+  const [info, setInfo] = useState({} as A1ListType)
+
+  useEffect(() => {
+    const file = info.img || []
+    // 传给 附件 组件的
+    const sonInfo = {
+      type: 'img',
+      fileList: file
+    }
+    ZupImgsRef.current?.setFileComFileFu(sonInfo)
+    ZupVideosRef.current?.setFileComFileFu(info.video || [])
+  }, [info])
+
+  const [loding, setLoding] = useState(false)
+
+  // 编辑进来获取详情
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A1_APIgetInfo(id)
+    if (res.code === 0) {
+      setInfo(res.data)
+      setLoding(true)
+    }
+  }, [])
+
+  useEffect(() => {
+    getInfoFu(sId)
+  }, [getInfoFu, sId])
+
   return (
     <div className={styles.A1look}>
-      <div className='A1Top'>
-        <div className='A1Top1'>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-          <h1>asdasd</h1>
-        </div>
-        <div className='A1Top2'>
-          <A1echarts />
-        </div>
-      </div>
-
-      <div className='A1Tab'>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-        <h1>asdasd</h1>
-      </div>
+      {loding ? (
+        <>
+          <div className='A1Top'>
+            <div className='A1Top1'>
+              <div className='A1topRow'>
+                <div className='A1top1LL'>基本信息:</div>
+                <div className='A1top1RR'>
+                  {info.name} | {info.gender === 1 ? '男' : '女'}{' '}
+                  {info.nation ? ` | ${info.nation}` : ''}&emsp;&emsp;
+                  {info.dateStart || info.dateEnd
+                    ? (info.dateStart || '(空)') + ' ~ ' + (info.dateEnd || '(空)')
+                    : ''}
+                </div>
+              </div>
+              <div className='A1topRow'>
+                <div className='A1top1LL'>番号:</div>
+                <div className='A1top1RR'>{info.dictPanName || '(空)'}</div>
+              </div>
+              <div className='A1topRow'>
+                <div className='A1top1LL'>籍贯:</div>
+                <div
+                  className='A1top1RR'
+                  dangerouslySetInnerHTML={{ __html: jiGuanFu(info, true) }}
+                ></div>
+              </div>
+              <div className='A1topRow'>
+                <div className='A1top1LL'>牺牲地:</div>
+                <div
+                  className='A1top1RR'
+                  dangerouslySetInnerHTML={{ __html: jiGuanFu(info, true, '牺牲地') }}
+                ></div>
+              </div>
+              <div className='A1topRow'>
+                <div className='A1top1LL'>个人介绍:</div>
+                <div className='A1top1RR'>{info.intro || '(空)'}</div>
+              </div>
+              <div className='A1topRow'>
+                <div className='A1top1LL'>图片:</div>
+                <div className='A1top1RR'>
+                  {info.img.length === 0 ? '(空)' : ''}
+                  <ZupTypes
+                    ref={ZupImgsRef}
+                    isLook={true}
+                    fileCheck={false}
+                    selecFlag='图片'
+                    imgSize={5}
+                    imgLength={50}
+                    dirCode='A1record'
+                    myUrl='cms/martyr/upload'
+                    isTypeShow={true}
+                    oneIsCover={true}
+                  />
+                </div>
+              </div>
+
+              <div className='A1topRow'>
+                <div className='A1top1LL'>视频:</div>
+                <div className='A1top1RR'>
+                  <ZupVideos
+                    isLook={true}
+                    size={500}
+                    fileNum={50}
+                    dirCode='A1recordVideo'
+                    myUrl='cms/martyr/upload'
+                    upTxt=';数量不超过50个。'
+                    ref={ZupVideosRef}
+                  />
+                </div>
+              </div>
+
+              <div className='A1topRow'>
+                <div className='A1top1LL'>场景链接:</div>
+                <div className='A1top1RR'>{info.link || '(空)'}</div>
+              </div>
+
+              <div className='A1topRow'>
+                <div className='A1top1LL'>备注:</div>
+                <div className='A1top1RR'>{info.remark || '(空)'}</div>
+              </div>
+            </div>
+            <div className='A1Top2'>
+              <A1echarts sId={info.id} sName={info.name} />
+            </div>
+          </div>
+
+          <div className='A1Tab'></div>
+        </>
+      ) : null}
     </div>
   )
 }

+ 89 - 0
后台管理/src/pages/A1record/A1relation/index.module.scss

@@ -0,0 +1,89 @@
+.A1relation {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal {
+      width: 800px !important;
+    }
+    .ant-modal-content {
+      overflow: hidden;
+    }
+    .A1Rtit {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      border-bottom: 1px solid #ccc;
+      padding-bottom: 10px;
+      margin-bottom: 15px;
+    }
+
+    .A1Rmain {
+      max-height: 500px;
+      overflow: auto;
+      .A1Rrow {
+        background-color: #dfdfdf;
+        border-radius: 6px;
+        padding: 8px;
+        width: 500px;
+        margin: 0 auto 10px;
+        height: 122px;
+        position: relative;
+
+        .A1RrowIndex {
+          position: absolute;
+          left: -20px;
+          top: 0px;
+        }
+      }
+      .A1Rrow1 {
+        display: flex;
+        justify-content: center;
+        .anticon-delete {
+          font-size: 20px;
+          margin-left: 10px;
+          cursor: pointer;
+        }
+      }
+      .A1Rrow2 {
+        display: flex;
+        height: 22px;
+        margin: 10px 0;
+        & > div {
+          width: 50%;
+        }
+      }
+      .A1Rrow3 {
+        display: flex;
+        & > div {
+          width: 50%;
+          .ant-input-affix-wrapper {
+            width: 90%;
+          }
+        }
+      }
+    }
+
+    .A1Rbtn {
+      margin-top: 10px;
+      text-align: center;
+      position: relative;
+      padding-bottom: 15px;
+      & > p {
+        position: absolute;
+        top: -3px;
+        left: 50%;
+        transform: translateX(-50%);
+        margin-top: 5px;
+        color: #ff4d4f;
+        opacity: 0;
+        pointer-events: none;
+        transition: all 0.3s;
+      }
+      .A1RbtnTxt {
+        top: 30px;
+        opacity: 1;
+      }
+    }
+  }
+}

+ 245 - 0
后台管理/src/pages/A1record/A1relation/index.tsx

@@ -0,0 +1,245 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Empty, Input, Modal, Select } from 'antd'
+import { MessageFu } from '@/utils/message'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { A1RRlistType } from '../data'
+import { useDispatch, useSelector } from 'react-redux'
+import { A1_APIgetList, A1_APIsaveRR } from '@/store/action/A1record'
+import { RootState } from '@/store'
+import { DeleteOutlined } from '@ant-design/icons'
+import classNames from 'classnames'
+
+type Props = {
+  sId: number
+  sName: string
+  closeFu: () => void
+  upDataFu: () => void
+  oldList: A1RRlistType[]
+}
+
+function A1relation({ sId, closeFu, upDataFu, oldList, sName }: Props) {
+  // 获取所有烈士信息
+  const dispatch = useDispatch()
+
+  useEffect(() => {
+    dispatch(
+      A1_APIgetList({
+        pageNum: 1,
+        pageSize: 99999
+      })
+    )
+  }, [dispatch])
+
+  const listAll = useSelector((state: RootState) => state.A1record.tableInfo.list)
+  const [list, setList] = useState<A1RRlistType[]>([])
+
+  const listAllRes = useMemo(() => {
+    return listAll
+      .filter(v => v.id !== sId)
+      .map(c => ({
+        value: c.id,
+        label: c.name,
+        disabled: list.map(q => q.moduleId).includes(c.id)
+      }))
+  }, [list, listAll, sId])
+  // 获取所有烈士信息-end
+
+  // useEffect(() => {
+  //   console.log('xxxxx', list)
+  // }, [list])
+
+  const [loding, setLoding] = useState(false)
+
+  useEffect(() => {
+    setList(oldList)
+    setLoding(true)
+  }, [oldList])
+
+  // 点击删除
+  const delArrRef = useRef<number[]>([])
+
+  const delOneFu = useCallback(
+    (item: A1RRlistType) => {
+      if (!item.isNew) delArrRef.current.push(item.id)
+      setList(list.filter(v => v.id !== item.id))
+    },
+    [list]
+  )
+
+  // 下拉框的改变
+  const selectChangeFu = useCallback(
+    (id: number, value: any, key: 'moduleId' | 'relationMartyr' | 'relationModule') => {
+      // if (list.find(v => v.moduleId === id)) {
+      //   return MessageFu.warning('不可重复选择')
+      // }
+
+      setList(
+        list.map(v => ({
+          ...v,
+          [key]: v.id === id ? value : v[key]
+        }))
+      )
+    },
+    [list]
+  )
+
+  // 下拉框id转换成lable
+  const selectNameRes = useCallback(
+    (moduleId: number) => {
+      let txt = ''
+      const obj = listAllRes.find(v => v.value === moduleId)
+      if (obj) txt = obj.label
+      return txt
+    },
+    [listAllRes]
+  )
+
+  // 是否可以点击确定 为true表示不满足,不能点击
+  const isOkFlag = useMemo(() => {
+    let index = 0
+    const findIndex = list.findIndex(v => !v.moduleId || !v.relationModule || !v.relationMartyr)
+
+    if (findIndex >= 0) index = findIndex + 1
+
+    return index
+  }, [list])
+
+  // 点击提交
+  const addBtn = useCallback(async () => {
+    const obj = {
+      delIds: delArrRef.current,
+      relation: list.map(v => ({
+        id: v.isNew ? null : v.id,
+        martyrId: sId,
+        moduleId: v.moduleId,
+        relationMartyr: v.relationMartyr,
+        relationModule: v.relationModule,
+        type: 'martyr'
+      }))
+    }
+    const res = await A1_APIsaveRR(obj)
+    if (res.code === 0) {
+      MessageFu.success('编辑成功')
+      upDataFu()
+      closeFu()
+    }
+  }, [closeFu, list, sId, upDataFu])
+
+  return (
+    <Modal
+      wrapClassName={styles.A1relation}
+      open={true}
+      title={
+        <div className='A1Rtit'>
+          <div>关联烈士</div>
+          <Button
+            type='primary'
+            onClick={() => {
+              if (list.length >= 50) return MessageFu.warning('可关联最多50个烈士')
+              setList([
+                ...list,
+                {
+                  id: Date.now(),
+                  moduleName: '',
+                  moduleId: null,
+                  relationMartyr: '',
+                  relationModule: '',
+                  isNew: true
+                }
+              ])
+            }}
+          >
+            新增
+          </Button>
+        </div>
+      }
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='A1Rmain'>
+        {list.length === 0 && loding ? (
+          <div style={{ textAlign: 'center' }}>
+            <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
+          </div>
+        ) : (
+          <>
+            {list.map((item, index) => (
+              <div className='A1Rrow' key={item.id}>
+                <div className='A1RrowIndex'>{index + 1}:</div>
+
+                <div className='A1Rrow1'>
+                  <Select
+                    style={{ width: 455 }}
+                    getPopupContainer={() => document.querySelector('.ant-modal-content')!}
+                    filterOption={(input, option) =>
+                      (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
+                    }
+                    allowClear
+                    placeholder='请搜索并选择'
+                    showSearch
+                    options={listAllRes}
+                    value={item.moduleId || null}
+                    onChange={e => selectChangeFu(item.id, e, 'moduleId')}
+                  />
+                  <MyPopconfirm
+                    txtK='删除'
+                    onConfirm={() => delOneFu(item)}
+                    Dom={<DeleteOutlined />}
+                  />
+                </div>
+                <div className='A1Rrow2'>
+                  <div>
+                    {selectNameRes(item.moduleId!)} → {sName}
+                  </div>
+                  <div>
+                    {sName} → {selectNameRes(item.moduleId!)}
+                  </div>
+                </div>
+
+                <div className='A1Rrow3'>
+                  <div>
+                    <Input
+                      placeholder='请输入'
+                      maxLength={10}
+                      showCount
+                      value={item.relationModule}
+                      onChange={e =>
+                        selectChangeFu(item.id, e.target.value.trim(), 'relationModule')
+                      }
+                    />
+                  </div>
+                  <div>
+                    <Input
+                      placeholder='请输入'
+                      maxLength={10}
+                      showCount
+                      value={item.relationMartyr}
+                      onChange={e =>
+                        selectChangeFu(item.id, e.target.value.trim(), 'relationMartyr')
+                      }
+                    />
+                  </div>
+                </div>
+              </div>
+            ))}
+          </>
+        )}
+      </div>
+
+      <div className='A1Rbtn'>
+        <Button type='primary' onClick={addBtn} disabled={!!isOkFlag}>
+          提交
+        </Button>
+        &emsp;
+        <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+        <p className={classNames(isOkFlag ? 'A1RbtnTxt' : '')}>请完善第 {isOkFlag} 条关联信息</p>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoA1relation = React.memo(A1relation)
+
+export default MemoA1relation

+ 28 - 0
后台管理/src/pages/A1record/data.ts

@@ -270,3 +270,31 @@ export const nationSelect = [
 
 // 番号相关
 export type NumListType = { id: number; name: string }
+
+// 处理籍贯
+export const jiGuanFu = (item: A1ListType, flag = false, val = '籍贯') => {
+  let res = '(空)'
+
+  const val1 = val === '籍贯' ? 'nativeProvince' : 'lossProvince'
+  const val2 = val === '籍贯' ? 'nativeCity' : 'lossCity'
+  const val3 = val === '籍贯' ? 'nativeRegion' : 'lossRegion'
+  const val4 = val === '籍贯' ? 'nativeAddress' : 'lossAddress'
+
+  if (item[val1]) res = item[val1]
+  if (item[val2]) res += ` / ${item[val2]}`
+  if (item[val3]) res += ` / ${item[val3]}`
+  if (item[val4]) res += `${flag ? '&emsp;&emsp;' : ' - '}${item[val4]}`
+  return res
+}
+
+// 人物关系图
+
+export type A1RRlistType = {
+  id: number
+  // martyrName: string //当前烈士
+  moduleName: string //选择了关联烈士
+  moduleId: number | null
+  relationMartyr: string
+  relationModule: string
+  isNew?: boolean
+}

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

@@ -2,6 +2,13 @@
   position: relative;
 
   :global {
+    .A1LookBack {
+      position: absolute;
+      top: -5px;
+      left: 200px;
+      z-index: 12;
+    }
+
     .A1top {
       padding: 15px 24px;
       border-radius: 10px;

+ 16 - 32
后台管理/src/pages/A1record/index.tsx

@@ -7,9 +7,7 @@ import { RootState } from '@/store'
 import { MessageFu } from '@/utils/message'
 import { Button, Input, Table } from 'antd'
 import MyPopconfirm from '@/components/MyPopconfirm'
-import { A1ListType, LookInfoType } from './data'
-import MyTable from '@/components/MyTable'
-import { A1tableC } from '@/utils/tableData'
+import { A1ListType, jiGuanFu, LookInfoType } from './data'
 import A1add from './A1add'
 import ImageLazy from '@/components/ImageLazy'
 
@@ -99,24 +97,13 @@ function A1record() {
       {
         title: '籍贯',
 
-        render: (item: A1ListType) => {
-          let res = '(空)'
-          if (item.nativeProvince) res = item.nativeProvince
-          if (item.nativeCity) res += ` / ${item.nativeCity}`
-          if (item.nativeRegion) res += ` / ${item.nativeRegion}`
-          if (item.nativeAddress) res += ` - ${item.nativeAddress}`
-          return res
-        }
+        render: (item: A1ListType) => jiGuanFu(item)
       },
       {
-        title: '出生年份',
-        width: 100,
-        render: (item: A1ListType) => item.dateStart || '(空)'
-      },
-      {
-        title: '死亡年份',
-        width: 100,
-        render: (item: A1ListType) => item.dateEnd || '(空)'
+        title: '生卒',
+        width: 200,
+        render: (item: A1ListType) =>
+          (item.dateStart || '(空)') + ' ~ ' + (item.dateEnd || '(空)')
       },
 
       {
@@ -167,7 +154,14 @@ function A1record() {
 
   return (
     <div className={styles.A1record}>
-      <div className='pageTitle'>烈士档案{lookInfo.txt ? ` - ${lookInfo.txt}` : ''}</div>
+      <div className='pageTitle'>
+        烈士档案{lookInfo.txt ? ` - ${lookInfo.txt}` : ''}{' '}
+        {lookInfo.txt === '查看' ? (
+          <div onClick={() => setLookInfo({ id: 0, txt: '' })} className='A1LookBack'>
+            <Button>返回</Button>
+          </div>
+        ) : null}
+      </div>
 
       {/* 顶部筛选 */}
       <div className='A1top'>
@@ -211,17 +205,6 @@ function A1record() {
             onChange: (pageNum, pageSize) => setFromData({ ...fromData, pageNum, pageSize })
           }}
         />
-
-        {/* <MyTable
-          yHeight={645}
-          list={tableInfo.list}
-          columnsTemp={A1tableC}
-          lastBtn={tableLastBtn}
-          pageNum={fromData.pageNum}
-          pageSize={fromData.pageSize}
-          total={tableInfo.total}
-          onChange={(pageNum, pageSize) => setFromData({ ...fromData, pageNum, pageSize })}
-        /> */}
       </div>
 
       {['新增', '编辑'].includes(lookInfo.txt) ? (
@@ -232,7 +215,8 @@ function A1record() {
           upTableFu={getListFu}
         />
       ) : null}
-      {/* <A1look /> */}
+
+      {lookInfo.txt === '查看' ? <A1look sId={lookInfo.id} /> : null}
     </div>
   )
 }

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

@@ -55,3 +55,12 @@ export const A1_APINumdel = (id: number) => {
 export const A1_APINumSave = (data: any) => {
   return http.post('cms/dict/save', data)
 }
+
+// --------------人物关系图--------------------
+export const A1_APIgetRRlist = (id: number) => {
+  return http.get(`cms/martyr/relation/${id}`)
+}
+
+export const A1_APIsaveRR = (data: any) => {
+  return http.post('cms/martyr/relation/save', data)
+}