Преглед изворни кода

Merge branch 'master' of http://192.168.0.115:3000/shaogen1995/qingDao_goods

lanxin пре 1 дан
родитељ
комит
978fbef8d3
34 измењених фајлова са 1134 додато и 198 уклоњено
  1. 1 1
      src/components/AuthRoute/index.tsx
  2. 2 1
      src/components/MyPopconfirm.tsx
  3. 1 1
      src/components/MyTable/form.tsx
  4. 1 1
      src/components/MyTable/index.tsx
  5. 63 0
      src/pages/Cledger/C1ledger/index.tsx
  6. 10 9
      src/pages/Cledger/C2routing/index.tsx
  7. 7 6
      src/pages/Cledger/C3goodsInfo/index.tsx
  8. 1 1
      src/pages/Dmanage/D2edit/D2info/index.tsx
  9. 1 1
      src/pages/Eculture/E1tag/E1add.tsx
  10. 2 2
      src/pages/Eculture/E1tag/index.tsx
  11. 209 0
      src/pages/Eculture/E3label/E3add.tsx
  12. 181 0
      src/pages/Eculture/E3label/index.module.scss
  13. 267 0
      src/pages/Eculture/E3label/index.tsx
  14. 1 0
      src/pages/Hexhibits/H1loan/H1detail/index.tsx
  15. 2 1
      src/pages/Isystem/I7user/I7add/index.tsx
  16. 12 0
      src/pages/Layout/PassEdit/index.module.scss
  17. 140 0
      src/pages/Layout/PassEdit/index.tsx
  18. 20 6
      src/pages/Layout/data.ts
  19. 6 97
      src/pages/Layout/index.tsx
  20. 27 15
      src/pages/Login/index.tsx
  21. 5 4
      src/pages/ZgoodsInfo/GItab2/index.tsx
  22. 2 1
      src/pages/ZgoodsInfo/data.ts
  23. 6 0
      src/pages/ZgoodsInfo/index.module.scss
  24. 15 2
      src/pages/ZgoodsInfo/index.tsx
  25. 24 4
      src/pages/Zother/AddClues/index.tsx
  26. 23 19
      src/pages/Zother/AddGoods/index.tsx
  27. 17 13
      src/pages/Zother/SonGoodsList/data.ts
  28. 37 0
      src/store/action/Eculture/E3label.ts
  29. 9 1
      src/store/action/layout.ts
  30. 25 0
      src/store/reducer/Eculture/E3label.ts
  31. 2 0
      src/store/reducer/index.ts
  32. 5 5
      src/utils/dataChange.tsx
  33. 3 0
      src/utils/http.ts
  34. 7 7
      src/utils/tableData.ts

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

