Quellcode durchsuchen

级联多选数据保存和回显修改

shaogen1995 vor 2 Tagen
Ursprung
Commit
1661de9d45

+ 3 - 0
src/pages/Dmanage/D2edit/D2info/index.tsx

@@ -83,6 +83,9 @@ function D2info() {
       }
 
       if (keyArr.includes('fileIds')) {
+        oldInfo.fileIds = oldInfo.fileIds || ''
+        newInfo.fileIds = newInfo.fileIds || ''
+
         // 有藏品附件
         let ids: any = new Set([...oldInfo['fileIds'].split(','), ...newInfo['fileIds'].split(',')])
 

+ 13 - 31
src/pages/Hexhibits/H1loan/H1detail/index.tsx

@@ -24,6 +24,7 @@ import { selectObj } from '@/utils/dataChange'
 import { showGoodTableC } from '@/utils/tableData'
 import store from '@/store'
 import { tagApiArr } from '@/pages/ZgoodsInfo/data'
+const { SHOW_CHILD } = Cascader
 
 type DetailInfo = {
   id?: number
@@ -147,8 +148,8 @@ function H1detail() {
     typeDictId: undefined as (string | number)[] | undefined,
     region: undefined as string | undefined,
     status: undefined as number | undefined,
-    subTagIds: '',
-    subArtDictIds: ''
+    subTagIds: '' as any,
+    subArtDictIds: '' as any
   })
   const goodFormDataRef = useRef(goodFormData)
   useEffect(() => {
@@ -168,11 +169,10 @@ function H1detail() {
 
     // 针对 多个标签的数据处理
     tagApiArr.forEach(v => {
-      if (params[v] && typeof params[v] === 'string') {
-        params[v] = params[v]
-          .replaceAll(';', ',')
-          .split(',')
-          .map((v: any) => Number(v))
+      if (params[v] && params[v].length) {
+        params[v] = params[v].map((c: any) => {
+          return Number(c[c.length - 1])
+        })
       }
     })
 
@@ -391,23 +391,14 @@ function H1detail() {
             fieldNames={{ label: 'name', value: 'id', children: 'children' }}
             allowClear={true}
             showSearch={true}
-            value={
-              goodFormData.subTagIds
-                ? goodFormData.subTagIds.split(';').map((item: string) => item.split(','))
-                : []
-            }
+            value={goodFormData.subTagIds ? goodFormData.subTagIds : []}
             onChange={e => {
               const seLectArr: any = e || []
-              let temp = ''
-              if (seLectArr.length) {
-                seLectArr.forEach((v: string[], i: number) => {
-                  temp += v.join(',') + (i === seLectArr.length - 1 ? '' : ';')
-                })
-              }
-              setGoodFormData({ ...goodFormData, subTagIds: temp })
+              setGoodFormData({ ...goodFormData, subTagIds: seLectArr })
             }}
             multiple
             maxTagCount='responsive'
+            showCheckedStrategy={SHOW_CHILD}
           />
           <Select
             placeholder='级别'
@@ -424,23 +415,14 @@ function H1detail() {
             fieldNames={{ label: 'name', value: 'id', children: 'children' }}
             allowClear={true}
             showSearch={true}
-            value={
-              goodFormData.subArtDictIds
-                ? goodFormData.subArtDictIds.split(';').map((item: string) => item.split(','))
-                : []
-            }
+            value={goodFormData.subArtDictIds ? goodFormData.subArtDictIds : []}
             onChange={e => {
               const seLectArr: any = e || []
-              let temp = ''
-              if (seLectArr.length) {
-                seLectArr.forEach((v: string[], i: number) => {
-                  temp += v.join(',') + (i === seLectArr.length - 1 ? '' : ';')
-                })
-              }
-              setGoodFormData({ ...goodFormData, subArtDictIds: temp })
+              setGoodFormData({ ...goodFormData, subArtDictIds: seLectArr })
             }}
             multiple
             maxTagCount='responsive'
+            showCheckedStrategy={SHOW_CHILD}
           />
           <Select
             placeholder='展区'

+ 15 - 9
src/pages/Zother/AddClues/index.tsx

@@ -12,6 +12,8 @@ import Z3upFilesRef from '@/components/Z3upFilesRef'
 import MyPopconfirm from '@/components/MyPopconfirm'
 import { useSelector } from 'react-redux'
 import { RootState } from '@/store'
+import { convertLeafIdsToPaths } from '@/utils/tagShow'
+const { SHOW_CHILD } = Cascader
 
 type Props = {
   info: GoodsType
@@ -49,10 +51,11 @@ function AddClues({ closeFu, succFu, moduleId, info, fileUpInfo, isLook }: Props
         if (!obj[v]) obj[v] = null
       })
 
-      if (obj.tagDictId) {
-        const tagDictId = obj.tagDictId.split(';').map((item: string) => item.split(','))
-        obj.tagDictId = tagDictId
-      }
+      // if (obj.tagDictId) {
+      //   const tagDictId = obj.tagDictId.split(';').map((item: string) => item.split(','))
+      //   obj.tagDictId = tagDictId
+      // }
+      if (obj.tagDictId) obj.tagDictId = convertLeafIdsToPaths(obj.tagDictId, '藏品')
 
       FormBoxRef.current?.setFieldsValue(obj)
 
@@ -96,20 +99,22 @@ function AddClues({ closeFu, succFu, moduleId, info, fileUpInfo, isLook }: Props
       cascaderChArr.forEach(v => {
         if (values[v]) obj[v] = values[v].join(',')
       })
-      // if (1 + 1 === 2) {
-      //   console.log(123, obj)
-      //   return
-      // }
 
       let tagDictId = ''
       if (obj.tagDictId.length) {
         obj.tagDictId.forEach((v: string[], i: number) => {
-          tagDictId += v.join(',') + (i === obj.tagDictId.length - 1 ? '' : ';')
+          tagDictId += v[v.length - 1] + (i === obj.tagDictId.length - 1 ? '' : ',')
         })
       }
 
       obj.tagDictId = tagDictId
 
+      // if (1 + 1 === 2) {
+      //   console.log('-------', values.tagDictId, tagDictId)
+
+      //   return
+      // }
+
       MessageFu.success(info.id > 0 ? '编辑成功' : '新增成功')
       succFu(info.id > 0 ? '编辑' : '新增', obj)
       closeFu()
@@ -181,6 +186,7 @@ function AddClues({ closeFu, succFu, moduleId, info, fileUpInfo, isLook }: Props
                 showSearch={true}
                 multiple
                 maxTagCount='responsive'
+                showCheckedStrategy={SHOW_CHILD}
               />
             </Form.Item>
 

+ 20 - 8
src/pages/Zother/AddGoods/index.tsx

@@ -15,8 +15,14 @@ import { API_getGoodsInfo } from '@/store/action/Cledger/C1ledger'
 import { MessageFu } from '@/utils/message'
 import { API_getFileListByIds } from '@/store/action/Cledger/C4file'
 import { FileUpInfoType } from '../data'
+import { convertLeafIdsToPaths } from '@/utils/tagShow'
+const { SHOW_CHILD } = Cascader
 
-export const jiLianDuoArr = ['artDictId', 'tagDictId', 'textureDictId']
+export const jiLianDuoArr = [
+  { key: 'artDictId', tag: '文创' },
+  { key: 'tagDictId', tag: '藏品' },
+  { key: 'textureDictId', tag: '质地3' }
+]
 
 // 级联的数据转换成字符串
 export const cascaderChArr = [
@@ -99,12 +105,15 @@ function AddGoods({
 
       // 处理多选的级联标签
       jiLianDuoArr.forEach(v => {
-        if (obj[v]) {
-          const temp = obj[v].split(';').map((item: string) => item.split(','))
-          obj[v] = temp
+        if (obj[v.key]) {
+          obj[v.key] = convertLeafIdsToPaths(obj[v.key], v.tag as '藏品')
         }
       })
 
+      if (!obj.makeDate) obj.makeDate = dayjs()
+      if (!obj.makeUser) obj.makeUser = getTokenInfo().user.realName
+      // if (!obj.inGoodYear) obj.inGoodYear = dayjs()
+
       FormBoxRef.current?.setFieldsValue(obj)
 
       // 设置附件
@@ -180,13 +189,13 @@ function AddGoods({
 
       jiLianDuoArr.forEach(v => {
         let temp = ''
-        if (obj[v].length) {
-          obj[v].forEach((c: string[], i: number) => {
-            temp += c.join(',') + (i === obj[v].length - 1 ? '' : ';')
+        if (obj[v.key].length) {
+          obj[v.key].forEach((c: string[], i: number) => {
+            temp += c[c.length - 1] + (i === obj[v.key].length - 1 ? '' : ',')
           })
         }
 
-        obj[v] = temp
+        obj[v.key] = temp
       })
 
       if (isEdit) {
@@ -298,6 +307,7 @@ function AddGoods({
                 showSearch={true}
                 multiple
                 maxTagCount='responsive'
+                showCheckedStrategy={SHOW_CHILD}
               />
             </Form.Item>
 
@@ -351,6 +361,7 @@ function AddGoods({
                 showSearch={true}
                 multiple
                 maxTagCount='responsive'
+                showCheckedStrategy={SHOW_CHILD}
               />
             </Form.Item>
 
@@ -425,6 +436,7 @@ function AddGoods({
                   showSearch={true}
                   multiple
                   maxTagCount='responsive'
+                  showCheckedStrategy={SHOW_CHILD}
                 />
               </Form.Item>
             </div>

+ 2 - 2
src/pages/Zother/EditBtn/index.tsx

@@ -145,8 +145,8 @@ function EditBtn({
           })
         })
 
-        // 没有选择关联藏品的时候,只存下面的字段
-        if (snaps.length === 0) {
+        // 没有选择关联藏品的时候并且是有第二个模块,只存下面的字段
+        if (snaps.length === 0 && isTow) {
           let snapSon: any = {}
           snapSon = {
             ...info2

+ 8 - 17
src/pages/Zother/SelectGoods/index.tsx

@@ -9,6 +9,7 @@ import MyPopconfirm from '@/components/MyPopconfirm'
 import AddClues from '../AddClues'
 import { FileUpInfoType } from '../data'
 import { tagApiArr } from '@/pages/ZgoodsInfo/data'
+const { SHOW_CHILD } = Cascader
 
 type Props = {
   API_getList: any
@@ -77,11 +78,10 @@ function SelectGoods({
 
     // 针对 多个标签的数据处理
     tagApiArr.forEach(v => {
-      if (obj[v] && typeof obj[v] === 'string') {
-        obj[v] = obj[v]
-          .replaceAll(';', ',')
-          .split(',')
-          .map((v: any) => Number(v))
+      if (obj[v] && obj[v].length) {
+        obj[v] = obj[v].map((c: any) => {
+          return Number(c[c.length - 1])
+        })
       }
     })
 
@@ -229,23 +229,14 @@ function SelectGoods({
                 fieldNames={{ label: 'name', value: 'id', children: 'children' }}
                 allowClear={!item.must}
                 showSearch={true}
-                value={
-                  formData[item.key]
-                    ? formData[item.key].split(';').map((item: string) => item.split(','))
-                    : []
-                }
+                value={formData[item.key] ? formData[item.key] : []}
                 onChange={e => {
                   const seLectArr: any = e || []
-                  let temp = ''
-                  if (seLectArr.length) {
-                    seLectArr.forEach((v: string[], i: number) => {
-                      temp += v.join(',') + (i === seLectArr.length - 1 ? '' : ';')
-                    })
-                  }
-                  setFormData({ ...formData, [item.key]: temp })
+                  setFormData({ ...formData, [item.key]: seLectArr })
                 }}
                 multiple
                 maxTagCount='responsive'
+                showCheckedStrategy={SHOW_CHILD}
               />
             ) : null}
           </div>

+ 8 - 17
src/pages/Zother/TableList/index.tsx

@@ -16,6 +16,7 @@ import MyTable from '@/components/MyTable'
 import dayjs from 'dayjs'
 import { tagApiArr } from '@/pages/ZgoodsInfo/data'
 const { RangePicker } = DatePicker
+const { SHOW_CHILD } = Cascader
 
 type Props = {
   baseFormData: any
@@ -110,11 +111,10 @@ const TableList = forwardRef<any, Props>(function TableList(props, ref) {
     })
     // 针对 多个标签的数据处理
     tagApiArr.forEach(v => {
-      if (params[v] && typeof params[v] === 'string') {
-        params[v] = params[v]
-          .replaceAll(';', ',')
-          .split(',')
-          .map((v: any) => Number(v))
+      if (params[v] && params[v].length) {
+        params[v] = params[v].map((c: any) => {
+          return Number(c[c.length - 1])
+        })
       }
     })
 
@@ -245,23 +245,14 @@ const TableList = forwardRef<any, Props>(function TableList(props, ref) {
                   fieldNames={{ label: 'name', value: 'id', children: 'children' }}
                   allowClear={!item.must}
                   showSearch={true}
-                  value={
-                    formData[item.key]
-                      ? formData[item.key].split(';').map((item: string) => item.split(','))
-                      : []
-                  }
+                  value={formData[item.key] ? formData[item.key] : []}
                   onChange={e => {
                     const seLectArr: any = e || []
-                    let temp = ''
-                    if (seLectArr.length) {
-                      seLectArr.forEach((v: string[], i: number) => {
-                        temp += v.join(',') + (i === seLectArr.length - 1 ? '' : ';')
-                      })
-                    }
-                    setFormData({ ...formData, [item.key]: temp })
+                    setFormData({ ...formData, [item.key]: seLectArr })
                   }}
                   multiple
                   maxTagCount='responsive'
+                  showCheckedStrategy={SHOW_CHILD}
                 />
               ) : null}
             </div>

+ 3 - 5
src/utils/dataChange.tsx

@@ -209,7 +209,7 @@ export function resTagFu(idString: string, type: '藏品' | '文创' | '质地3'
       ? store.getState().E1tag.treeData
       : type === '文创'
         ? store.getState().E3label.treeData
-        : store.getState().I2dict.dictAll
+        : getDictFu('质地3')!
 
   // 1. 构建ID到名称的映射
   const idToNameMap = new Map<string, string>()
@@ -224,11 +224,9 @@ export function resTagFu(idString: string, type: '藏品' | '文创' | '质地3'
 
   // 2. 解析ID字符串并映射为名称
   return idString
-    .split(';')
+    .split(',')
     .map(part => {
-      const ids = part.split(',').map(id => id.trim())
-      const targetId = ids[ids.length - 1] // 取路径最后一个ID
-      return idToNameMap.get(targetId) || ''
+      return idToNameMap.get(part) || ''
     })
     .filter(name => name) // 过滤空值(可选,根据需要调整)
     .join(';') // 使用中文分号拼接

+ 82 - 0
src/utils/tagShow.ts

@@ -0,0 +1,82 @@
+import { TypeI5Tree } from '@/pages/Isystem/I5organization/data'
+import store from '@/store'
+import { getDictFu } from './dataChange'
+
+// 多级联通过最后一级的id返回二维数组
+export function convertLeafIdsToPaths(
+  leafIds: string,
+  type: '藏品' | '文创' | '质地3'
+): string[][] {
+  // 1. 如果没有叶子ID,返回空数组
+  if (!leafIds || leafIds.trim() === '') {
+    return []
+  }
+
+  const treeData =
+    type === '藏品'
+      ? store.getState().E1tag.treeData
+      : type === '文创'
+        ? store.getState().E3label.treeData
+        : getDictFu('质地3')!
+
+  // 2. 分割ID字符串
+  const idList = leafIds
+    .split(',')
+    .map(id => id.trim())
+    .filter(id => id !== '')
+  if (idList.length === 0) {
+    return []
+  }
+
+  // 3. 创建ID到节点的映射,提高查找性能
+  const idMap = new Map<string, TypeI5Tree>()
+  const idToParentMap = new Map<string, string>() // 存储每个节点的父节点ID
+
+  // 4. 遍历整棵树,填充映射
+  const fillMaps = (nodes: TypeI5Tree[]) => {
+    for (const node of nodes) {
+      idMap.set(node.id, node)
+
+      // 如果当前节点不是根节点,记录父子关系
+      if (node.parentId !== '0') {
+        idToParentMap.set(node.id, node.parentId)
+      }
+
+      // 递归处理子节点
+      if (node.children && node.children.length > 0) {
+        fillMaps(node.children)
+      }
+    }
+  }
+
+  fillMaps(treeData)
+
+  // 5. 查找每个叶子ID的完整路径
+  const result: string[][] = []
+
+  for (const leafId of idList) {
+    const path: string[] = []
+    let currentNodeId: string | undefined = leafId
+
+    // 从叶子节点向上查找,直到找到根节点
+    while (currentNodeId && idMap.has(currentNodeId)) {
+      const node = idMap.get(currentNodeId)!
+      path.unshift(node.id) // 在数组开头插入,确保顺序是从根到叶
+
+      if (node.parentId === '0') {
+        // 找到了根节点
+        break
+      } else {
+        // 继续向上查找父节点
+        currentNodeId = idToParentMap.get(currentNodeId)
+      }
+    }
+
+    // 如果找到了有效路径,加入结果
+    if (path.length > 0) {
+      result.push(path)
+    }
+  }
+
+  return result
+}