@@ -17,7 +17,7 @@ export default function AuthRoute({ path, component: Com, ...rest }: AtahType) {
       render={() => {
         if (hasToken()) return <Com />
         else {
-          MessageFu.warning('请登录')
+          MessageFu.warning('请重新登录')
           return (
             <Redirect
               to={{

+ 2 - 1
src/components/MyPopconfirm.tsx

@@ -1,5 +1,6 @@
 import React, { useMemo } from 'react'
 import { Button, Popconfirm } from 'antd'
+import { defaultPassWord } from '@/utils/http'
 
 type Props = {
   txtK: '删除' | '删除2' | '取消' | '返回' | '重置密码' | '退出登录' | '重新提交' | '撤回'
@@ -16,7 +17,7 @@ function MyPopconfirm({ txtK, onConfirm, Dom, loc, disabled }: Props) {
       删除2: ['确定删除吗?', '确定'],
       取消: ['放弃编辑后,信息将不会保存!', '放弃'],
       返回: ['放弃编辑后,信息将不会保存!', '放弃'],
-      重置密码: ['密码重制后为Aa147852,是否重置?', '重置'],
+      重置密码: [`密码重制后为${defaultPassWord},是否重置?`, '重置'],
       退出登录: ['确定退出吗?', '确定'],
       重新提交: ['确定重新提交吗?', '确定'],
       撤回: ['确定撤回吗?', '确定']

+ 1 - 1
src/components/MyTable/form.tsx

@@ -171,7 +171,7 @@ const MyTable = forwardRef<MyTableMethods, MyTableProps>(
             // resJiLianFu(item[v[2]], 'tag'),
             let resTxt = item[v[2]] || isNull
             if (resTxt) {
-              return resTagFu(resTxt) || isNull
+              return resTagFu(resTxt, v[3] || '藏品') || isNull
             }
             return resTxt || isNull
           },

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

@@ -117,7 +117,7 @@ function MyTable({
           // resJiLianFu(item[v[2]], 'tag'),
           let resTxt = item[v[2]] || isNull
           if (resTxt) {
-            return resTagFu(resTxt) || isNull
+            return resTagFu(resTxt, v[3] || '藏品') || isNull
           }
           return resTxt || isNull
         },

+ 63 - 0
src/pages/Cledger/C1ledger/index.tsx

@@ -15,6 +15,69 @@ import { exportExcelFile } from '@/utils/xlsxExport'
 import { CaretDownOutlined } from '@ant-design/icons'
 import C1Import from './C1Import'
 
+const C1topSearch = [
+  {
+    type: 'input',
+    key: 'searchKey',
+    placeholder: '搜索藏品登记号、藏品名称'
+  },
+  {
+    type: 'cascaderSS',
+    key: 'artDictId',
+    placeholder: `文创标签`
+    // options: getDictFu('藏品标签')
+  },
+  {
+    type: 'select',
+    key: 'level',
+    placeholder: '级别',
+    options: selectObj['藏品级别']
+  },
+  // 待完善sg
+  // {
+  //   type: 'cascaderSS',
+  //   key: 'tagDictId',
+  //   placeholder: '藏品标签',
+  //   options: getDictFu('藏品标签')
+  // },
+  {
+    type: 'cascader',
+    key: 'ageDictId',
+    placeholder: '年代',
+    options: getDictFu('藏品年代')
+  },
+  {
+    type: 'cascader',
+    key: 'textureDictId',
+    placeholder: '质地',
+    options: getDictFu('质地')
+  },
+  {
+    type: 'select',
+    key: 'tornLevel',
+    placeholder: '完残程度',
+    options: selectObj['完残程度']
+  },
+  // TODO
+  {
+    type: 'select',
+    key: 'status',
+    placeholder: '入藏状态',
+    options: selectObj['藏品入藏状态']
+  },
+  {
+    type: 'select',
+    key: 'siteStatus',
+    placeholder: '库存状态',
+    options: selectObj['藏品库存状态']
+  },
+  {
+    type: 'select',
+    key: 'siteLoc',
+    placeholder: `搜索库房位置`
+  }
+]
+
 const C1baseFormData = {
   ...baseFormData,
   typeDictId: '',

+ 10 - 9
src/pages/Cledger/C2routing/index.tsx

@@ -73,6 +73,8 @@ const getAllTreeKeys = (nodes: TreeDataNode[]): string[] => {
 
 const C2siderLeftTree = ({ setExtraParams }: { setExtraParams: (params: any) => void }) => {
   const { treeData: dictAll } = useSelector((state: RootState) => state.E1tag)
+  const E3label = useSelector((state: RootState) => state.E3label.treeData)
+
   // 当前选中的树节点ID(高亮)
   const [acShu, setAcShu] = useState('')
   // 勾选中的节点 key,默认全部选中
@@ -128,11 +130,10 @@ const C2siderLeftTree = ({ setExtraParams }: { setExtraParams: (params: any) =>
     [value]
   )
 
-  // 按节点名称筛选:藏品类别、藏品年代、藏品标签(树)、藏品级别(平铺)
+  // 按节点名称筛选:藏品标签(树)、藏品年代、文创标签(树)、藏品级别(平铺)
   const categoryFiltered = useMemo(() => {
-    const list = getDictFu('藏品类别') || []
-    return value2 ? filterTreeByName(list, value2) : list
-  }, [value2])
+    return value2 ? filterTreeByName(dictAll, value2) : dictAll
+  }, [dictAll, value2])
 
   const ageFiltered = useMemo(() => {
     const list = getDictFu('藏品年代') || []
@@ -140,8 +141,8 @@ const C2siderLeftTree = ({ setExtraParams }: { setExtraParams: (params: any) =>
   }, [value2])
 
   const tagTreeFiltered = useMemo(() => {
-    return value2 ? filterTreeByName(dictAll, value2) : dictAll
-  }, [dictAll, value2])
+    return value2 ? filterTreeByName(E3label, value2) : E3label
+  }, [E3label, value2])
 
   const levelFiltered = useMemo(() => {
     const list = selectObj['藏品级别'] || []
@@ -150,11 +151,11 @@ const C2siderLeftTree = ({ setExtraParams }: { setExtraParams: (params: any) =>
     return list.filter((item: { label: string }) => item.label.toUpperCase().includes(key))
   }, [value2])
 
-  // 四个数据源合并为一棵树:藏品类别、藏品年代、藏品标签、藏品级别(key 带前缀便于拆分为分类参数)
+  // 四个数据源合并为一棵树:藏品标签(树)、藏品年代、文创标签(树)、藏品级别(平铺)(key 带前缀便于拆分为分类参数)
   const treeData = useMemo(() => {
     const rootCategory: TreeDataNode = {
       key: 'root-类别',
-      title: '藏品类别',
+      title: '藏品标签',
       children: loopToTreeNodes(categoryFiltered, 'type')
     }
     const rootAge: TreeDataNode = {
@@ -164,7 +165,7 @@ const C2siderLeftTree = ({ setExtraParams }: { setExtraParams: (params: any) =>
     }
     const rootTag: TreeDataNode = {
       key: 'root-标签',
-      title: '藏品标签',
+      title: '文创标签',
       children: loopToTreeNodes(tagTreeFiltered, 'tag')
     }
     const rootLevel: TreeDataNode = {

+ 7 - 6
src/pages/Cledger/C3goodsInfo/index.tsx

@@ -27,12 +27,13 @@ const C1topSearch = [
     placeholder: '级别',
     options: selectObj['藏品级别']
   },
-  {
-    type: 'cascader',
-    key: 'typeDictId',
-    placeholder: '类别',
-    options: getDictFu('藏品类别')
-  },
+  // // 待完善sg
+  // {
+  //   type: 'cascader',
+  //   key: 'typeDictId',
+  //   placeholder: '类别',
+  //   options: getDictFu('藏品类别')
+  // },
   {
     type: 'cascader',
     key: 'ageDictId',

+ 1 - 1
src/pages/Dmanage/D2edit/D2info/index.tsx

@@ -38,7 +38,7 @@ function D2info() {
           name: '藏品标签',
           resFu: (info: GoodsType) => {
             let resTxt = info.tagDictId
-            if (resTxt) return resTagFu(resTxt) || '(空)'
+            if (resTxt) return resTagFu(resTxt, '藏品') || '(空)'
             return resTxt || '(空)'
           }
         }

+ 1 - 1
src/pages/Eculture/E1tag/E1add.tsx

@@ -172,7 +172,7 @@ function E1add({ addInfo, addFu, closeFu }: Props) {
             <Input maxLength={20} showCount placeholder='请输入内容' />
           </Form.Item>
 
-          <Form.Item label='标签说明' name='description'>
+          <Form.Item label='标签说明' name='intro'>
             <TextArea maxLength={500} showCount placeholder='请输入内容' />
           </Form.Item>
 

+ 2 - 2
src/pages/Eculture/E1tag/index.tsx

@@ -150,7 +150,7 @@ function E1tag() {
 
   return (
     <div className={styles.E1tag}>
-      <div className='pageTitle'>标签管理</div>
+      <div className='pageTitle'>藏品标签</div>
 
       {/* 左侧 */}
       <div className='E1son E1ll'>
@@ -233,7 +233,7 @@ function E1tag() {
 
               <div className='E1mr2Row'>
                 <div className='E1mr2Row1'>标签说明:</div>
-                <div className='E1mr2Row2'>{rightData.description || '(空)'}</div>
+                <div className='E1mr2Row2'>{rightData.intro || '(空)'}</div>
               </div>
             </div>
           </>

+ 209 - 0
src/pages/Eculture/E3label/E3add.tsx

@@ -0,0 +1,209 @@
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Cascader, Form, FormInstance, Input, InputNumber, Modal } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import { MessageFu } from '@/utils/message'
+import TextArea from 'antd/es/input/TextArea'
+import { I5AddInfoType, TypeI5Tree } from '@/pages/Isystem/I5organization/data'
+import { E3_APIgetInfo, E3_APIsave } from '@/store/action/Eculture/E3label'
+
+type Props = {
+  addInfo: I5AddInfoType
+  addFu: () => void
+  closeFu: () => void
+}
+
+function E3add({ addInfo, addFu, closeFu }: Props) {
+  const treeData = useSelector((state: RootState) => state.E3label.treeData)
+
+  // 级联选择器改变的时候 筛选当前级联的 信息出来
+  const [acCardInfo, setAcCardInfo] = useState({} as TypeI5Tree)
+  const [parentIdArr, setParentIdArr] = useState<string[] | null>(null)
+
+  // useEffect(() => {
+  //   console.log(acCardInfo, parentIdArr)
+  // }, [acCardInfo, parentIdArr])
+
+  useEffect(() => {
+    setAcCardInfo(addInfo.acInfo)
+
+    let ids: string[] | null = addInfo.acInfo.id ? [addInfo.acInfo.id] : null
+
+    if (addInfo.acInfo.ancestor) ids = [...addInfo.acInfo.ancestor.split(','), addInfo.acInfo.id]
+
+    let idsRes = ids
+    if (ids && ids.length >= 1 && addInfo.txt === '编辑') {
+      ids.pop()
+    }
+
+    if (idsRes) idsRes = idsRes.filter((v, i) => v !== '0')
+
+    setParentIdArr(idsRes)
+  }, [addInfo.acInfo, addInfo.txt])
+
+  const cardChange = useCallback((aa: any, bb: any) => {
+    setParentIdArr(aa)
+
+    if (bb && bb.length) setAcCardInfo(bb[bb.length - 1])
+    else setAcCardInfo({} as TypeI5Tree)
+  }, [])
+
+  const getInfoFu = useCallback(async (id: string) => {
+    const res = await E3_APIgetInfo(id)
+    if (res.code === 0) {
+      FormBoxRef.current?.setFieldsValue({
+        ...res.data
+      })
+    }
+  }, [])
+  useEffect(() => {
+    if (addInfo.txt === '编辑') getInfoFu(addInfo.id)
+    else {
+      FormBoxRef.current?.setFieldsValue({
+        sort: 999
+      })
+    }
+  }, [addInfo.id, addInfo.txt, getInfoFu])
+
+  // 设置表单初始数据(区分编辑和新增)
+  const FormBoxRef = useRef<FormInstance>(null)
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    // return MessageFu.warning("有表单不符号规则!");
+  }, [])
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      let ancestor = ''
+      let parentId: string | null = null
+
+      if (parentIdArr && parentIdArr.length >= 6 && addInfo.txt === '新增')
+        return MessageFu.warning('最多支持六级!')
+
+      if (acCardInfo) parentId = addInfo.txt === '编辑' ? acCardInfo.parentId : acCardInfo.id
+      if (parentIdArr && parentId) ancestor = parentIdArr.filter(v => v !== addInfo.id).join(',')
+
+      let level = 1
+      if (parentIdArr) {
+        level = addInfo.txt === '新增' ? acCardInfo.level + 1 : acCardInfo.level
+      }
+
+      // 补0
+      if (addInfo.id === '-1') {
+        // 新增
+        if (!parentId && !ancestor) {
+          ancestor = '0'
+          parentId = '0'
+        } else ancestor = '0,' + ancestor
+      } else {
+        // 编辑
+        if (!ancestor) ancestor = '0'
+        else ancestor = '0,' + ancestor
+      }
+
+      const obj = {
+        ...values,
+        id: addInfo.id === '-1' ? null : addInfo.id,
+        ancestor,
+        level,
+        parentId
+      }
+      // console.log(123, obj)
+      // if (1 + 1 === 2) {
+      //   return
+      // }
+
+      const res = await E3_APIsave(obj)
+
+      if (res.code === 0) {
+        MessageFu.success(addInfo.txt + '成功!')
+        addFu()
+        closeFu()
+      }
+    },
+    [acCardInfo, addFu, addInfo.id, addInfo.txt, closeFu, parentIdArr]
+  )
+
+  return (
+    <Modal
+      wrapClassName={styles.E3add}
+      open={true}
+      title={addInfo.txt}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='E3aMain'>
+        <Form
+          scrollToFirstError={true}
+          ref={FormBoxRef}
+          name='basic'
+          labelCol={{ span: 3 }}
+          onFinish={onFinish}
+          onFinishFailed={onFinishFailed}
+          autoComplete='off'
+        >
+          <div className='fromRow'>
+            <div className='fromRowll'>上级标签:</div>
+            <div className='fromRowrr'>
+              <Cascader
+                style={{ width: 658 }}
+                disabled={addInfo.txt === '编辑'}
+                changeOnSelect
+                fieldNames={{ label: 'name', value: 'id', children: 'children' }}
+                options={treeData}
+                placeholder={addInfo.txt === '编辑' ? '空' : '请选择'}
+                value={parentIdArr ? [...parentIdArr] : []}
+                onChange={cardChange}
+              />
+            </div>
+          </div>
+
+          <Form.Item
+            label='标签名称'
+            name='name'
+            rules={[{ required: true, message: '请输入标签名称!' }]}
+            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
+          >
+            <Input maxLength={20} showCount placeholder='请输入内容' />
+          </Form.Item>
+
+          <Form.Item label='标签说明' name='intro'>
+            <TextArea maxLength={500} showCount placeholder='请输入内容' />
+          </Form.Item>
+
+          <div className='fromRow2'>
+            <Form.Item
+              label='排序值'
+              name='sort'
+              rules={[{ required: true, message: '请输入排序值!' }]}
+            >
+              <InputNumber min={1} max={999} precision={0} placeholder='请输入' />
+            </Form.Item>
+            <div className='fromRowTit'>
+              请输入1~999的数字。数字越小,排序越靠前。数字相同时,更新发布的内容排在前面
+            </div>
+          </div>
+
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+            <Button type='primary' htmlType='submit'>
+              提交
+            </Button>
+            &emsp;
+            <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+          </Form.Item>
+        </Form>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoE3add = React.memo(E3add)
+
+export default MemoE3add

+ 181 - 0
src/pages/Eculture/E3label/index.module.scss

@@ -0,0 +1,181 @@
+.E3label {
+  display: flex;
+  :global {
+    .E3son {
+      width: 60%;
+      margin-right: 20px;
+      background-color: var(--boxBcaColor);
+      border-radius: 10px;
+      padding: 24px;
+    }
+    .E3ll {
+      .E3ll1 {
+        margin-bottom: 20px;
+      }
+      .E3ll2 {
+        height: calc(100% - 52px);
+
+        overflow-y: auto;
+        .site-tree-search-value {
+          color: red;
+          font-weight: 700;
+        }
+        .ant-tree {
+          background-color: var(--boxBcaColor);
+          min-height: 100%;
+        }
+        .ant-tree-title span {
+          font-size: 18px;
+        }
+
+        .ant-tree-node-selected {
+          padding: 4px 8px !important;
+          background-color: var(--txtColor) !important;
+          .ant-tree-title span {
+            color: #fff !important;
+          }
+        }
+        .NODATA {
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          align-items: center;
+          color: #666666;
+          font-size: 16px;
+          height: 100%;
+          // img {
+          //   width: 150px;
+          // }
+          & > p {
+            margin-bottom: 10px;
+          }
+          div {
+            width: 80%;
+            margin-top: 8%;
+            display: flex;
+            justify-content: space-around;
+          }
+        }
+      }
+    }
+
+    .E3rr {
+      width: calc(40% - 20px);
+      overflow-y: auto;
+      margin-right: 0;
+
+      .E3mr2 {
+        .E3mr2_1 {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          font-weight: 700;
+          color: var(--themeColor);
+          font-size: 24px;
+        }
+        .E3mr2_2 {
+          margin: 20px 0 40px;
+          display: flex;
+          .E3mr2Btn {
+            cursor: pointer;
+            margin-right: 15px;
+            width: 130px;
+            height: 40px;
+            line-height: 38px;
+            text-align: center;
+            color: #fff;
+            background-color: var(--txtColor);
+            border-radius: 4px;
+            font-size: 18px;
+            letter-spacing: 2px;
+            border: 1px solid transparent;
+            transition: all 0.3s;
+            &:hover {
+              transform: scale(1.1);
+            }
+          }
+          .E3mr2Btn2 {
+            color: #ff4d4d;
+            background-color: #fff;
+            border: 1px solid #ccc;
+          }
+        }
+
+        .E3mr2Row {
+          display: flex;
+          font-size: 20px;
+          margin-bottom: 30px;
+          .E3mr2Row1 {
+            font-weight: 700;
+            font-size: 20px;
+            width: 100px;
+          }
+
+          .E3mr2Row2 {
+            width: calc(100% - 100px);
+            word-wrap: break-word;
+          }
+        }
+
+        .E3mr2RowLast {
+          align-items: self-start;
+          .E3mr2Row2 {
+            display: flex;
+            flex-wrap: wrap;
+          }
+        }
+      }
+
+      .E3mr3 {
+        margin-top: 15px;
+        height: calc(100% - 100px);
+        background-color: red;
+      }
+    }
+  }
+}
+
+// 新增弹窗页面
+.E3add {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 800px !important;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+    }
+
+    .E3aMain {
+      padding-top: 15px;
+      .fromRow2 {
+        position: relative;
+
+        .fromRowTit {
+          position: absolute;
+          left: 200px;
+          top: 5px;
+          color: #999;
+          font-size: 12px;
+        }
+      }
+      .fromRow {
+        display: flex;
+        align-items: center;
+        margin-bottom: 24px;
+        .fromRowll {
+          width: 94px;
+          text-align: right;
+          position: relative;
+        }
+        .fromRowrr {
+          width: calc(100% - 94px);
+        }
+      }
+    }
+  }
+}

+ 267 - 0
src/pages/Eculture/E3label/index.tsx

@@ -0,0 +1,267 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Input, Tree, TreeDataNode } from 'antd'
+import { useDispatch, useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { MessageFu } from '@/utils/message'
+import { filterTreeByName, treeResIdFu } from '@/pages/Isystem/I2dict/data'
+import { I5AddInfoType, TypeI5Tree } from '@/pages/Isystem/I5organization/data'
+import classNames from 'classnames'
+import { E3_APIdel, E3_APIgetTree } from '@/store/action/Eculture/E3label'
+import E3add from './E3add'
+
+function E3label() {
+  const dispatch = useDispatch()
+
+  const [loding, setLoding] = useState(false)
+
+  const getInfoFu = useCallback(
+    (flag: boolean) => {
+      dispatch(
+        E3_APIgetTree(data => {
+          setLoding(true)
+
+          if (flag && data && data.length) setAcShu(data[0].id)
+        })
+      )
+    },
+    [dispatch]
+  )
+
+  useEffect(() => {
+    getInfoFu(true)
+  }, [getInfoFu])
+
+  const { treeData: dictAll } = useSelector((state: RootState) => state.E3label)
+
+  // 点击重置
+  const resetFu = useCallback(
+    (flag: boolean) => {
+      // 重置 flag为true
+      // 新增和编辑 为false
+      getInfoFu(flag)
+
+      setValue('')
+      setValue2('')
+    },
+    [getInfoFu]
+  )
+
+  // 当前选中的树节点ID
+  const [acShu, setAcShu] = useState('')
+
+  // 点击树节点
+  const onSelect = (id: any) => {
+    if (id[0]) setAcShu(id[0])
+  }
+
+  // 搜索高亮
+  const [value, setValue] = useState('')
+  const [value2, setValue2] = useState('')
+
+  const timeRef = useRef(-1)
+  const valueChange = useCallback((val: string) => {
+    setValue(val.trim())
+    clearTimeout(timeRef.current)
+    timeRef.current = window.setTimeout(() => {
+      setValue2(val.trim())
+    }, 500)
+  }, [])
+
+  // value变化的时候获取所有dom 设置隐藏
+  const treeDataTemp = useMemo(() => {
+    if (value2) {
+      return filterTreeByName(dictAll, value2)
+    } else return dictAll
+  }, [dictAll, value2])
+
+  const treeData = useMemo(() => {
+    const loop = (dataTemp: any[]): TreeDataNode[] => {
+      const data = dataTemp || []
+
+      return data.map(item => {
+        const strTitle = ((item.num ? item.num + ' ' : '') + item.name) as string
+
+        const strTitleD = strTitle.toUpperCase()
+
+        const valueD = value.toUpperCase()
+        const index = strTitleD.indexOf(valueD)
+
+        const beforeStr = strTitle.substring(0, index)
+        const afterStr = strTitle.slice(index + value.length)
+        const title =
+          index > -1 ? (
+            <span key={item.id}>
+              {beforeStr}
+              <span className='site-tree-search-value'>{value}</span>
+              {afterStr}
+            </span>
+          ) : (
+            <span key={item.id}>{strTitle}</span>
+          )
+        if (item.children) {
+          return { title, key: item.id, children: loop(item.children) }
+        }
+        return {
+          title,
+          key: item.id
+        }
+      })
+    }
+
+    return loop(treeDataTemp)
+  }, [treeDataTemp, value])
+
+  // 右侧信息
+  const rightData = useMemo(() => {
+    let obj = {} as TypeI5Tree
+
+    obj = treeResIdFu(treeDataTemp, acShu)
+
+    return obj || {}
+  }, [acShu, treeDataTemp])
+
+  // 点击删除
+  const delTree = useCallback(
+    async (id: string) => {
+      const res = await E3_APIdel(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功!')
+        resetFu(true)
+      }
+    },
+    [resetFu]
+  )
+
+  // 点击新增和编辑
+  const [addInfo, setAddInfo] = useState({} as I5AddInfoType)
+
+  const addSonFu = useCallback(
+    (id: string) => {
+      setAddInfo({
+        id,
+        txt: id === '-1' ? '新增' : '编辑',
+        acInfo: rightData
+      })
+    },
+    [rightData]
+  )
+
+  return (
+    <div className={styles.E3label}>
+      <div className='pageTitle'>文创标签</div>
+
+      {/* 左侧 */}
+      <div className='E3son E3ll'>
+        <div className='E3ll1'>
+          <Input
+            style={{ width: 300 }}
+            placeholder='请输入标签名称'
+            maxLength={30}
+            showCount
+            value={value}
+            onChange={e => valueChange(e.target.value)}
+            allowClear
+          />
+        </div>
+        <div className='E3ll2'>
+          {treeDataTemp && treeDataTemp.length ? (
+            <Tree
+              // 默认全部展开
+              defaultExpandAll={true}
+              // 数据
+              treeData={treeData}
+              // 自定义字段
+              // fieldNames={{ title: 'title', key: 'key', children: 'children' }}
+              // 选中
+              selectedKeys={[acShu]}
+              // 点击
+              onSelect={onSelect}
+            />
+          ) : loding ? (
+            <div className='NODATA'>暂无相关搜索结果,请更换关键字搜索</div>
+          ) : null}
+        </div>
+      </div>
+      <div className='E3son E3rr'>
+        {rightData.id ? (
+          <>
+            <div className='E3mr2'>
+              <div className='E3mr2_1'>
+                <div>操作:</div>
+                <Button
+                  size='large'
+                  type='primary'
+                  onClick={() => setAddInfo({ id: '-1', txt: '新增', acInfo: rightData })}
+                >
+                  新增
+                </Button>
+              </div>
+
+              <div className='E3mr2_2'>
+                <div onClick={() => addSonFu(rightData.id)} className={classNames('E3mr2Btn')}>
+                  编辑
+                </div>
+                &emsp;
+                <MyPopconfirm
+                  txtK='删除'
+                  onConfirm={() => delTree(rightData.id)}
+                  disabled={rightData.parentId === '0'}
+                  Dom={<div className={classNames('E3mr2Btn E3mr2Btn2')}>删除</div>}
+                />
+              </div>
+
+              <div className='E3mr2Row'>
+                <div className='E3mr2Row1'>标签名称:</div>
+                <div className='E3mr2Row2'>{rightData.name}</div>
+              </div>
+
+              <div className='E3mr2Row'>
+                <div className='E3mr2Row1'>层级:</div>
+                <div className='E3mr2Row2'>{rightData.level}</div>
+              </div>
+              {/* <div className='E3mr2Row'>
+                    <div className='E3mr2Row1'>id:</div>
+                    <div className='E3mr2Row2'>{rightData.id}</div>
+                  </div> */}
+
+              <div className='E3mr2Row'>
+                <div className='E3mr2Row1'>排序值:</div>
+                <div className='E3mr2Row2'>{rightData.sort}</div>
+              </div>
+
+              <div className='E3mr2Row'>
+                <div className='E3mr2Row1'>标签说明:</div>
+                <div className='E3mr2Row2'>{rightData.intro || '(空)'}</div>
+              </div>
+            </div>
+          </>
+        ) : null}
+      </div>
+
+      {/* 右侧 */}
+
+      <div className='E3top'></div>
+
+      {/* 主体 */}
+      <div className='E3main'>
+        <div className='E3m1'>
+          <div className='E3m1rr'></div>
+        </div>
+      </div>
+      {/* 新增/编辑页面 中图法分类 */}
+      {addInfo.id ? (
+        <E3add
+          addInfo={addInfo}
+          addFu={() => resetFu(false)}
+          closeFu={() => setAddInfo({} as I5AddInfoType)}
+        />
+      ) : null}
+    </div>
+  )
+}
+
+const MemoE3label = React.memo(E3label)
+
+export default MemoE3label

+ 1 - 0
src/pages/Hexhibits/H1loan/H1detail/index.tsx

@@ -260,6 +260,7 @@ function H1detail() {
   }, [info.region])
 
   const typeDictOptions = useMemo(() => {
+    // 待完善sg
     try {
       return getDictFu('藏品类别') || []
     } catch {

+ 2 - 1
src/pages/Isystem/I7user/I7add/index.tsx

@@ -9,6 +9,7 @@ import { UserTableAPIType } from '../data'
 import { I6_APIgetList } from '@/store/action/Isystem/I6role'
 import { getUserInfoByIdAPI, userSaveAPI } from '@/store/action/Isystem/I7user'
 import { treeLastIdFindFatherFu } from '@/utils/dataChange'
+import { defaultPassWord } from '@/utils/http'
 
 type Props = {
   id: any
@@ -199,7 +200,7 @@ function I7add({ id, closePage, upTableList, addTableList, formOld }: Props) {
             />
           </Form.Item>
 
-          {id ? null : <div className='passTit'>* 默认密码 Aa147852</div>}
+          {id ? null : <div className='passTit'>* 默认密码 {defaultPassWord}</div>}
 
           {/* 确定和取消按钮 */}
           <br />

+ 12 - 0
src/pages/Layout/PassEdit/index.module.scss

@@ -0,0 +1,12 @@
+.PassEdit {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+      padding-top: 20px !important;
+    }
+  }
+}

+ 140 - 0
src/pages/Layout/PassEdit/index.tsx

@@ -0,0 +1,140 @@
+import React, { useCallback, useEffect, useMemo, useRef } from 'react'
+import styles from './index.module.scss'
+import { Button, Form, FormInstance, Input, Modal } from 'antd'
+import { MessageFu } from '@/utils/message'
+import { Base64 } from 'js-base64'
+import encodeStr from '@/utils/pass'
+import { passWordEditAPI, passWordEditAPI2 } from '@/store/action/layout'
+import store from '@/store'
+import { loginExit } from '../data'
+import { setTokenInfo } from '@/utils/storage'
+import history from '@/utils/history'
+import { defaultPassWord } from '@/utils/http'
+
+type Props = {
+  userTokenInfo?: any
+}
+
+function PassEdit({ userTokenInfo }: Props) {
+  // 设置表单ref
+  const FormBoxRef = useRef<FormInstance>(null)
+
+  // 是否是从登录页面进来的,需求强制修改默认密码
+  const flag = useMemo(() => {
+    let flag = false
+    if (userTokenInfo && userTokenInfo.token) flag = true
+    return flag
+  }, [userTokenInfo])
+
+  useEffect(() => {
+    if (flag) {
+      FormBoxRef.current?.setFieldsValue({
+        oldPassword: defaultPassWord
+      })
+    }
+  }, [flag])
+
+  // 拿到新密码的输入框的值
+  const oldPasswordValue = useRef('')
+
+  const checkPassWord = (rule: any, value: any = '') => {
+    if (value !== oldPasswordValue.current) return Promise.reject('新密码不一致!')
+    else return Promise.resolve(value)
+  }
+
+  const onFinish = useCallback(
+    async (values: any) => {
+      // 通过校验之后发送请求
+      if (values.oldPassword === values.newPassword) return MessageFu.warning('新旧密码不能相同!')
+      const obj = {
+        oldPassword: encodeStr(Base64.encode(values.oldPassword)),
+        newPassword: encodeStr(Base64.encode(values.newPassword))
+      }
+      const token = flag ? userTokenInfo.token : undefined
+      const res: any = flag ? await passWordEditAPI(obj, token) : await passWordEditAPI2(obj)
+      if (res.code === 0) {
+        store.dispatch({ type: 'layout/passEditShow', payload: false })
+        if (flag) {
+          MessageFu.success('登录成功')
+          // 用户信息存到本地
+          setTokenInfo(userTokenInfo)
+          history.replace('/')
+        } else {
+          MessageFu.success('修改成功')
+          loginExit()
+        }
+      }
+    },
+    [flag, userTokenInfo]
+  )
+
+  return (
+    <Modal
+      wrapClassName={styles.PassEdit}
+      destroyOnClose
+      open={true}
+      title={flag ? '为保障账号安全,请修改默认密码' : '修改密码'}
+      // onCancel={() => store.dispatch({ type: 'layout/passEditShow', payload: false })}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <Form
+        ref={FormBoxRef}
+        scrollToFirstError={true}
+        name='basic'
+        labelCol={{ span: 5 }}
+        wrapperCol={{ span: 16 }}
+        onFinish={onFinish}
+        autoComplete='off'
+      >
+        <Form.Item
+          label='旧密码'
+          name='oldPassword'
+          rules={[{ required: true, message: '不能为空!' }]}
+          getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
+        >
+          <Input.Password maxLength={20} disabled={flag} />
+        </Form.Item>
+
+        <Form.Item
+          label='新密码'
+          name='newPassword'
+          rules={[
+            { required: true, message: '不能为空!' },
+            { min: 6, max: 15, message: '密码长度为6-15个字符!' }
+          ]}
+          getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
+        >
+          <Input.Password
+            maxLength={15}
+            onChange={e => (oldPasswordValue.current = e.target.value)}
+          />
+        </Form.Item>
+
+        <Form.Item
+          label='确定新密码'
+          name='checkPass'
+          rules={[{ validator: checkPassWord }]}
+          getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
+        >
+          <Input.Password maxLength={15} />
+        </Form.Item>
+
+        <Form.Item wrapperCol={{ offset: 5, span: 16 }}>
+          <Button onClick={() => store.dispatch({ type: 'layout/passEditShow', payload: false })}>
+            {flag ? '取消登录' : '取消'}
+          </Button>
+          &emsp;
+          <Button type='primary' htmlType='submit'>
+            {flag ? '确定修改并进入系统' : '确定'}
+          </Button>
+        </Form.Item>
+      </Form>
+    </Modal>
+  )
+}
+
+const MemoPassEdit = React.memo(PassEdit)
+
+export default MemoPassEdit

+ 20 - 6
src/pages/Layout/data.ts

@@ -1,5 +1,13 @@
+import history from '@/utils/history'
+import { removeTokenInfo } from '@/utils/storage'
 import React from 'react'
 
+// 点击退出登录
+export const loginExit = () => {
+  removeTokenInfo()
+  history.replace('/login')
+}
+
 export type LookDomType = {
   src: string
   type: 'video' | 'audio' | 'model' | ''
@@ -155,6 +163,12 @@ const tabLeftArr: RouterType = [
         path: '/resource',
         Com: React.lazy(() => import('../Dmanage/D4resource')),
         pageType: 'ZY'
+      },
+      {
+        id: 601,
+        name: '藏品标签',
+        path: '/tag',
+        Com: React.lazy(() => import('../Eculture/E1tag'))
       }
     ]
   },
@@ -164,16 +178,16 @@ const tabLeftArr: RouterType = [
     show: false,
     son: [
       {
-        id: 601,
-        name: '标签管理',
-        path: '/tag',
-        Com: React.lazy(() => import('../Eculture/E1tag'))
-      },
-      {
         id: 602,
         name: '故事管理',
         path: '/story',
         Com: React.lazy(() => import('../Eculture/E2story'))
+      },
+      {
+        id: 603,
+        name: '文创标签',
+        path: '/label',
+        Com: React.lazy(() => import('../Eculture/E3label'))
       }
     ]
   },

+ 6 - 97
src/pages/Layout/index.tsx

@@ -4,15 +4,10 @@ import styles from './index.module.scss'
 import { Route, Switch, useLocation } from 'react-router-dom'
 import AuthRoute from '@/components/AuthRoute'
 import history from '@/utils/history'
-import { Button, Form, Input, Modal } from 'antd'
-import { Base64 } from 'js-base64'
-import encodeStr from '@/utils/pass'
-import { passWordEditAPI } from '@/store/action/layout'
-import { getTokenInfo, removeTokenInfo } from '@/utils/storage'
-import { MessageFu } from '@/utils/message'
+import { getTokenInfo } from '@/utils/storage'
 import NotFound from '@/components/NotFound'
 import classNames from 'classnames'
-import tabLeftArr, { routerSon, RouterType, RouterTypeRow } from './data'
+import tabLeftArr, { loginExit, routerSon, RouterType, RouterTypeRow } from './data'
 import MyPopconfirm from '@/components/MyPopconfirm'
 import store, { RootState } from '@/store'
 import SpinLodingSon from '@/components/SpinLodingSon'
@@ -25,6 +20,8 @@ import { E1_APIgetTree } from '@/store/action/Eculture/E1tag'
 import { baseURL } from '@/utils/http'
 import baseTouXiangImg from '@/assets/img/user.png'
 import { ZFbaseFu } from '@/store/reducer/ZformData'
+import PassEdit from './PassEdit'
+import { E3_APIgetTree } from '@/store/action/Eculture/E3label'
 
 function Layout() {
   const [loding, setLoding] = useState(false)
@@ -39,6 +36,7 @@ function Layout() {
       })
     )
     dispatch(E1_APIgetTree())
+    dispatch(E3_APIgetTree())
   }, [dispatch])
 
   useEffect(() => {
@@ -211,35 +209,6 @@ function Layout() {
     // if (item.name !== '工作台') changSetFu(item)
   }, [])
 
-  // 拿到新密码的输入框的值
-  const oldPasswordValue = useRef('')
-
-  const checkPassWord = (rule: any, value: any = '') => {
-    if (value !== oldPasswordValue.current) return Promise.reject('新密码不一致!')
-    else return Promise.resolve(value)
-  }
-
-  const onFinish = async (values: any) => {
-    // 通过校验之后发送请求
-    if (values.oldPassword === values.newPassword) return MessageFu.warning('新旧密码不能相同!')
-    const obj = {
-      oldPassword: encodeStr(Base64.encode(values.oldPassword)),
-      newPassword: encodeStr(Base64.encode(values.newPassword))
-    }
-    const res: any = await passWordEditAPI(obj)
-    if (res.code === 0) {
-      MessageFu.success('修改成功!')
-      store.dispatch({ type: 'layout/passEditShow', payload: false })
-      loginExit()
-    }
-  }
-
-  // 点击退出登录
-  const loginExit = () => {
-    removeTokenInfo()
-    history.push('/login')
-  }
-
   // 点击用户 出来 退出登录 修改密码
   const [isUserBtnShow, setIsUserBtnShow] = useState(false)
 
@@ -355,67 +324,7 @@ function Layout() {
       </div>
 
       {/* 点击修改密码打开的对话框 */}
-      <Modal
-        destroyOnClose
-        open={passEditShow}
-        title='修改密码'
-        onCancel={() => store.dispatch({ type: 'layout/passEditShow', payload: false })}
-        footer={
-          [] // 设置footer为空,去掉 取消 确定默认按钮
-        }
-      >
-        <Form
-          scrollToFirstError={true}
-          name='basic'
-          labelCol={{ span: 5 }}
-          wrapperCol={{ span: 16 }}
-          onFinish={onFinish}
-          autoComplete='off'
-        >
-          <Form.Item
-            label='旧密码'
-            name='oldPassword'
-            rules={[{ required: true, message: '不能为空!' }]}
-            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
-          >
-            <Input.Password maxLength={20} />
-          </Form.Item>
-
-          <Form.Item
-            label='新密码'
-            name='newPassword'
-            rules={[
-              { required: true, message: '不能为空!' },
-              { min: 6, max: 15, message: '密码长度为6-15个字符!' }
-            ]}
-            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
-          >
-            <Input.Password
-              maxLength={15}
-              onChange={e => (oldPasswordValue.current = e.target.value)}
-            />
-          </Form.Item>
-
-          <Form.Item
-            label='确定新密码'
-            name='checkPass'
-            rules={[{ validator: checkPassWord }]}
-            getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
-          >
-            <Input.Password maxLength={15} />
-          </Form.Item>
-
-          <Form.Item wrapperCol={{ offset: 14, span: 16 }}>
-            <Button onClick={() => store.dispatch({ type: 'layout/passEditShow', payload: false })}>
-              取消
-            </Button>
-            &emsp;
-            <Button type='primary' htmlType='submit'>
-              确定
-            </Button>
-          </Form.Item>
-        </Form>
-      </Modal>
+      {passEditShow ? <PassEdit /> : null}
     </div>
   )
 }

+ 27 - 15
src/pages/Login/index.tsx

@@ -2,13 +2,17 @@ import styles from './index.module.scss'
 
 import { Input } from 'antd'
 import { UserOutlined, LockOutlined, NumberOutlined } from '@ant-design/icons'
-import { useCallback, useEffect, useState } from 'react'
+import { useCallback, useEffect, useRef, useState } from 'react'
 import { Base64 } from 'js-base64'
 import encodeStr from '@/utils/pass'
 import { setTokenInfo } from '@/utils/storage'
 import history from '@/utils/history'
 import { MessageFu } from '@/utils/message'
 import { API_LoginGetCode, userLoginAPI } from '@/store/action/layout'
+import store, { RootState } from '@/store'
+import PassEdit from '../Layout/PassEdit'
+import { useSelector } from 'react-redux'
+import { defaultPassWord } from '@/utils/http'
 
 export default function Login() {
   // 获取验证码
@@ -35,6 +39,9 @@ export default function Login() {
   const keyUpEntFu = (e: React.KeyboardEvent<HTMLInputElement>) => {
     if (e.key === 'Enter') loginClickFu()
   }
+
+  const userTokenInfoRef = useRef<any>({})
+
   // 点击登录
   const loginClickFu = useCallback(async () => {
     // 非空判断
@@ -47,23 +54,25 @@ export default function Login() {
     }
     const res: any = await userLoginAPI(obj)
     if (res.code === 0) {
-      MessageFu.success('登录成功')
+      userTokenInfoRef.current = { ...res.data, token: res.data.satoken }
 
       // 检查密码是不是默认密码,是的话给提示
-      if (passWord === 'Aa147852') {
-        window.setTimeout(() => {
-          MessageFu.warning('您的密码还是默认密码,请尽快修改!')
-        }, 1000)
+      if (passWord === defaultPassWord) {
+        MessageFu.warning('为保障账号安全,请修改默认密码')
+        setCode('')
+        LoginGetCodeFu()
+        store.dispatch({ type: 'layout/passEditShow', payload: true })
+      } else {
+        MessageFu.success('登录成功')
+        // 用户信息存到本地
+        setTokenInfo(userTokenInfoRef.current)
+        const urlAll = window.location.href
+        if (urlAll.includes('?back=')) {
+          const url = urlAll.split('?back=')[1]
+          if (url) history.replace(`/${url}`)
+          else history.replace('/')
+        } else history.replace('/')
       }
-
-      // 用户信息存到本地
-      setTokenInfo({ ...res.data, token: res.data.satoken })
-      const urlAll = window.location.href
-      if (urlAll.includes('?back=')) {
-        const url = urlAll.split('?back=')[1]
-        if (url) history.replace(`/${url}`)
-        else history.replace('/')
-      } else history.replace('/')
     } else if (res.code === 3014) {
       MessageFu.warning('账号不存在或密码错误,请联系管理员!')
     } else if (res.code === -1 && res.msg === '验证码有误') {
@@ -71,6 +80,8 @@ export default function Login() {
     }
   }, [LoginGetCodeFu, code, passWord, userName])
 
+  const { passEditShow } = useSelector((state: RootState) => state.A0Layout)
+
   return (
     <div className={styles.Login}>
       {/* logg */}
@@ -122,6 +133,7 @@ export default function Login() {
           </div>
         </div>
       </div>
+      {passEditShow ? <PassEdit userTokenInfo={userTokenInfoRef.current} /> : null}
     </div>
   )
 }

+ 5 - 4
src/pages/ZgoodsInfo/GItab2/index.tsx

@@ -21,8 +21,8 @@ function GItab2({ info }: Props) {
   const [list, setList] = useState<any[]>([])
 
   const getInfoFu = useCallback(async () => {
-    if (info.siteId) {
-      const res = await API_GIsiteInfo(info.siteId)
+    if (info.id) {
+      const res = await API_GIsiteInfo(info.id)
       if (res.code === 0) {
         const obj: any = res.data || {}
         const arr: any[] = []
@@ -33,7 +33,8 @@ function GItab2({ info }: Props) {
           { key: 'layer1', name: '排' },
           { key: 'layer2', name: '列' },
           { key: 'layer3', name: '层' },
-          { key: 'layer4', name: '格' }
+          { key: 'layer4', name: '格' },
+          { key: 'siteLocRemark', name: '位置备注' }
         ]
 
         keyArr.forEach((v, i) => {
@@ -47,7 +48,7 @@ function GItab2({ info }: Props) {
         setList(arr)
       }
     }
-  }, [info.siteId])
+  }, [info.id])
 
   useEffect(() => {
     getInfoFu()

+ 2 - 1
src/pages/ZgoodsInfo/data.ts

@@ -14,7 +14,8 @@ export const GIrowArr = [
   },
   { key: 'makeUser', name: '制档人' },
   { key: 'level', name: '藏品级别' },
-  { key: 'typeDictId', name: '藏品类别', resFu: (info: GoodsType) => resJiLianFu(info.typeDictId) },
+  // // 待完善sg
+  // { key: 'typeDictId', name: '藏品类别', resFu: (info: GoodsType) => resJiLianFu(info.typeDictId) },
   { key: 'ageDictId', name: '藏品年代', resFu: (info: GoodsType) => resJiLianFu(info.ageDictId) },
   { key: 'ageInfo', name: '具体年代' },
   {

+ 6 - 0
src/pages/ZgoodsInfo/index.module.scss

@@ -85,5 +85,11 @@
       border-radius: 10px;
       color: var(--txtColor);
     }
+
+    .GItag2 {
+      border-color: var(--myAntdColor);
+      border-radius: 10px;
+      color: var(--myAntdColor);
+    }
   }
 }

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

@@ -240,7 +240,7 @@ function ZgoodsInfo() {
 
     if (info.tagDictId) {
       dom = []
-      const txt: string = resTagFu(info.tagDictId)
+      const txt: string = resTagFu(info.tagDictId, '藏品')
 
       if (txt) {
         const arr = txt.split(';')
@@ -252,9 +252,22 @@ function ZgoodsInfo() {
           )
         })
       }
+
+      const txt2: string = resTagFu(info.artDictId, '文创')
+
+      if (txt2) {
+        const arr = txt2.split(';')
+        arr.forEach((v, i) => {
+          dom.push(
+            <Tag key={v + i} className='GItag2'>
+              {v}
+            </Tag>
+          )
+        })
+      }
     }
     return dom
-  }, [info.tagDictId])
+  }, [info.artDictId, info.tagDictId])
 
   // 切换左侧tab
   const cutTabFu = useCallback(

+ 24 - 4
src/pages/Zother/AddClues/index.tsx

@@ -10,6 +10,8 @@ import TextArea from 'antd/es/input/TextArea'
 import { getDictFu, selectObj } from '@/utils/dataChange'
 import Z3upFilesRef from '@/components/Z3upFilesRef'
 import MyPopconfirm from '@/components/MyPopconfirm'
+import { useSelector } from 'react-redux'
+import { RootState } from '@/store'
 
 type Props = {
   info: GoodsType
@@ -22,6 +24,9 @@ type Props = {
 }
 
 function AddClues({ closeFu, succFu, moduleId, info, fileUpInfo, isLook }: Props) {
+  // 获取标签 树结构
+  const E1tree = useSelector((state: RootState) => state.E1tag.treeData)
+
   // 设置表单ref
   const FormBoxRef = useRef<FormInstance>(null)
 
@@ -44,6 +49,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
+      }
+
       FormBoxRef.current?.setFieldsValue(obj)
 
       // 设置附件
@@ -91,6 +101,15 @@ function AddClues({ closeFu, succFu, moduleId, info, fileUpInfo, isLook }: Props
       //   return
       // }
 
+      let tagDictId = ''
+      if (obj.tagDictId.length) {
+        obj.tagDictId.forEach((v: string[], i: number) => {
+          tagDictId += v.join(',') + (i === obj.tagDictId.length - 1 ? '' : ';')
+        })
+      }
+
+      obj.tagDictId = tagDictId
+
       MessageFu.success(info.id > 0 ? '编辑成功' : '新增成功')
       succFu(info.id > 0 ? '编辑' : '新增', obj)
       closeFu()
@@ -151,16 +170,17 @@ function AddClues({ closeFu, succFu, moduleId, info, fileUpInfo, isLook }: Props
                 options={selectObj['完残程度']}
               />
             </Form.Item>
-
-            <Form.Item label='初步藏品类别' name='typeDictId'>
+            <Form.Item label='初步藏品标签' name='tagDictId'>
               <Cascader
                 disabled={isLook}
                 changeOnSelect
-                options={getDictFu('藏品类别')}
-                placeholder={isLook ? '(空)' : '请输入'}
+                options={E1tree}
+                placeholder={isLook ? '(空)' : '请选择'}
                 fieldNames={{ label: 'name', value: 'id', children: 'children' }}
                 allowClear={true}
                 showSearch={true}
+                multiple
+                maxTagCount='responsive'
               />
             </Form.Item>
 

+ 23 - 19
src/pages/Zother/AddGoods/index.tsx

@@ -17,13 +17,7 @@ import { API_getFileListByIds } from '@/store/action/Cledger/C4file'
 import { FileUpInfoType } from '../data'
 
 // 级联的数据转换成字符串
-export const cascaderChArr = [
-  'typeDictId',
-  'ageDictId',
-  'pcsUnitDictId',
-  'textureDictId',
-  'qualityLevelDictId'
-]
+export const cascaderChArr = ['ageDictId', 'pcsUnitDictId', 'textureDictId', 'qualityLevelDictId']
 
 // 下拉框为空的时候转变成null
 export const addZiSelectChArr = [
@@ -60,6 +54,7 @@ function AddGoods({
 }: Props) {
   // 获取标签 树结构
   const E1tree = useSelector((state: RootState) => state.E1tag.treeData)
+  const E3tree = useSelector((state: RootState) => state.E3label.treeData)
 
   // 设置表单ref
   const FormBoxRef = useRef<FormInstance>(null)
@@ -94,7 +89,11 @@ function AddGoods({
         if (!obj[v]) obj[v] = null
       })
 
-      // 处理藏品标签
+      // 处理文创标签
+      if (obj.artDictId) {
+        const artDictId = obj.artDictId.split(';').map((item: string) => item.split(','))
+        obj.artDictId = artDictId
+      }
       if (obj.tagDictId) {
         const tagDictId = obj.tagDictId.split(';').map((item: string) => item.split(','))
         obj.tagDictId = tagDictId
@@ -173,7 +172,16 @@ function AddGoods({
         if (values[v]) obj[v] = values[v].join(',')
       })
 
-      // 藏品标签-级联多选特殊处理
+      // 文创标签-级联多选特殊处理
+      let artDictId = ''
+      if (obj.artDictId.length) {
+        obj.artDictId.forEach((v: string[], i: number) => {
+          artDictId += v.join(',') + (i === obj.artDictId.length - 1 ? '' : ';')
+        })
+      }
+
+      obj.artDictId = artDictId
+
       let tagDictId = ''
       if (obj.tagDictId.length) {
         obj.tagDictId.forEach((v: string[], i: number) => {
@@ -183,12 +191,6 @@ function AddGoods({
 
       obj.tagDictId = tagDictId
 
-      // if (1 + 1 === 2) {
-      //   // console.log('pppppp', obj.tagDictId)
-
-      //   return
-      // }
-
       if (isEdit) {
         // 藏品编辑模块
         let flag = true
@@ -288,10 +290,10 @@ function AddGoods({
               <Input placeholder='请输入' showCount maxLength={30} />
             </Form.Item>
 
-            <Form.Item label='藏品标签' name='tagDictId'>
+            <Form.Item label='文创标签' name='artDictId'>
               <Cascader
                 changeOnSelect
-                options={E1tree}
+                options={E3tree}
                 placeholder='请选择'
                 fieldNames={{ label: 'name', value: 'id', children: 'children' }}
                 allowClear={true}
@@ -341,14 +343,16 @@ function AddGoods({
               <Select allowClear={true} placeholder='请选择' options={selectObj['藏品级别']} />
             </Form.Item>
 
-            <Form.Item label='藏品类别' name='typeDictId'>
+            <Form.Item label='藏品标签' name='tagDictId'>
               <Cascader
                 changeOnSelect
-                options={getDictFu('藏品类别')}
+                options={E1tree}
                 placeholder='请选择'
                 fieldNames={{ label: 'name', value: 'id', children: 'children' }}
                 allowClear={true}
                 showSearch={true}
+                multiple
+                maxTagCount='responsive'
               />
             </Form.Item>
 

+ 17 - 13
src/pages/Zother/SonGoodsList/data.ts

@@ -67,6 +67,9 @@ export type GoodsType = {
 
   // 库存信息id
   storageId: number
+
+  // 文创标签
+  artDictId: string
 }
 
 // 选择线索-----------------
@@ -86,12 +89,13 @@ export const sgTopSelectDom = [
     key: 'searchKey',
     type: 'Input'
   },
-  {
-    name: '初定类别',
-    key: 'typeDictId',
-    type: 'Cascader',
-    options: getDictFu('藏品类别')
-  },
+  // 待完善sg
+  // {
+  //   name: '初定类别',
+  //   key: 'typeDictId',
+  //   type: 'Cascader',
+  //   options: getDictFu('藏品类别')
+  // },
   {
     name: '初定年代',
     key: 'ageDictId',
@@ -139,13 +143,13 @@ export const sgTopSelectDomGood = [
     type: 'Select',
     options: selectObj['藏品级别']
   },
-
-  {
-    name: '类别',
-    key: 'typeDictId',
-    type: 'Cascader',
-    options: getDictFu('藏品类别')
-  },
+  // 待完善sg
+  // {
+  //   name: '类别',
+  //   key: 'typeDictId',
+  //   type: 'Cascader',
+  //   options: getDictFu('藏品类别')
+  // },
   {
     name: '年代',
     key: 'ageDictId',

+ 37 - 0
src/store/action/Eculture/E3label.ts

@@ -0,0 +1,37 @@
+import { TypeI5Tree } from '@/pages/Isystem/I5organization/data'
+import { AppDispatch } from '@/store'
+import http from '@/utils/http'
+
+/**
+ * 标签 - 获取树列表
+ */
+export const E3_APIgetTree = (callFu?: (data: TypeI5Tree[]) => void): any => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.get('cms/art/getTree')
+    if (res.code === 0) {
+      callFu && callFu(res.data || [])
+      dispatch({ type: 'E3/getTree', payload: res.data || [] })
+    }
+  }
+}
+
+/**
+ * 标签 - 删除
+ */
+export const E3_APIdel = (id: string) => {
+  return http.get(`cms/art/remove/${id}`)
+}
+
+/**
+ * 标签 - 获取详情
+ */
+export const E3_APIgetInfo = (id: string) => {
+  return http.get(`cms/art/detail/${id}`)
+}
+
+/**
+ * 标签 - 新增或修改
+ */
+export const E3_APIsave = (data: any) => {
+  return http.post('cms/art/save', { ...data, type: 'art' })
+}

+ 9 - 1
src/store/action/layout.ts

@@ -13,7 +13,15 @@ export const userLoginAPI = (data: any) => {
 /**
  * 修改密码接口
  */
-export const passWordEditAPI = (data: any) => {
+export const passWordEditAPI = (data: any, token?: string) => {
+  const config: any = {}
+  if (token) {
+    config.headers = { satoken: token }
+  }
+  return http.post('sys/user/updatePwd', { ...data }, config)
+}
+
+export const passWordEditAPI2 = (data: any) => {
   return http.post('sys/user/updatePwd', { ...data })
 }
 

+ 25 - 0
src/store/reducer/Eculture/E3label.ts

@@ -0,0 +1,25 @@
+import { TypeI5Tree } from '@/pages/Isystem/I5organization/data'
+
+// 初始化状态
+const initState = {
+  // 树数据
+  treeData: [] as TypeI5Tree[]
+}
+
+// 定义 action 类型
+type Props = {
+  type: 'E3/getTree'
+  payload: TypeI5Tree[]
+}
+
+// reducer
+export default function Reducer(state = initState, action: Props) {
+  switch (action.type) {
+    // 获取树数据
+    case 'E3/getTree':
+      return { ...state, treeData: action.payload }
+
+    default:
+      return state
+  }
+}

+ 2 - 0
src/store/reducer/index.ts

@@ -17,6 +17,7 @@ import D3writeOff from './Dmanage/D3writeOff'
 import D4resource from './Dmanage/D4resource'
 import E1tag from './Eculture/E1tag'
 import E2story from './Eculture/E2story'
+import E3label from './Eculture/E3label'
 import G1accident from './Gmaintain/G1accident'
 import G2actuality from './Gmaintain/G2actuality'
 import G3repair from './Gmaintain/G3repair'
@@ -54,6 +55,7 @@ const rootReducer = combineReducers({
   D4resource,
   E1tag,
   E2story,
+  E3label,
 
   G1accident,
   G2actuality,

+ 5 - 5
src/utils/dataChange.tsx

@@ -180,8 +180,7 @@ export const selectObj = {
 export const getDictFu = (key: string) => {
   const dictAll = store.getState().I2dict.dictAll
   const list = dictAll.filter(v => v.name === key)
-
-  return list[0].children
+  return list ? list[0].children : []
 }
 
 // -------------------级联回显-------------------
@@ -202,9 +201,10 @@ export const resJiLianFu = (idTemp: string, type?: 'tag', isNull?: string) => {
   } else return isNull || '(空)'
 }
 
-// 藏品标签回显
-export function resTagFu(idString: string): any {
-  const dataList = store.getState().E1tag.treeData
+// 藏品标签回显 、文创标签回显
+export function resTagFu(idString: string, type: '藏品' | '文创'): any {
+  const dataList =
+    type === '藏品' ? store.getState().E1tag.treeData : store.getState().E3label.treeData
 
   // 1. 构建ID到名称的映射
   const idToNameMap = new Map<string, string>()

+ 3 - 0
src/utils/http.ts

@@ -5,6 +5,9 @@ import store from '@/store'
 import { MessageFu } from './message'
 import { domShowFu } from './domShow'
 
+// 初始默认密码
+export const defaultPassWord = 'Aa147852'
+
 export const envFlag = process.env.NODE_ENV === 'development'
 
 // const baseUrlTemp = 'https://sit-qingdaobeer.4dage.com' // 测试环境

+ 7 - 7
src/utils/tableData.ts

@@ -36,7 +36,7 @@ export const SonClueListTableC = [
   ['txt', '线索编号', 'num'],
   ['text', '线索简介', 'intro', 50],
   ['txt', '联系方式', 'phone'],
-  ['txtC', '初步藏品类别', 'typeDictId'],
+  ['txtCTag', '初步藏品标签', 'tagDictId', '藏品'],
   ['txtC', '初步藏品年代', 'ageDictId'],
   ['select', '完残程度', 'tornLevel', selectObj['完残程度']],
   ['text', '备注', 'remark', 50]
@@ -47,10 +47,10 @@ export const goodsSonTableC = (loc?: boolean) => {
   const arr: any = [
     ['txt', '藏品登记号', 'num'],
     ['img', '封面', 'thumb'],
-    ['txtCTag', '藏品标签', 'tagDictId'],
+    ['txtCTag', '藏品标签', 'tagDictId', '藏品'],
+    ['txtCTag', '文创标签', 'artDictId', '文创'],
     ['txt', '藏品名称', 'name'],
     ['select', '级别', 'level', selectObj['藏品级别']],
-    ['txtC', '类别', 'typeDictId'],
     ['txtC', '年代', 'ageDictId'],
     ['txtC', '质地', 'textureDictId'],
     ['select', '完残程度', 'tornLevel', selectObj['完残程度']],
@@ -65,7 +65,7 @@ export const goodsSelectCuleC = [
   ['txt', '线索编号', 'num'],
   ['img', '封面', 'thumb'],
   ['txt', '线索名称', 'name'],
-  ['txtC', '初定类别', 'typeDictId'],
+  ['txtCTag', '初步藏品标签', 'tagDictId', '藏品'],
   ['txtC', '初定年代', 'ageDictId'],
   ['select', '完残程度', 'tornLevel', selectObj['完残程度']]
 ]
@@ -117,7 +117,7 @@ export const I8tableC = [
 export const storyTableC = [
   ['txt', '故事标题', 'name'],
   ['txt', '关联藏品', 'goodName'],
-  ['txt', '藏品标签', 'tagName'],
+  ['txt', '藏品标签', 'tagName', '藏品'],
   ['txt', '录入人', 'creatorName'],
   ['txt', '录入日期', 'createTime']
 ]
@@ -125,7 +125,7 @@ export const storyTableC = [
 export const storyAndGoodsTableC = [
   ['txt', '藏品登记号', 'num'],
   ['img', '封面', 'thumb'],
-  ['txt', '藏品标签', 'tagName'],
+  ['txt', '藏品标签', 'tagName', '藏品'],
   ['txt', '藏品名称', 'name']
 ]
 
@@ -293,7 +293,7 @@ export const staffTableC = [
 export const showGoodTableC = [
   ['txt', '藏品登记号', 'goodNum'],
   ['img', '封面', 'goodThumb'],
-  ['txtCTag', '藏品标签', 'goodTag'],
+  ['txtCTag', '藏品标签', 'goodTag', '藏品'],
   ['txt', '藏品名称', 'goodName'],
   ['txt', '展区', 'region'],
   ['txt', '具体位置', 'address'],