chenlei 3 månader sedan
förälder
incheckning
b27e311d76
31 ändrade filer med 2935 tillägg och 231 borttagningar
  1. 235 200
      src/components/MyTable/index.tsx
  2. 4 2
      src/components/ZGaddNow/index.tsx
  3. 14 0
      src/pages/A_workbench/A1dataSta/constants.ts
  4. 8 0
      src/pages/A_workbench/A1dataSta/panel.module.scss
  5. 16 0
      src/pages/A_workbench/A1dataSta/panel.tsx
  6. 1 1
      src/pages/A_workbench/A4voucher/index.tsx
  7. 1 0
      src/pages/C_goodsManage/C21wealth/C21edit/index.tsx
  8. 0 20
      src/pages/C_goodsManage/C21wealth/constants.ts
  9. 131 0
      src/pages/D_storeManage/D3staff/D3edit/index.module.scss
  10. 451 0
      src/pages/D_storeManage/D3staff/D3edit/index.tsx
  11. 44 0
      src/pages/D_storeManage/D3staff/components/OutsiderModal/index.tsx
  12. 47 0
      src/pages/D_storeManage/D3staff/constants.ts
  13. 69 0
      src/pages/D_storeManage/D3staff/index.module.scss
  14. 272 3
      src/pages/D_storeManage/D3staff/index.tsx
  15. 32 0
      src/pages/D_storeManage/D3staff/types.ts
  16. 143 0
      src/pages/D_storeManage/D7check/D7edit/index.module.scss
  17. 581 0
      src/pages/D_storeManage/D7check/D7edit/index.tsx
  18. 43 0
      src/pages/D_storeManage/D7check/components/BatchFillingModal/index.tsx
  19. 152 0
      src/pages/D_storeManage/D7check/components/StocktakingModal/index.tsx
  20. 116 0
      src/pages/D_storeManage/D7check/constants.tsx
  21. 64 0
      src/pages/D_storeManage/D7check/index.module.scss
  22. 257 2
      src/pages/D_storeManage/D7check/index.tsx
  23. 28 0
      src/pages/D_storeManage/D7check/types.ts
  24. 12 0
      src/pages/Layout/data.ts
  25. 2 2
      src/store/action/C1ledger.ts
  26. 69 0
      src/store/action/D3staff.ts
  27. 73 0
      src/store/action/D7check.ts
  28. 28 0
      src/store/reducer/D3staff.ts
  29. 28 0
      src/store/reducer/D7check.ts
  30. 5 1
      src/store/reducer/index.ts
  31. 9 0
      src/utils/objects.ts

+ 235 - 200
src/components/MyTable/index.tsx

@@ -1,11 +1,18 @@
-import React, { useCallback, useEffect, useMemo, useState } from 'react'
+import React, {
+  forwardRef,
+  useCallback,
+  useEffect,
+  useImperativeHandle,
+  useMemo,
+  useState
+} from 'react'
 import styles from './index.module.scss'
-import { DatePicker, Input, Table } from 'antd'
+import { DatePicker, Form, FormInstance, Input, Table, TableProps } from 'antd'
 import ImageLazy from '../ImageLazy'
 import classNames from 'classnames'
 import { resJiLianFu } from '@/utils/history'
 
-type Props = {
+interface MyTableProps extends Omit<TableProps, 'onChange'> {
   yHeight?: number //设置表格的高度
   list: any //表格数据
   columnsTemp: any[][] //表格展示
@@ -26,217 +33,245 @@ type Props = {
   // 设置宽度
   widthSet?: any
   rowKey?: string
+  readOnly?: boolean
 }
 
-function MyTable({
-  yHeight,
-  list,
-  columnsTemp,
-  total,
-  pageNum = 1,
-  pageSize = 10,
-  pagingInfo = {
-    showQuickJumper: true,
-    position: ['bottomCenter'],
-    showSizeChanger: true
-  },
-  onChange,
-  lastBtn = [],
-  startBtn = [],
-  classKey = '',
-  merge,
-  myTitle,
-  isNull = '(空)',
-  widthSet,
-  rowKey = 'id'
-}: Props) {
-  // 点击操作高亮
-  const [clickAc, setClickAc] = useState(0)
-
-  // 表格内容定制化
-  const tableComObj = useCallback(
-    (key: string, val: string[], id?: any, backFu?: (id: number) => void) => {
-      const obj = {
-        // 超链接打开
-        A: (
-          <a href={val[1]} target='_blank' title={val[1]} rel='noreferrer'>
-            {val[0]}
-          </a>
-        ),
-        // 点击触发事件
-        S: (
-          <span
-            className={classNames('MTclick', clickAc === id ? 'MTclickAc' : '')}
-            onClick={() => {
-              if (id && backFu) {
-                backFu(id)
-                setClickAc(id)
-              }
-            }}
-          >
-            {val[1]}
-          </span>
-        )
-      }
-      return Reflect.get(obj, key)
+export interface MyTableMethods {
+  form: FormInstance<any>
+}
+
+const MyTable = forwardRef<MyTableMethods, MyTableProps>(
+  (
+    {
+      yHeight,
+      list,
+      columnsTemp,
+      total,
+      pageNum = 1,
+      pageSize = 10,
+      pagingInfo = {
+        showQuickJumper: true,
+        position: ['bottomCenter'],
+        showSizeChanger: true
+      },
+      onChange,
+      lastBtn = [],
+      startBtn = [],
+      classKey = '',
+      merge,
+      myTitle,
+      isNull = '(空)',
+      widthSet,
+      rowKey = 'id',
+      readOnly,
+      ...rest
     },
-    [clickAc]
-  )
+    ref
+  ) => {
+    // 点击操作高亮
+    const [clickAc, setClickAc] = useState(0)
+    const [form] = Form.useForm()
 
-  useEffect(() => {
-    const dom = document.querySelector(`.MyTable${classKey} .ant-table-body`) as HTMLDivElement
+    // 表格内容定制化
+    const tableComObj = useCallback(
+      (key: string, val: string[], id?: any, backFu?: (id: number) => void) => {
+        const obj = {
+          // 超链接打开
+          A: (
+            <a href={val[1]} target='_blank' title={val[1]} rel='noreferrer'>
+              {val[0]}
+            </a>
+          ),
+          // 点击触发事件
+          S: (
+            <span
+              className={classNames('MTclick', clickAc === id ? 'MTclickAc' : '')}
+              onClick={() => {
+                if (id && backFu) {
+                  backFu(id)
+                  setClickAc(id)
+                }
+              }}
+            >
+              {val[1]}
+            </span>
+          )
+        }
+        return Reflect.get(obj, key)
+      },
+      [clickAc]
+    )
 
-    if (dom && yHeight) dom.style.height = yHeight + 'px'
-  }, [classKey, yHeight])
+    useEffect(() => {
+      const dom = document.querySelector(`.MyTable${classKey} .ant-table-body`) as HTMLDivElement
 
-  // 页码变化
-  const paginationChange = useCallback(
-    () => (pageNum: number, pageSize: number) => {
-      if (onChange) {
-        onChange(pageNum, pageSize)
-      }
-    },
-    [onChange]
-  )
-
-  const dataChangeFu = useCallback(
-    (v: any) => {
-      /**
-       * index:序号
-       * txt:正常数据
-       * img:图片
-       * txtChange:判断显示不同字段
-       * text:文字比较多的情况
-       */
-
-      const obj = {
-        index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize,
-        txt: (item: any) =>
-          v[3] && !item[v[2]] ? (
-            <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
-          ) : (
-            item[v[2]] || isNull
-          ),
-        // 多个字段拼接
-        ping: (item: any) => (item[v[2]] || '') + (resJiLianFu(item[v[3]]) || '') || isNull,
-        // 这个模块特有的级联控制
-        txtC: (item: any) =>
-          v[1] === '年代' && item[v[2]] === '其他' ? '其他' : resJiLianFu(item[v[2]]),
-        // 尺寸
-        size: (item: any) => {
-          let danWei = resJiLianFu(item.sizeUnit, ' ')
-
-          let txt1 = item.sizeL ? `通长${item.sizeL}` : ''
-          let txt2 = item.sizeW ? `通宽${item.sizeW}` : ''
-          let txt3 = item.sizeH ? `通高${item.sizeH}` : ''
-
-          txt1 = txt1 ? txt1 + danWei : ''
-          txt2 = txt2 ? txt2 + danWei : ''
-          txt3 = txt3 ? txt3 + danWei : ''
-
-          let arr = [txt1, txt2, txt3]
-          arr = arr.filter(v => v)
-
-          if (!txt1 && !txt2 && !txt3) return '(空)'
-          else return arr.join(' - ')
-        },
-        img: (item: any) =>
-          v[3] && !item[v[2]] ? (
-            <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
-          ) : (
-            <div className='tableImgAuto'>
-              <ImageLazy
-                width={60}
-                height={60}
-                srcBig={item.thumbPc || item.filePath}
-                src={item[v[2]] || item.thumb}
-                offline={(item[v[2]] || item.thumb).includes('http')}
-              />
-            </div>
-          ),
-        txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
-        text: (item: any) => {
-          let tempCom: any = item[v[2]] || isNull
+      if (dom && yHeight) dom.style.height = yHeight + 'px'
+    }, [classKey, yHeight])
 
-          if (tempCom.length >= v[3]) {
-            tempCom = tempCom.substring(0, v[3]) + '...'
-          }
+    // 页码变化
+    const paginationChange = useCallback(
+      () => (pageNum: number, pageSize: number) => {
+        if (onChange) {
+          onChange(pageNum, pageSize)
+        }
+      },
+      [onChange]
+    )
+
+    const dataChangeFu = useCallback(
+      (v: any) => {
+        /**
+         * index:序号
+         * txt:正常数据
+         * img:图片
+         * txtChange:判断显示不同字段
+         * text:文字比较多的情况
+         */
+
+        const obj = {
+          index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize,
+          txt: (item: any) =>
+            v[3] && !item[v[2]] ? (
+              <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
+            ) : (
+              item[v[2]] || isNull
+            ),
+          // 多个字段拼接
+          ping: (item: any) => (item[v[2]] || '') + (resJiLianFu(item[v[3]]) || '') || isNull,
+          // 这个模块特有的级联控制
+          txtC: (item: any) =>
+            v[1] === '年代' && item[v[2]] === '其他' ? '其他' : resJiLianFu(item[v[2]]),
+          // 尺寸
+          size: (item: any) => {
+            let danWei = resJiLianFu(item.sizeUnit, ' ')
+
+            let txt1 = item.sizeL ? `通长${item.sizeL}` : ''
+            let txt2 = item.sizeW ? `通宽${item.sizeW}` : ''
+            let txt3 = item.sizeH ? `通高${item.sizeH}` : ''
+
+            txt1 = txt1 ? txt1 + danWei : ''
+            txt2 = txt2 ? txt2 + danWei : ''
+            txt3 = txt3 ? txt3 + danWei : ''
+
+            let arr = [txt1, txt2, txt3]
+            arr = arr.filter(v => v)
+
+            if (!txt1 && !txt2 && !txt3) return '(空)'
+            else return arr.join(' - ')
+          },
+          img: (item: any) =>
+            v[3] && !item[v[2]] ? (
+              <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
+            ) : (
+              <div className='tableImgAuto'>
+                <ImageLazy
+                  width={60}
+                  height={60}
+                  srcBig={item.thumbPc || item.filePath}
+                  src={item[v[2]] || item.thumb}
+                  offline={(item[v[2]] || item.thumb).includes('http')}
+                />
+              </div>
+            ),
+          txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
+          text: (item: any) => {
+            let tempCom: any = item[v[2]] || isNull
 
-          if (v[4]) {
-            tempCom = tableComObj(v[4], [tempCom, item[v[2]]], item.id, v[5])
-          } else if ((item[v[2]] || '').length >= v[3]) {
-            tempCom = (
-              <span style={{ cursor: 'pointer' }} title={item[v[2]]}>
-                {tempCom}
-              </span>
+            if (tempCom.length >= v[3]) {
+              tempCom = tempCom.substring(0, v[3]) + '...'
+            }
+
+            if (v[4]) {
+              tempCom = tableComObj(v[4], [tempCom, item[v[2]]], item.id, v[5])
+            } else if ((item[v[2]] || '').length >= v[3]) {
+              tempCom = (
+                <span style={{ cursor: 'pointer' }} title={item[v[2]]}>
+                  {tempCom}
+                </span>
+              )
+            }
+
+            return tempCom
+          },
+          input: (item: any) => {
+            return (
+              <Form.Item noStyle name={`${item.id}-${v[2]}`}>
+                <Input
+                  allowClear
+                  readOnly={readOnly}
+                  maxLength={v[3]?.maxLength}
+                  placeholder={v[3]?.placeholder || '请输入'}
+                />
+              </Form.Item>
+            )
+          },
+          datePicker: (item: any) => {
+            return (
+              <Form.Item noStyle name={`${item.id}-${v[2]}`}>
+                <DatePicker readOnly={readOnly} />
+              </Form.Item>
+            )
+          },
+          custom: (item: any) => {
+            return (
+              <Form.Item noStyle name={`${item.id}-${v[2]}`}>
+                {v[3].render(readOnly)}
+              </Form.Item>
             )
           }
-
-          return tempCom
-        },
-        input: (item: any) => {
-          return (
-            <Input
-              allowClear
-              value={item[v[2]]}
-              maxLength={v[3]?.maxLength}
-              placeholder={v[3]?.placeholder || '请输入'}
-              // @ts-ignore
-              onInput={v => (item[v[2]] = v.target.value)}
-            />
-          )
-        },
-        datePicker: (item: any) => {
-          return (
-            // @ts-ignore
-            <DatePicker onChange={v => (item[v[2]] = v)} />
-          )
         }
-      }
 
-      return Reflect.get(obj, v[0])
-    },
-    [isNull, pageNum, pageSize, tableComObj]
-  )
-
-  const columns = useMemo(() => {
-    const arr: any = columnsTemp.map((v: any) => ({
-      title: myTitle && v.includes(myTitle.name) ? myTitle.Com : v[1],
-      render: dataChangeFu(v),
-      width: widthSet && Reflect.get(widthSet, v[2]) ? Reflect.get(widthSet, v[2]) : 'auto',
-      onCell:
-        merge && v.includes(merge.type)
-          ? // {rowSpan:3}
-            (item: any, index: number) => ({
-              rowSpan: index === 0 ? merge.num : 0
-            })
-          : ''
+        return Reflect.get(obj, v[0])
+      },
+      [isNull, pageNum, pageSize, readOnly, tableComObj]
+    )
+
+    const columns = useMemo(() => {
+      const arr: any = columnsTemp.map((v: any) => ({
+        title: myTitle && v.includes(myTitle.name) ? myTitle.Com : v[1],
+        render: dataChangeFu(v),
+        width: widthSet && Reflect.get(widthSet, v[2]) ? Reflect.get(widthSet, v[2]) : 'auto',
+        onCell:
+          merge && v.includes(merge.type)
+            ? // {rowSpan:3}
+              (item: any, index: number) => ({
+                rowSpan: index === 0 ? merge.num : 0
+              })
+            : ''
+      }))
+
+      return arr
+    }, [columnsTemp, dataChangeFu, merge, myTitle, widthSet])
+
+    useImperativeHandle(ref, () => ({
+      form
     }))
 
-    return arr
-  }, [columnsTemp, dataChangeFu, merge, myTitle, widthSet])
-
-  return (
-    <Table
-      className={`${styles.MyTable} MyTable${classKey}`}
-      scroll={{ y: yHeight ? yHeight : '' }}
-      dataSource={list}
-      columns={[...startBtn, ...columns, ...lastBtn]}
-      rowKey={rowKey}
-      pagination={
-        pagingInfo
-          ? {
-              ...pagingInfo,
-              current: pageNum,
-              pageSize: pageSize,
-              total: total,
-              onChange: paginationChange()
-            }
-          : false
-      }
-    />
-  )
-}
+    return (
+      <Form form={form} component={false}>
+        <Table
+          {...rest}
+          className={`${styles.MyTable} MyTable${classKey}`}
+          scroll={{ y: yHeight ? yHeight : '' }}
+          dataSource={list}
+          columns={[...startBtn, ...columns, ...lastBtn]}
+          rowKey={rowKey}
+          pagination={
+            pagingInfo
+              ? {
+                  ...pagingInfo,
+                  current: pageNum,
+                  pageSize: pageSize,
+                  total: total,
+                  onChange: paginationChange()
+                }
+              : false
+          }
+        />
+      </Form>
+    )
+  }
+)
 
 const MemoMyTable = React.memo(MyTable)
 

+ 4 - 2
src/components/ZGaddNow/index.tsx

@@ -22,6 +22,7 @@ type Props = {
   canObj?: any //其他页面带过来的参数
   // 藏品登记-只选择一个
   register?: boolean
+  httpType?: 'get' | 'post'
 }
 
 function ZGaddNow({
@@ -31,7 +32,8 @@ function ZGaddNow({
   dataResFu,
   oldCheckArr,
   canObj,
-  register
+  register,
+  httpType = 'post'
 }: Props) {
   // 入藏状态特别过滤
   const RuChangSelect = useMemo(() => {
@@ -75,7 +77,7 @@ function ZGaddNow({
       ...formDataRef.current,
       ...canObjTemp
     }
-    const res = await API_goodsNowAdd(nowSta.id, obj)
+    const res = await API_goodsNowAdd(nowSta.id, obj, httpType)
     if (res.code === 0) {
       const arr: any = res.data.map((v: any) => ({
         ...v,

+ 14 - 0
src/pages/A_workbench/A1dataSta/constants.ts

@@ -0,0 +1,14 @@
+export const A1DATA_TABS = [
+  {
+    label: '博物馆馆藏文物年度核查统计',
+    value: 0
+  },
+  {
+    label: '库存文物动态统计',
+    value: 1
+  },
+  {
+    label: '年度库房藏品',
+    value: 2
+  }
+]

+ 8 - 0
src/pages/A_workbench/A1dataSta/panel.module.scss

@@ -0,0 +1,8 @@
+.A1dataSta {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 24px 24px 0;
+  position: relative;
+  :global {
+  }
+}

+ 16 - 0
src/pages/A_workbench/A1dataSta/panel.tsx

@@ -0,0 +1,16 @@
+import React from 'react'
+import styles from './panel.module.scss'
+
+function A1dataSta() {
+  return (
+    <div className={styles.A1dataSta}>
+      <div className='pageTitle'>数据统计</div>
+
+      <div className='A1card'>123</div>
+    </div>
+  )
+}
+
+const MemoA1dataSta = React.memo(A1dataSta)
+
+export default MemoA1dataSta

+ 1 - 1
src/pages/A_workbench/A4voucher/index.tsx

@@ -164,7 +164,7 @@ function A4voucher() {
         }
       }
     ]
-  }, [tableBtnFu])
+  }, [tableBtnFu, downImg])
 
   // 多选
   const [checkArr, setCheckArr] = useState<number[]>([])

+ 1 - 0
src/pages/C_goodsManage/C21wealth/C21edit/index.tsx

@@ -518,6 +518,7 @@ function C21edit() {
       {/* 新增弹窗 */}
       {nowSta.id ? (
         <ZGaddNow
+          httpType='get'
           nowSta={nowSta}
           closeFu={() => setNowSta({ key: '', id: '' })}
           dataResFu={data => {

+ 0 - 20
src/pages/C_goodsManage/C21wealth/constants.ts

@@ -21,26 +21,6 @@ export const C21WEALTH_TABLE_COLUMNS = [
   ['txtChange', '申请状态', 'status', statusObj]
 ]
 
-export const C21WEALTH_COLUMNS = [
-  ['img', '封面图', 'thumb'],
-  ['txt', '编号类型', 'numName'],
-  ['txt', '藏品编号', 'goodsNum'],
-  ['txt', '藏品名称', 'goodsName'],
-  ['ping', '数量', 'pcs', 'pcsUnit'],
-  ['txtChange', '库存状态', 'statusStorage', statusStorageObj],
-  [
-    'input',
-    '放置位置',
-    'address',
-    {
-      maxLength: 20,
-      placeholder: '请填写内容,不超过20字'
-    }
-  ],
-  ['datePicker', '借出日期 *', 'startDate'],
-  ['datePicker', '预计归还日期 *', 'endDate']
-]
-
 export const MEDIA_TYPES = [
   {
     label: '图像',

+ 131 - 0
src/pages/D_storeManage/D3staff/D3edit/index.module.scss

@@ -0,0 +1,131 @@
+.D3staff {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 15px 24px 0px;
+  :global {
+    .D4Tit {
+      font-size: 18px;
+      font-weight: 700;
+      padding-bottom: 10px;
+      padding-left: 18px;
+      border-bottom: 1px solid #ccc;
+      margin-bottom: 17px;
+      color: var(--themeColor);
+      .ant-btn {
+        margin-left: 15px;
+        pointer-events: none;
+      }
+    }
+    .D4main {
+      width: 100%;
+      height: calc(100% - 70px);
+      overflow-y: auto;
+      padding-bottom: 40px;
+
+      .D4rowAll {
+        display: flex;
+        justify-content: space-between;
+        align-items: self-start;
+        font-size: 16px;
+        flex-wrap: wrap;
+        .D4row {
+          width: 48%;
+          display: flex;
+          align-items: center;
+          margin-bottom: 20px;
+          .D4rowll {
+            width: 120px;
+            text-align: right;
+            font-weight: 700;
+            & > span {
+              color: #ff4d4f;
+            }
+          }
+          .D4rowrr {
+            width: calc(100% - 120px);
+            .ant-input-affix-wrapper {
+              width: 300px;
+            }
+            .ant-select {
+              width: 300px;
+            }
+          }
+        }
+        .D4row2 {
+          align-items: self-start;
+          .D4rowll {
+            position: relative;
+            top: 3px;
+          }
+        }
+        .D4row3 {
+          position: relative;
+          top: 4px;
+        }
+
+        .D4rowFull {
+          width: 100%;
+          margin-top: -20px;
+          align-items: self-start;
+          margin-bottom: 0;
+          .D4rowll {
+            position: relative;
+            top: 3px;
+          }
+        }
+      }
+      // 藏品清单
+      .D4googsBox {
+        padding-right: 20px;
+        .D1GtNum {
+          cursor: pointer;
+          text-decoration: underline;
+          // &:hover {
+          //   color: var(--themeColor);
+          // }
+        }
+
+        .D1GtNumAc {
+          color: var(--themeColor);
+        }
+      }
+      .D4Tit2 {
+        margin-top: 24px;
+        display: flex;
+        justify-content: space-between;
+        padding-bottom: 10px;
+        border-bottom: 1px solid #ccc;
+        margin-bottom: 20px;
+        .D4Tit2ll {
+          font-size: 18px;
+          font-weight: 700;
+          padding-left: 18px;
+          margin-bottom: 17px;
+          color: var(--themeColor);
+        }
+        .D4Tit2rr {
+          position: relative;
+          z-index: 2;
+          .ant-btn {
+            margin-left: 15px;
+          }
+        }
+      }
+    }
+
+    .D4btn {
+      position: absolute;
+      bottom: 20px;
+      left: 134px;
+      .ant-btn {
+        margin-right: 20px;
+      }
+    }
+  }
+}
+
+.tabRow {
+  margin-bottom: 15px;
+  display: flex;
+  justify-content: space-between;
+}

+ 451 - 0
src/pages/D_storeManage/D3staff/D3edit/index.tsx

@@ -0,0 +1,451 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { useParams } from 'react-router-dom'
+import { Button, DatePicker, Input, Select, Tabs } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import history, { btnFlagFu2 } from '@/utils/history'
+import { MessageFu } from '@/utils/message'
+import { statusObj } from '@/utils/tableData'
+import X3auditInfo from '@/pages/X_stock/X3auditInfo'
+import ZflowTable from '@/components/ZflowTable'
+import MyTable from '@/components/MyTable'
+import { EXbtnFu } from '@/utils/EXBtn'
+import {
+  D3_APIcreate,
+  D3_APIdel,
+  D3_APIgetInfo,
+  D3_APIsaveApply,
+  D3_APIsaveAudit,
+  D3_APIsaveCreate,
+  D3_APIsaveDraft
+} from '@/store/action/D3staff'
+import { D3StaffOversiderType, ID3StaffItem } from '../types'
+import { useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import { OutsiderModal } from '../components/OutsiderModal'
+import { D3STAFF_OUTSIDER_TABLE_COLUMNS } from '../constants'
+
+export const pageTitTxtObj = {
+  1: '新增',
+  2: '编辑',
+  3: '审批',
+  4: '查看'
+}
+
+function C21edit() {
+  const { key, id } = useParams<any>()
+  // key:1 新增 2编辑 3审批 4查看
+
+  // 滚到顶部
+  const sollrDom = useRef<HTMLDivElement>(null)
+  // 顶部数据
+  const [topInfo, setTopInfo] = useState({} as ID3StaffItem)
+  const storeList = useSelector((state: RootState) => state.D2storSet.tableInfo.list)
+  const [outsiderVisible, setOutsiderVisible] = useState(false)
+  const [oversiderList, setOversiderList] = useState<D3StaffOversiderType[]>([])
+
+  // 创建订单
+  const creatFu = useCallback(async () => {
+    const res = await D3_APIcreate()
+    if (res.code === 0) {
+      setTopInfo(res.data)
+    }
+  }, [])
+
+  // 获取详情
+  const getInfoFu = useCallback(async () => {
+    const res = await D3_APIgetInfo(id)
+    if (res.code === 0) {
+      setTopInfo(res.data)
+    }
+  }, [id])
+
+  useEffect(() => {
+    if (key === '1') creatFu()
+    else getInfoFu()
+
+    if (sollrDom.current) sollrDom.current.scrollTop = 0
+  }, [creatFu, getInfoFu, key])
+
+  // 富文本的ref
+  const ZRichTextRef = useRef<any>(null)
+
+  // 审批意见的ref
+  const ZAuditRef = useRef<any>(null)
+
+  const pageTitTxt = useMemo(() => {
+    return Reflect.get(pageTitTxtObj, key)
+  }, [key])
+
+  const checkDataFu = useCallback(() => {
+    if (!topInfo.date) {
+      MessageFu.warning('请选择入库时间')
+      return true
+    }
+    if (!topInfo.reason) {
+      MessageFu.warning('请输入入库事由')
+      return true
+    }
+
+    return false
+  }, [topInfo])
+
+  const curStore = useMemo(() => {
+    return storeList.find(i => i.id === topInfo.storageId)
+  }, [storeList, topInfo])
+
+  // 审批的sta
+  const [auditSta, setAuDitSta] = useState('')
+
+  // 新增的底部按钮点击
+  const btnClickFu = useCallback(
+    async (val: '草稿' | '创建' | '保存' | '审批') => {
+      if (checkDataFu()) return
+
+      if (val === '审批') {
+        // console.log('审批信息富文本', rtf2)
+        if (!auditSta) {
+          if (sollrDom.current) sollrDom.current.scrollTop = 0
+          return MessageFu.warning('请选择审批结果')
+        }
+        const rtf2 = ZAuditRef.current?.resData()
+
+        const res = await D3_APIsaveAudit({
+          orderId: topInfo.id,
+          rtfOpinion: rtf2,
+          status: auditSta === '同意' ? 1 : 2
+        })
+
+        if (res.code === 0) {
+          MessageFu.success('审批成功')
+          // 跳详情页
+          history.push(`/staff_edit/4/${topInfo.id}`)
+        }
+      } else {
+        const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
+        // console.log('申请信息富文本', JSON.stringify(rtf1.val || ''))
+
+        const obj = {
+          ...topInfo,
+          rtf: JSON.stringify(rtf1.val || '')
+        }
+        // console.log(123, obj)
+
+        // if (1 + 1 === 2) return
+
+        if (val === '草稿') {
+          // 存草稿 当前页保存 不跳转
+          const res = await D3_APIsaveDraft(obj)
+          if (res.code === 0) {
+            MessageFu.success('草稿保存成功')
+          }
+        } else {
+          const res = val === '创建' ? await D3_APIsaveCreate(obj) : await D3_APIsaveApply(obj)
+          if (res.code === 0) {
+            MessageFu.success(`${val}成功`)
+            // 跳到详情页
+            history.push(`/staff_edit/4/${topInfo.id}`)
+          }
+        }
+      }
+    },
+    [auditSta, checkDataFu, topInfo]
+  )
+
+  // 查看的按钮创建-提交-撤回
+  const lookBtnFu = useCallback(
+    async (val: '创建' | '提交') => {
+      const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
+      // console.log('申请信息富文本', JSON.stringify(rtf1.val || ''))
+
+      const obj = {
+        ...topInfo,
+        rtf: JSON.stringify(rtf1.val || '')
+      }
+
+      const res = val === '创建' ? await D3_APIsaveCreate(obj) : await D3_APIsaveApply(obj)
+
+      if (res.code === 0) {
+        if (sollrDom.current) sollrDom.current.scrollTop = 0
+        MessageFu.success(val + '成功')
+        getInfoFu()
+      }
+    },
+    [getInfoFu, topInfo]
+  )
+
+  // 查看模式点击删除
+  const delFu = useCallback(async () => {
+    const res = await D3_APIdel(id)
+    if (res.code === 0) {
+      MessageFu.success('删除成功')
+      history.push('/wealth')
+    }
+  }, [id])
+
+  // 查看模式点击审批 编辑
+  const lookJumpFu = useCallback(
+    (val: '审批' | '编辑') => {
+      history.push(`/staff_edit/${val === '审批' ? 3 : 2}/${id}`)
+      MessageFu.success(`已跳转至${val}页面`)
+    },
+    [id]
+  )
+
+  // 查看模式下的按钮
+  const lookBtn = useMemo(() => {
+    return (
+      <>
+        {btnFlagFu2(topInfo)['创建'] ? (
+          <Button type='primary' onClick={() => lookBtnFu('创建')}>
+            创建
+          </Button>
+        ) : null}
+        {btnFlagFu2(topInfo)['提交'] ? (
+          <Button type='primary' onClick={() => lookBtnFu('提交')}>
+            提交
+          </Button>
+        ) : null}
+
+        {btnFlagFu2(topInfo)['审批'] ? (
+          <Button type='primary' onClick={() => lookJumpFu('审批')}>
+            审批
+          </Button>
+        ) : null}
+        {btnFlagFu2(topInfo)['编辑'] ? (
+          <Button type='primary' onClick={() => lookJumpFu('编辑')}>
+            编辑
+          </Button>
+        ) : null}
+
+        {btnFlagFu2(topInfo)['重新提交'] ? (
+          <Button type='primary' onClick={() => lookBtnFu('提交')}>
+            重新提交
+          </Button>
+        ) : null}
+
+        {EXbtnFu(topInfo)}
+
+        {btnFlagFu2(topInfo)['删除'] ? (
+          <MyPopconfirm
+            txtK='删除'
+            onConfirm={() => delFu()}
+            Dom={
+              <Button type='primary' danger>
+                删除
+              </Button>
+            }
+          />
+        ) : null}
+
+        <Button onClick={() => history.push('/wealth')}>返回</Button>
+      </>
+    )
+  }, [delFu, lookBtnFu, lookJumpFu, topInfo])
+
+  // 申请记录
+  const [auditsShow, setAuditsShow] = useState(false)
+
+  return (
+    <div className={styles.D3staff}>
+      <div className='pageTitle'>人员出入库-{pageTitTxt}</div>
+
+      <div className='D4main' ref={sollrDom}>
+        {['3'].includes(key) ? (
+          <X3auditInfo
+            dirCode='D4wealth'
+            myUrl='cms/orderIn/upload'
+            auditSta={auditSta}
+            auditStaFu={val => setAuDitSta(val)}
+            ref={ZAuditRef}
+          />
+        ) : null}
+
+        {/* 表单字段、附件等 */}
+        <div className='D4Tit'>
+          申请信息
+          {key === '1' ? null : (
+            <Button type='dashed'>{Reflect.get(statusObj, topInfo.status)}</Button>
+          )}
+        </div>
+        <div className='D4rowAll'>
+          <div className='D4row'>
+            <div className='D4rowll'>业务单号:</div>
+            <div className='D4rowrr'>{topInfo.num}</div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>业务名称:</div>
+            <div className='D4rowrr'>{topInfo.name}</div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>发起人:</div>
+            <div className='D4rowrr'>{topInfo.creatorName}</div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>发起部门:</div>
+            <div className='D4rowrr'>{topInfo.deptName}</div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>
+              <span>*</span>入库时间:
+            </div>
+            <div className='D4rowrr'>
+              <DatePicker
+                showTime
+                onChange={(e, dateString) => setTopInfo({ ...topInfo, date: dateString as string })}
+              />
+            </div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>
+              <span>*</span>入库事由:
+            </div>
+            <div className='D4rowrr'>
+              <Input
+                value={topInfo.reason}
+                onChange={e => setTopInfo({ ...topInfo, reason: e.target.value })}
+                readOnly={['3', '4'].includes(key)}
+                placeholder='请输入内容'
+                maxLength={200}
+                showCount
+              />
+            </div>
+          </div>
+        </div>
+
+        {/* 库房信息 */}
+        <div className='D4googsBox'>
+          <div className='D4Tit2'>
+            <div className='D4Tit2ll'>库房信息</div>
+          </div>
+        </div>
+        <div className='D4rowAll'>
+          <div className='D4row'>
+            <div className='D4rowll'>库别名称:</div>
+            <div className='D4rowrr'>
+              <Select
+                placeholder='请选择'
+                options={storeList}
+                fieldNames={{ label: 'name', value: 'id' }}
+                onChange={e => setTopInfo({ ...topInfo, storageId: e })}
+              />
+            </div>
+          </div>
+          <div className='D4row'>
+            <div className='D4rowll'>库房负责人:</div>
+            <div className='D4rowrr'>{curStore?.managerUser || '--'}</div>
+          </div>
+        </div>
+
+        {/* 人员信息 */}
+        <div className='D4googsBox'>
+          <div className='D4Tit2'>
+            <div className='D4Tit2ll'>人员信息</div>
+          </div>
+
+          <Tabs
+            type='card'
+            items={[
+              {
+                key: '0',
+                label: '外部人员',
+                children: (
+                  <>
+                    <div className={styles.tabRow}>
+                      <Input
+                        addonBefore='陪同人员'
+                        placeholder='请填入姓名,以逗号分隔'
+                        style={{ width: 500 }}
+                        allowClear
+                      />
+
+                      <Button type='primary' onClick={() => setOutsiderVisible(true)}>
+                        新增
+                      </Button>
+                    </div>
+                    <MyTable
+                      rowKey='name'
+                      yHeight={200}
+                      list={oversiderList}
+                      columnsTemp={D3STAFF_OUTSIDER_TABLE_COLUMNS}
+                    />
+                  </>
+                )
+              },
+              {
+                key: '1',
+                label: '内部人员',
+                children: (
+                  <>
+                    <div className={styles.tabRow}>
+                      <Input
+                        addonBefore='进库人员 '
+                        placeholder='请填入姓名,以逗号分隔'
+                        style={{ width: 500 }}
+                        allowClear
+                      />
+                    </div>
+                  </>
+                )
+              }
+            ]}
+          />
+        </div>
+
+        {/* 申请流程 */}
+        {auditsShow ? (
+          <ZflowTable tableArr={topInfo.audits || []} closeFu={() => setAuditsShow(false)} />
+        ) : null}
+      </div>
+
+      {/* 底部按钮 */}
+      <div className='D4btn'>
+        {['3', '4'].includes(key) && topInfo.audits && topInfo.audits.length ? (
+          <Button type='primary' onClick={() => setAuditsShow(true)}>
+            申请记录
+          </Button>
+        ) : null}
+
+        {key === '4' ? (
+          lookBtn
+        ) : (
+          <>
+            {key === '3' ? (
+              <Button type='primary' onClick={() => btnClickFu('审批')}>
+                审批
+              </Button>
+            ) : (
+              <Button type='primary' onClick={() => btnClickFu(key === '1' ? '创建' : '保存')}>
+                {key === '1' ? '创建' : '保存'}
+              </Button>
+            )}
+
+            {key === '1' ? (
+              <Button type='primary' onClick={() => btnClickFu('草稿')}>
+                存草稿
+              </Button>
+            ) : null}
+
+            <MyPopconfirm txtK='取消' onConfirm={() => history.push('/wealth')} />
+          </>
+        )}
+      </div>
+
+      {/* 添加外部人员 */}
+      <OutsiderModal
+        visible={outsiderVisible}
+        setVisible={setOutsiderVisible}
+        onOk={item => setOversiderList([...oversiderList, item])}
+      />
+    </div>
+  )
+}
+
+const MemoC21edit = React.memo(C21edit)
+
+export default MemoC21edit

+ 44 - 0
src/pages/D_storeManage/D3staff/components/OutsiderModal/index.tsx

@@ -0,0 +1,44 @@
+import { Form, Input, Modal } from 'antd'
+import { FC } from 'react'
+import { D3StaffOversiderType } from '../../types'
+
+export interface OutsiderModalProps {
+  visible: boolean
+  setVisible: (v: boolean) => void
+  onOk: (item: D3StaffOversiderType) => void
+}
+
+export const OutsiderModal: FC<OutsiderModalProps> = ({ visible, setVisible, onOk }) => {
+  const [form] = Form.useForm()
+
+  const handleCancel = () => {
+    setVisible(false)
+  }
+
+  const handleSubmit = async () => {
+    if (!(await form.validateFields())) return
+
+    onOk(form.getFieldsValue())
+    setVisible(false)
+    form.resetFields()
+  }
+
+  return (
+    <Modal title='外部人员' open={visible} onCancel={handleCancel} onOk={handleSubmit}>
+      <Form form={form} labelCol={{ span: 5 }}>
+        <Form.Item label='姓名' required rules={[{ required: true }]} name='name'>
+          <Input maxLength={30} placeholder='请输入' />
+        </Form.Item>
+        <Form.Item label='联系方式' name='phone'>
+          <Input maxLength={30} placeholder='请输入' />
+        </Form.Item>
+        <Form.Item label='身份证号' name='papers'>
+          <Input maxLength={30} placeholder='请输入' />
+        </Form.Item>
+        <Form.Item label='所在单位' name='remark'>
+          <Input maxLength={30} placeholder='请输入' />
+        </Form.Item>
+      </Form>
+    </Modal>
+  )
+}

+ 47 - 0
src/pages/D_storeManage/D3staff/constants.ts

@@ -0,0 +1,47 @@
+import { selectObj } from '@/utils/select'
+import { D3StaffSearchType, ID3StaffParams } from './types'
+import { statusObj } from '@/utils/tableData'
+
+export const D3STAFF_PARAM_ROWS: D3StaffSearchType[] = [
+  { name: '业务编号', key: 'num', type: '输入框' },
+  { name: '入库日期范围', key: 'inDate', type: '日期选择' },
+  // { name: '入库人员类型', key: '', type: '输入框' },
+  // { name: '相关库房', key: '', type: '输入框' },
+  { name: '发起部门', key: 'deptName', type: '输入框' }
+]
+
+export const D3STAFF_PARAM_ROWS2: D3StaffSearchType[] = [
+  { name: '发起人', key: 'userName', type: '输入框' },
+  { name: '发起日期范围', key: 'date', type: '日期选择' },
+  { name: '申请状态', key: 'status', type: '下拉框', data: selectObj['流程申请状态'] },
+  { name: '选择角色', key: 'userType', type: '下拉框', data: selectObj['角色'] }
+]
+
+export const D3STAFF_TABLE_COLUMNS = [
+  ['txt', '业务编号', 'num'],
+  ['txt', '入库时间', 'name'],
+  ['txt', '入库人员', 'deptName'],
+  ['txt', '入库事由', 'userName'],
+  ['txt', '相关库房', 'createTime'],
+  ['txt', '发起部门', 'deptName'],
+  ['txt', '发起人', 'userName'],
+  ['txt', '发起日期', 'createTime'],
+  ['txtChange', '申请状态', 'status', statusObj]
+]
+
+export const D3STAFF_OUTSIDER_TABLE_COLUMNS = [
+  ['txt', '姓名', 'name'],
+  ['txt', '联系方式', 'phone'],
+  ['txt', '身份证号', 'papers'],
+  ['txt', '所在单位', 'remark']
+]
+
+export const DEFAULT_D3STAFF_PARAMS: ID3StaffParams = {
+  pageNum: 1,
+  pageSize: 10,
+  num: '',
+  userName: '',
+  deptName: '',
+  status: '',
+  userType: ''
+}

+ 69 - 0
src/pages/D_storeManage/D3staff/index.module.scss

@@ -1,4 +1,73 @@
 .D3staff {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 24px 24px 0;
+  position: relative;
   :global {
+    .C1top {
+      display: flex;
+      justify-content: space-between;
+      .C1topll {
+        display: flex;
+        & > div {
+          display: flex;
+          align-items: center;
+          position: relative;
+          &:not(:last-child) {
+            margin-right: 15px;
+          }
+          & > span {
+            position: absolute;
+            top: -18px;
+            left: 0;
+            pointer-events: none;
+          }
+        }
+      }
+
+      .C1toprrSuo {
+        width: 100%;
+        margin-top: 15px;
+        text-align: right;
+      }
+
+      .C1toprrKai {
+        position: relative;
+        top: 10px;
+        width: 310px;
+        height: 84px;
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+      }
+
+      .C1topllAll {
+        width: 100%;
+        & > div {
+          flex: 1;
+          .ant-input,
+          .ant-picker,
+          .ant-select {
+            width: 100%;
+          }
+        }
+      }
+    }
+    .C1top {
+      margin-bottom: 15px;
+
+      &:nth-child(2) {
+        margin-bottom: 25px;
+      }
+    }
+    .C1top2 {
+      justify-content: flex-end;
+    }
+    .ant-select-selection-placeholder {
+      color: black !important;
+    }
+    .ant-table-cell {
+      padding: 8px !important;
+    }
   }
 }

+ 272 - 3
src/pages/D_storeManage/D3staff/index.tsx

@@ -1,10 +1,279 @@
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import styles from './index.module.scss'
+import { useDispatch, useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import { Button, Cascader, DatePicker, Input, Select } from 'antd'
+import history, { btnFlagFu } from '@/utils/history'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import MyTable from '@/components/MyTable'
+import {
+  D3STAFF_PARAM_ROWS,
+  D3STAFF_PARAM_ROWS2,
+  D3STAFF_TABLE_COLUMNS,
+  DEFAULT_D3STAFF_PARAMS
+} from './constants'
+import { D3StaffSearchType, ID3StaffItem, ID3StaffParams } from './types'
+import { C21_APIdel } from '@/store/action/C21wealth'
+import { MessageFu } from '@/utils/message'
+import dayjs from 'dayjs'
+import { statusObj } from '@/utils/tableData'
+import ExportJsonExcel from 'js-export-excel'
+import { D3_APIList } from '@/store/action/D3staff'
+import { filterEmptyStrings } from '@/utils/objects'
+
+const { RangePicker } = DatePicker
+
 function D3staff() {
+  // 从仓库拿数据
+  const tableInfo = useSelector((state: RootState) => state.D3staff.tableInfo)
+  const [formData, setFormData] = useState({ ...DEFAULT_D3STAFF_PARAMS })
+  const formDataRef = useRef({ ...DEFAULT_D3STAFF_PARAMS })
+  const formDataOldRef = useRef({ ...DEFAULT_D3STAFF_PARAMS })
+  const dispatch = useDispatch()
+
+  // 输入框的改变
+  const txtChangeFu = useCallback(
+    (txt: string, key: keyof ID3StaffParams) => {
+      setFormData({
+        ...formData,
+        [key]: txt
+      })
+    },
+    [formData]
+  )
+
+  // 顶部筛选
+  const searchDom = useCallback(
+    (arr: D3StaffSearchType[]) => {
+      return arr.map(item => {
+        return (
+          <div key={item.name}>
+            <span>{item.name}:</span>
+            {item.type === '输入框' ? (
+              <Input
+                placeholder='请输入'
+                maxLength={30}
+                value={formData[item.key]}
+                onChange={e => txtChangeFu(e.target.value, item.key)}
+              />
+            ) : item.type === '下拉框' ? (
+              <Select
+                options={item.data}
+                placeholder='全部'
+                allowClear={true}
+                value={formData[item.key as 'num'] ? formData[item.key as 'num'] : null}
+                onChange={e => setFormData({ ...formData, [item.key]: e })}
+              />
+            ) : item.type === '日期选择' ? (
+              <RangePicker
+                format='YYYY-MM-DD'
+                allowClear={true}
+                onChange={(e, dateStrings) => setFormData({ ...formData, [item.key]: dateStrings })}
+              />
+            ) : (
+              <Cascader
+                options={item.data}
+                placeholder='全部'
+                fieldNames={{ label: 'name', value: 'id', children: 'children' }}
+                allowClear={true}
+                value={
+                  formData[item.key as 'num']
+                    ? (formData[item.key as 'num'] as string).split(',')
+                    : []
+                }
+                onChange={e => setFormData({ ...formData, [item.key]: e ? e.join(',') : '' })}
+              />
+            )}
+          </div>
+        )
+      })
+    },
+    [formData, txtChangeFu]
+  )
+
+  // 点击搜索的 时间戳
+  const [timeKey, setTimeKey] = useState(0)
+  // 点击搜索
+  const clickSearch = useCallback(() => {
+    setFormData({ ...formData, pageNum: 1 })
+    setTimeout(() => {
+      setTimeKey(Date.now())
+    }, 50)
+  }, [formData])
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setFormData({ ...DEFAULT_D3STAFF_PARAMS })
+    setTimeout(() => {
+      setTimeKey(Date.now())
+    }, 50)
+  }, [])
+
+  // 页码变化
+  const paginationChange = useCallback(
+    (pageNum: number, pageSize: number) => {
+      setFormData({ ...formData, pageNum, pageSize })
+      setTimeout(() => {
+        setTimeKey(Date.now())
+      }, 50)
+    },
+    [formData]
+  )
+
+  // 封装发送请求的函数
+  const getListFu = useCallback(() => {
+    const { date, ...rest } = formDataRef.current
+    if (Array.isArray(date) && date.length) {
+      // @ts-ignore
+      rest.startTime = date[0]
+      // @ts-ignore
+      rest.endTime = date[1]
+    }
+    formDataOldRef.current = rest
+    dispatch(D3_APIList(filterEmptyStrings(rest)))
+  }, [dispatch])
+
+  // 点击操作按钮
+  const tableBtnFu = useCallback((id: any, key: string) => {
+    history.push(`/wealth_edit/${key}/${id}`)
+  }, [])
+
+  // 点击删除
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res = await C21_APIdel(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功')
+        getListFu()
+      }
+    },
+    [getListFu]
+  )
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: any) => {
+          let obj = btnFlagFu(item)
+          return !Object.values(obj).some(Boolean) ? (
+            '-'
+          ) : (
+            <>
+              {obj['编辑'] ? (
+                <Button size='small' type='text' onClick={() => tableBtnFu(item.id, '2')}>
+                  编辑
+                </Button>
+              ) : null}
+
+              {obj['审批'] ? (
+                <Button size='small' type='text' onClick={() => tableBtnFu(item.id, '3')}>
+                  审批
+                </Button>
+              ) : null}
+              {obj['查看'] ? (
+                <Button size='small' type='text' onClick={() => tableBtnFu(item.id, '4')}>
+                  查看
+                </Button>
+              ) : null}
+
+              {obj['删除'] ? (
+                <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+              ) : null}
+            </>
+          )
+        }
+      }
+    ]
+  }, [delTableFu, tableBtnFu])
+
+  // 点击导出
+  const deriveFu = useCallback(async () => {
+    const name = '人员出入库' + dayjs(new Date()).format('YYYY-MM-DD HH:mm')
+
+    const res = await D3_APIList(
+      {
+        ...formDataOldRef.current,
+        pageNum: 1,
+        pageSize: 99999
+      },
+      true
+    )
+
+    if (res.code === 0) {
+      if (res.data.records.length <= 0) return MessageFu.warning('当前搜索条件没有数据!')
+
+      const option = {
+        fileName: name,
+        datas: [
+          {
+            sheetData: res.data.records.map((v: ID3StaffItem) => ({
+              ...v,
+              status: statusObj[v.status as 1]
+            })),
+            sheetName: name,
+            sheetFilter: ['num', 'dateStart', 'authUnit', 'creatorName', 'createTime', 'status'],
+            sheetHeader: ['申请编号', '交修日期', '交修部门', '发起人', '发送日期', '申请状态'],
+            columnWidths: [10, 10, 10, 10, 10, 10]
+          }
+        ]
+      }
+
+      const toExcel = new ExportJsonExcel(option) //new
+      toExcel.saveExcel() //保存
+    }
+  }, [])
+
+  useEffect(() => {
+    getListFu()
+  }, [getListFu, timeKey])
+
+  useEffect(() => {
+    formDataRef.current = formData
+  }, [formData])
+
   return (
     <div className={styles.D3staff}>
-      <div className='pageTitle'>人员出入</div>
-      <p>待开发</p>
+      <div className='pageTitle'>资源使用</div>
+
+      {/* 第一行 */}
+      <div className='C1top'>
+        <div className='C1topll C1topllAll'>{searchDom(D3STAFF_PARAM_ROWS)}</div>
+      </div>
+
+      {/* 第二行 */}
+      <div className='C1top'>
+        <div className='C1topll C1topllAll'>{searchDom(D3STAFF_PARAM_ROWS2)}</div>
+      </div>
+
+      {/* 第二行 */}
+      <div className='C1top C1top2'>
+        <Button type='primary' onClick={deriveFu}>
+          批量导出
+        </Button>
+        &emsp;
+        <Button type='primary' onClick={() => history.push('/staff_edit/1/null')}>
+          新增
+        </Button>
+        &emsp;
+        <Button type='primary' onClick={clickSearch}>
+          查询
+        </Button>
+        &emsp;
+        <Button onClick={resetSelectFu}>重置</Button>
+      </div>
+
+      {/* 表格 */}
+      <MyTable
+        yHeight={580}
+        list={tableInfo.list}
+        columnsTemp={D3STAFF_TABLE_COLUMNS}
+        lastBtn={tableLastBtn}
+        pageNum={formData.pageNum}
+        pageSize={formData.pageSize}
+        total={tableInfo.total}
+        onChange={(pageNum, pageSize) => paginationChange(pageNum, pageSize)}
+      />
     </div>
   )
 }

+ 32 - 0
src/pages/D_storeManage/D3staff/types.ts

@@ -0,0 +1,32 @@
+import { FourTableType } from '@/pages/B_enterTibet/B1collect/type'
+
+export interface ID3StaffItem extends FourTableType {
+  id: number
+  num: string
+}
+
+export type D3StaffSearchType = {
+  name: string
+  key: keyof ID3StaffParams
+  type: '输入框' | '下拉框' | '级联' | '日期选择'
+  data?: any[]
+}
+
+export interface ID3StaffParams {
+  pageSize: number
+  pageNum: number
+  num: string
+  inDate?: string[]
+  date?: string[]
+  userType: string
+  status: string
+  userName: string
+  deptName: string
+}
+
+export type D3StaffOversiderType = {
+  name: string
+  phone: string
+  papers: string
+  remark: string
+}

+ 143 - 0
src/pages/D_storeManage/D7check/D7edit/index.module.scss

@@ -0,0 +1,143 @@
+.D3staff {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 15px 24px 0px;
+  :global {
+    .D4Tit {
+      font-size: 18px;
+      font-weight: 700;
+      padding-bottom: 10px;
+      padding-left: 18px;
+      border-bottom: 1px solid #ccc;
+      margin-bottom: 17px;
+      color: var(--themeColor);
+      .ant-btn {
+        margin-left: 15px;
+        pointer-events: none;
+      }
+    }
+    .D4main {
+      width: 100%;
+      height: calc(100% - 70px);
+      overflow-y: auto;
+      padding-bottom: 40px;
+
+      .D4rowAll {
+        display: flex;
+        justify-content: space-between;
+        align-items: self-start;
+        font-size: 16px;
+        flex-wrap: wrap;
+        .D4row {
+          width: 48%;
+          display: flex;
+          align-items: center;
+          margin-bottom: 20px;
+          .D4rowll {
+            width: 120px;
+            text-align: right;
+            font-weight: 700;
+            & > span {
+              color: #ff4d4f;
+            }
+          }
+          .D4rowrr {
+            width: calc(100% - 120px);
+            .ant-input-affix-wrapper {
+              width: 300px;
+            }
+            .ant-select {
+              width: 300px;
+            }
+          }
+        }
+        .D4row2 {
+          align-items: self-start;
+          .D4rowll {
+            position: relative;
+            top: 3px;
+          }
+        }
+        .D4row3 {
+          position: relative;
+          top: 4px;
+        }
+
+        .D4rowFull {
+          width: 100%;
+          margin-top: -20px;
+          align-items: self-start;
+          margin-bottom: 0;
+          .D4rowll {
+            position: relative;
+            top: 3px;
+          }
+        }
+      }
+      // 藏品清单
+      .D4googsBox {
+        padding-right: 20px;
+        .D1GtNum {
+          cursor: pointer;
+          text-decoration: underline;
+          // &:hover {
+          //   color: var(--themeColor);
+          // }
+        }
+
+        .D1GtNumAc {
+          color: var(--themeColor);
+        }
+      }
+      .D4Tit2 {
+        margin-top: 24px;
+        display: flex;
+        justify-content: space-between;
+        padding-bottom: 10px;
+        border-bottom: 1px solid #ccc;
+        margin-bottom: 20px;
+        .D4Tit2ll {
+          font-size: 18px;
+          font-weight: 700;
+          padding-left: 18px;
+          margin-bottom: 17px;
+          color: var(--themeColor);
+        }
+        .D4Tit2rr {
+          position: relative;
+          z-index: 2;
+          .ant-btn {
+            margin-left: 15px;
+          }
+        }
+      }
+    }
+
+    .D4btn {
+      position: absolute;
+      bottom: 20px;
+      left: 134px;
+      .ant-btn {
+        margin-right: 20px;
+      }
+    }
+  }
+}
+
+.tabRow {
+  margin-bottom: 15px;
+  display: flex;
+  justify-content: space-between;
+}
+
+.D6editMo {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+    .D6editMoBtn {
+      margin-top: 40px;
+      text-align: center;
+    }
+  }
+}

+ 581 - 0
src/pages/D_storeManage/D7check/D7edit/index.tsx

@@ -0,0 +1,581 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { useParams } from 'react-router-dom'
+import { Button, DatePicker, Input, Modal, Select } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import history, { btnFlagFu2 } from '@/utils/history'
+import { MessageFu } from '@/utils/message'
+import { statusObj } from '@/utils/tableData'
+import X3auditInfo from '@/pages/X_stock/X3auditInfo'
+import ZflowTable from '@/components/ZflowTable'
+import MyTable, { MyTableMethods } from '@/components/MyTable'
+import { EXbtnFu } from '@/utils/EXBtn'
+import {
+  D7_APIcreate,
+  D7_APIdel,
+  D7_APIgetInfo,
+  D7_APIsaveApply,
+  D7_APIsaveAudit,
+  D7_APIsaveCreate,
+  D7_APIsaveDraft
+} from '@/store/action/D7check'
+import { ID7CheckItem } from '../types'
+import { useDispatch, useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import { D2_APIgetList } from '@/store/action/D2storSet'
+import { StocktakingModal } from '../components/StocktakingModal'
+import { D7CHECK_COLLECTION_COLUMNS } from '../constants'
+import dayjs from 'dayjs'
+import { areAllCheckersFilled } from '@/utils/objects'
+import { C1GoodType } from '@/pages/A3_ledger/C1ledger/type'
+import { BatchFillingModal } from '../components/BatchFillingModal'
+
+export const pageTitTxtObj = {
+  1: '新增',
+  2: '编辑',
+  3: '审批',
+  4: '查看'
+}
+
+function D7edit() {
+  const { key, id } = useParams<any>()
+  // key:1 新增 2编辑 3审批 4查看
+
+  // 滚到顶部
+  const sollrDom = useRef<HTMLDivElement>(null)
+  // 顶部数据
+  const [topInfo, setTopInfo] = useState({} as ID7CheckItem)
+  const { list: storageIdArr } = useSelector((state: RootState) => state.D2storSet.tableInfo)
+  const [stocktakingVisible, setStocktakingVisible] = useState(false)
+  const [batchFillingVisible, setBatchFillingVisible] = useState(false)
+  const [collectionList, setCollectionList] = useState<C1GoodType[]>([])
+  const tableRef = useRef<MyTableMethods | null>(null)
+  const delSnapIdsRef = useRef<number[]>([])
+  // 变更分库缩写 清空 藏品清单
+  const [isModalOpen, setIsModalOpen] = useState(0)
+
+  const dispatch = useDispatch()
+
+  useEffect(() => {
+    dispatch(D2_APIgetList({ pageNum: 1, pageSize: 99999 }))
+  }, [dispatch])
+
+  // 创建订单
+  const creatFu = useCallback(async () => {
+    const res = await D7_APIcreate()
+    if (res.code === 0) {
+      setTopInfo({
+        ...res.data,
+        date: dayjs().format('YYYY-MM-DD')
+      })
+    }
+  }, [])
+
+  // 获取详情
+  const getInfoFu = useCallback(
+    async (iid = id) => {
+      const res = await D7_APIgetInfo(iid)
+      if (res.code === 0) {
+        const data = res.data
+        setTopInfo(data)
+        // 藏品清单快照信息id对比
+        const arrTemp: any = []
+        const snapsTemp = data.snaps || []
+
+        snapsTemp.forEach((v: any) => {
+          const { cusForm, ...obj } = JSON.parse(v.snap || '{}')
+          if (obj.id) obj.id2 = v.id
+          if (cusForm) tableRef.current?.form.setFieldsValue(cusForm)
+
+          arrTemp.push(obj)
+        })
+        setCollectionList(arrTemp)
+      }
+    },
+    [id]
+  )
+
+  useEffect(() => {
+    if (key === '1') creatFu()
+    else getInfoFu()
+
+    if (sollrDom.current) sollrDom.current.scrollTop = 0
+  }, [creatFu, getInfoFu, key])
+
+  // 富文本的ref
+  const ZRichTextRef = useRef<any>(null)
+
+  // 审批意见的ref
+  const ZAuditRef = useRef<any>(null)
+
+  const pageTitTxt = useMemo(() => {
+    return Reflect.get(pageTitTxtObj, key)
+  }, [key])
+
+  const checkDataFu = useCallback(() => {
+    if (!topInfo.date) {
+      MessageFu.warning('请选择盘点日期')
+      return true
+    }
+    if (!topInfo.num) {
+      MessageFu.warning('请填写盘点单编号')
+      return true
+    }
+    if (!topInfo.storageId) {
+      MessageFu.warning('请选择分库')
+      return true
+    }
+    if (!topInfo.reason) {
+      MessageFu.warning('请填写盘点事由')
+      return true
+    }
+    if (!collectionList.length) {
+      MessageFu.warning('请添加盘点范围')
+      return true
+    }
+
+    const tableInputVals = tableRef.current?.form.getFieldsValue()
+    if (!areAllCheckersFilled('checker', tableInputVals)) {
+      MessageFu.warning(`请填写盘点人`)
+      return true
+    }
+
+    return false
+  }, [topInfo, collectionList])
+
+  // 审批的sta
+  const [auditSta, setAuDitSta] = useState('')
+
+  // 新增的底部按钮点击
+  const btnClickFu = useCallback(
+    async (val: '草稿' | '创建' | '保存' | '审批') => {
+      if (checkDataFu()) return
+
+      if (val === '审批') {
+        // console.log('审批信息富文本', rtf2)
+        if (!auditSta) {
+          if (sollrDom.current) sollrDom.current.scrollTop = 0
+          return MessageFu.warning('请选择审批结果')
+        }
+        const rtf2 = ZAuditRef.current?.resData()
+
+        const res = await D7_APIsaveAudit({
+          orderId: topInfo.id,
+          rtfOpinion: rtf2,
+          status: auditSta === '同意' ? 1 : 2
+        })
+
+        if (res.code === 0) {
+          MessageFu.success('审批成功')
+          // 跳详情页
+          history.push(`/check_edit/4/${topInfo.id}`)
+        }
+      } else {
+        const tableValues = tableRef.current?.form.getFieldsValue()
+        const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
+        // console.log('申请信息富文本', JSON.stringify(rtf1.val || ''))
+
+        const obj = {
+          ...topInfo,
+          goodsIds: collectionList.map(v => v.id).join(','),
+          delSnapIds: delSnapIdsRef.current.length ? delSnapIdsRef.current : '',
+          snaps: collectionList.map(i => ({
+            goodsId: i.id,
+            id: i.id2 ? i.id2 : null,
+            orderId: topInfo.id,
+            statusCheck: tableValues[`${i.id}-statusCheck`],
+            snap: JSON.stringify({
+              ...i,
+              cusForm: tableValues
+            })
+          })),
+          rtf: JSON.stringify(rtf1.val || '')
+        }
+        // console.log(123, obj)
+
+        // if (1 + 1 === 2) return
+
+        if (val === '草稿') {
+          // 存草稿 当前页保存 不跳转
+          const res = await D7_APIsaveDraft(obj)
+          if (res.code === 0) {
+            MessageFu.success('草稿保存成功')
+            getInfoFu(topInfo.id)
+          }
+        } else {
+          const res = val === '创建' ? await D7_APIsaveCreate(obj) : await D7_APIsaveApply(obj)
+          if (res.code === 0) {
+            MessageFu.success(`${val}成功`)
+            // 跳到详情页
+            history.push(`/check_edit/4/${topInfo.id}`)
+          }
+        }
+      }
+    },
+    [auditSta, checkDataFu, topInfo, collectionList, getInfoFu]
+  )
+
+  // 查看的按钮创建-提交-撤回
+  const lookBtnFu = useCallback(
+    async (val: '创建' | '提交') => {
+      const tableValues = tableRef.current?.form.getFieldsValue()
+      const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
+      // console.log('申请信息富文本', JSON.stringify(rtf1.val || ''))
+
+      const obj = {
+        ...topInfo,
+        goodsIds: collectionList.map(v => v.id).join(','),
+        delSnapIds: delSnapIdsRef.current.length ? delSnapIdsRef.current : '',
+        snaps: collectionList.map(i => ({
+          goodsId: i.id,
+          id: i.id2 ? i.id2 : null,
+          orderId: topInfo.id,
+          statusCheck: tableValues[`${i.id}-statusCheck`],
+          snap: JSON.stringify({
+            ...i,
+            cusForm: tableValues
+          })
+        })),
+        rtf: JSON.stringify(rtf1.val || '')
+      }
+
+      const res = val === '创建' ? await D7_APIsaveCreate(obj) : await D7_APIsaveApply(obj)
+
+      if (res.code === 0) {
+        if (sollrDom.current) sollrDom.current.scrollTop = 0
+        MessageFu.success(val + '成功')
+        getInfoFu()
+      }
+    },
+    [getInfoFu, topInfo, collectionList]
+  )
+
+  // 查看模式点击删除
+  const delFu = useCallback(async () => {
+    const res = await D7_APIdel(id)
+    if (res.code === 0) {
+      MessageFu.success('删除成功')
+      history.push('/check')
+    }
+  }, [id])
+
+  // 查看模式点击审批 编辑
+  const lookJumpFu = useCallback(
+    (val: '审批' | '编辑') => {
+      history.push(`/check_edit/${val === '审批' ? 3 : 2}/${id}`)
+      MessageFu.success(`已跳转至${val}页面`)
+    },
+    [id]
+  )
+
+  // 查看模式下的按钮
+  const lookBtn = useMemo(() => {
+    return (
+      <>
+        {btnFlagFu2(topInfo)['创建'] ? (
+          <Button type='primary' onClick={() => lookBtnFu('创建')}>
+            创建
+          </Button>
+        ) : null}
+        {btnFlagFu2(topInfo)['提交'] ? (
+          <Button type='primary' onClick={() => lookBtnFu('提交')}>
+            提交
+          </Button>
+        ) : null}
+
+        {btnFlagFu2(topInfo)['审批'] ? (
+          <Button type='primary' onClick={() => lookJumpFu('审批')}>
+            审批
+          </Button>
+        ) : null}
+        {btnFlagFu2(topInfo)['编辑'] ? (
+          <Button type='primary' onClick={() => lookJumpFu('编辑')}>
+            编辑
+          </Button>
+        ) : null}
+
+        {btnFlagFu2(topInfo)['重新提交'] ? (
+          <Button type='primary' onClick={() => lookBtnFu('提交')}>
+            重新提交
+          </Button>
+        ) : null}
+
+        {EXbtnFu(topInfo)}
+
+        {btnFlagFu2(topInfo)['删除'] ? (
+          <MyPopconfirm
+            txtK='删除'
+            onConfirm={() => delFu()}
+            Dom={
+              <Button type='primary' danger>
+                删除
+              </Button>
+            }
+          />
+        ) : null}
+
+        <Button onClick={() => history.push('/check')}>返回</Button>
+      </>
+    )
+  }, [delFu, lookBtnFu, lookJumpFu, topInfo])
+
+  // 申请记录
+  const [auditsShow, setAuditsShow] = useState(false)
+
+  const handleStocktakingOk = (list: any[]) => {
+    delSnapIdsRef.current.push(...collectionList.map(i => i.id2))
+    setCollectionList(list)
+  }
+
+  const handleBatchFillingOk = (form: any) => {
+    const temp: Record<string, string> = {}
+    collectionList.forEach(item => {
+      temp[`${item.id}-checker`] = form.checker
+      temp[`${item.id}-remark`] = form.remark
+    })
+    tableRef.current?.form.setFieldsValue(temp)
+  }
+
+  return (
+    <div className={styles.D3staff}>
+      <div className='pageTitle'>藏品盘点-{pageTitTxt}</div>
+
+      <div className='D4main' ref={sollrDom}>
+        {['3'].includes(key) ? (
+          <X3auditInfo
+            dirCode='D7check'
+            myUrl='cms/orderIn/upload'
+            auditSta={auditSta}
+            auditStaFu={val => setAuDitSta(val)}
+            ref={ZAuditRef}
+          />
+        ) : null}
+
+        {/* 表单字段、附件等 */}
+        <div className='D4Tit'>
+          申请信息
+          {key === '1' ? null : (
+            <Button type='dashed'>{Reflect.get(statusObj, topInfo.status)}</Button>
+          )}
+        </div>
+        <div className='D4rowAll'>
+          <div className='D4row'>
+            <div className='D4rowll'>
+              <span>*</span>盘点日期:
+            </div>
+            <div className='D4rowrr'>
+              {topInfo.id && (
+                <DatePicker
+                  defaultValue={dayjs(topInfo.date)}
+                  style={{ width: '300px' }}
+                  onChange={e => {
+                    setTopInfo({ ...topInfo, date: e.format('YYYY-MM-DD') })
+                  }}
+                />
+              )}
+            </div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>
+              <span>*</span>盘点单编号:
+            </div>
+            <div className='D4rowrr'>
+              <Input
+                value={topInfo.num}
+                onChange={e => setTopInfo({ ...topInfo, num: e.target.value })}
+                readOnly={['3', '4'].includes(key)}
+                placeholder='请输入内容'
+                maxLength={30}
+                showCount
+              />
+            </div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>
+              <span>*</span>分库缩写:
+            </div>
+            <div className='D4rowrr'>
+              <Select
+                disabled={['3', '4'].includes(key)}
+                placeholder='请搜索选择'
+                showSearch
+                filterOption={(input, option) => {
+                  const txt = option!.label
+
+                  return txt.toLowerCase().includes(input.toLowerCase())
+                }}
+                options={storageIdArr.map(v => ({ label: v.num + ' - ' + v.name, value: v.id }))}
+                // fieldNames={{ label: 'num', value: 'num' }}
+                allowClear={false}
+                value={topInfo.storageId || null}
+                onChange={e => {
+                  if (topInfo.storageId && topInfo.storageId !== e && collectionList.length) {
+                    setIsModalOpen(e)
+                  } else setTopInfo({ ...topInfo, storageId: e ? e : null })
+                }}
+              />
+            </div>
+          </div>
+
+          <div className='D4row'>
+            <div className='D4rowll'>
+              <span>*</span>盘点事由:
+            </div>
+            <div className='D4rowrr'>
+              <Input
+                value={topInfo.reason}
+                onChange={e => setTopInfo({ ...topInfo, reason: e.target.value })}
+                readOnly={['3', '4'].includes(key)}
+                placeholder='请输入内容'
+                maxLength={200}
+                showCount
+              />
+            </div>
+          </div>
+        </div>
+
+        {/* 盘点范围 */}
+        <div className='D4googsBox'>
+          <div className='D4Tit2'>
+            <div className='D4Tit2ll'>盘点范围</div>
+            {!['3', '4'].includes(key) && (
+              <div>
+                <Button
+                  type='primary'
+                  disabled={!collectionList.length}
+                  style={{ marginRight: 15 }}
+                  onClick={() => setBatchFillingVisible(true)}
+                >
+                  批量填写
+                </Button>
+                <Button
+                  disabled={!topInfo.storageId}
+                  type='primary'
+                  onClick={() => setStocktakingVisible(true)}
+                >
+                  设置盘点范围
+                </Button>
+              </div>
+            )}
+          </div>
+
+          <MyTable
+            ref={tableRef}
+            readOnly={['3', '4'].includes(key)}
+            widthSet={{ statusCheck: 200, remark: 200 }}
+            yHeight={350}
+            list={collectionList}
+            columnsTemp={D7CHECK_COLLECTION_COLUMNS}
+            lastBtn={
+              ['3', '4'].includes(key)
+                ? undefined
+                : [
+                    {
+                      title: '操作',
+                      render(item: C1GoodType, _: any, idx: number) {
+                        return (
+                          <MyPopconfirm
+                            txtK='删除'
+                            onConfirm={() => {
+                              if (item.id2 && !delSnapIdsRef.current.includes(item.id2))
+                                delSnapIdsRef.current.push(item.id2)
+                              const temp = [...collectionList]
+                              temp.splice(idx, 1)
+                              setCollectionList(temp)
+                            }}
+                          />
+                        )
+                      }
+                    }
+                  ]
+            }
+          />
+        </div>
+
+        {/* 申请流程 */}
+        {auditsShow ? (
+          <ZflowTable tableArr={topInfo.audits || []} closeFu={() => setAuditsShow(false)} />
+        ) : null}
+      </div>
+
+      {/* 底部按钮 */}
+      <div className='D4btn'>
+        {['3', '4'].includes(key) && topInfo.audits && topInfo.audits.length ? (
+          <Button type='primary' onClick={() => setAuditsShow(true)}>
+            申请记录
+          </Button>
+        ) : null}
+
+        {key === '4' ? (
+          lookBtn
+        ) : (
+          <>
+            {key === '3' ? (
+              <Button type='primary' onClick={() => btnClickFu('审批')}>
+                审批
+              </Button>
+            ) : (
+              <Button type='primary' onClick={() => btnClickFu(key === '1' ? '创建' : '保存')}>
+                {key === '1' ? '创建' : '保存'}
+              </Button>
+            )}
+
+            {key === '1' ? (
+              <Button type='primary' onClick={() => btnClickFu('草稿')}>
+                存草稿
+              </Button>
+            ) : null}
+
+            <MyPopconfirm txtK='取消' onConfirm={() => history.push('/check')} />
+          </>
+        )}
+      </div>
+
+      {/* 分库缩写改变的时候校验一下 */}
+      <Modal
+        wrapClassName={styles.D6editMo}
+        title='变更分库后,将清空当前的藏品清单'
+        open={!!isModalOpen}
+        footer={[]}
+      >
+        <div className='D6editMoBtn'>
+          <Button
+            type='primary'
+            onClick={() => {
+              setTopInfo({ ...topInfo, storageId: isModalOpen })
+
+              collectionList.forEach(v => {
+                if (!delSnapIdsRef.current.includes(v.id)) delSnapIdsRef.current.push(v.id)
+              })
+              setCollectionList([])
+              setIsModalOpen(0)
+            }}
+          >
+            继续
+          </Button>
+          &emsp;
+          <Button onClick={() => setIsModalOpen(0)}>取消</Button>
+        </div>
+      </Modal>
+
+      <BatchFillingModal
+        visible={batchFillingVisible}
+        setVisible={setBatchFillingVisible}
+        onOk={handleBatchFillingOk}
+      />
+
+      <StocktakingModal
+        storageId={topInfo.storageId}
+        visible={stocktakingVisible}
+        setVisible={setStocktakingVisible}
+        onOk={handleStocktakingOk}
+      />
+    </div>
+  )
+}
+
+const MemoD7edit = React.memo(D7edit)
+
+export default MemoD7edit

+ 43 - 0
src/pages/D_storeManage/D7check/components/BatchFillingModal/index.tsx

@@ -0,0 +1,43 @@
+import { Form, Input, Modal } from 'antd'
+import { FC } from 'react'
+
+export interface BatchFillingModalProps {
+  visible: boolean
+  setVisible: (v: boolean) => void
+  onOk: (form: any) => void
+}
+
+export const BatchFillingModal: FC<BatchFillingModalProps> = ({ visible, setVisible, onOk }) => {
+  const [form] = Form.useForm()
+
+  const handleCancel = () => {
+    setVisible(false)
+  }
+
+  const handleSubmit = async () => {
+    if (!(await form.validateFields())) return
+    onOk(form.getFieldsValue())
+    setVisible(false)
+    form.resetFields()
+  }
+
+  return (
+    <Modal
+      title='批量填写'
+      width={700}
+      maskClosable={false}
+      open={visible}
+      onCancel={handleCancel}
+      onOk={handleSubmit}
+    >
+      <Form form={form} labelCol={{ span: 3 }}>
+        <Form.Item name='checker' label='盘点人' rules={[{ required: true }]}>
+          <Input placeholder='请填写' maxLength={20} />
+        </Form.Item>
+        <Form.Item name='remark' label='备注'>
+          <Input placeholder='请填写' maxLength={20} />
+        </Form.Item>
+      </Form>
+    </Modal>
+  )
+}

+ 152 - 0
src/pages/D_storeManage/D7check/components/StocktakingModal/index.tsx

@@ -0,0 +1,152 @@
+import MyPopconfirm from '@/components/MyPopconfirm'
+import MyTable from '@/components/MyTable'
+import { D7_APIGoodList } from '@/store/action/D7check'
+import { MessageFu } from '@/utils/message'
+import { InputNumber, Modal, Radio } from 'antd'
+import { FC, useCallback, useEffect, useState } from 'react'
+
+export interface StocktakingModalProps {
+  visible: boolean
+  storageId: number | null
+  setVisible: (v: boolean) => void
+  onOk: (list: any[]) => void
+}
+
+export enum STOCKTAKING_TYPES {
+  ALL = 1,
+  NUM = 2,
+  CHECK = 3
+}
+
+export const StocktakingModal: FC<StocktakingModalProps> = ({
+  visible,
+  storageId,
+  setVisible,
+  onOk
+}) => {
+  const [curIndex, setCurIndex] = useState(STOCKTAKING_TYPES.ALL)
+  const [min, setMin] = useState<number | null>(null)
+  const [max, setMax] = useState<number | null>(null)
+  const [list, setList] = useState<any[]>([])
+  const [loading, setLoading] = useState(false)
+  const [confirmLoading, setConfirmLoading] = useState(false)
+  const [checkedList, setCheckedList] = useState<any[]>([])
+
+  const getList = useCallback(
+    async (params?: any) => {
+      if (!storageId) return
+
+      try {
+        Boolean(params) ? setConfirmLoading(true) : setLoading(true)
+        const res = await D7_APIGoodList({
+          storageId,
+          type: curIndex,
+          ...(params || {})
+        })
+        setList(res.data)
+        return res.data
+      } finally {
+        Boolean(params) ? setConfirmLoading(false) : setLoading(false)
+      }
+    },
+    [storageId, curIndex]
+  )
+
+  const handleCancel = () => {
+    setVisible(false)
+  }
+
+  const handleSubmit = async () => {
+    let stack: any[] = list
+
+    switch (curIndex) {
+      case STOCKTAKING_TYPES.NUM:
+        if (!min || !max) {
+          MessageFu.warning('请填写最小值和最大值')
+          return
+        }
+        stack = await getList({
+          min,
+          max
+        })
+        break
+      case STOCKTAKING_TYPES.CHECK:
+        stack = checkedList
+        break
+    }
+    onOk(stack)
+    setVisible(false)
+  }
+
+  useEffect(() => {
+    if (visible) getList()
+  }, [visible, getList])
+
+  return (
+    <Modal
+      title='设置盘点范围'
+      width={700}
+      maskClosable={false}
+      open={visible}
+      okButtonProps={{
+        disabled: loading
+      }}
+      confirmLoading={confirmLoading}
+      onCancel={handleCancel}
+      onOk={handleSubmit}
+    >
+      <Radio.Group
+        value={curIndex}
+        options={[
+          { value: STOCKTAKING_TYPES.ALL, label: '该库房所有藏品' },
+          { value: STOCKTAKING_TYPES.NUM, label: '按藏品分库号' },
+          { value: STOCKTAKING_TYPES.CHECK, label: '按所选藏品' }
+        ]}
+        style={{ marginBottom: 15 }}
+        onChange={e => setCurIndex(e.target.value)}
+      />
+
+      {curIndex === STOCKTAKING_TYPES.NUM && (
+        <div style={{ display: 'flex', marginBottom: 15 }}>
+          <InputNumber
+            value={min}
+            precision={0}
+            placeholder='请填写最小值'
+            min={0}
+            style={{ flex: 1 }}
+            onChange={setMin}
+          />
+          <span style={{ padding: '0 10px' }}>-</span>
+          <InputNumber
+            precision={0}
+            value={max}
+            min={min || 0}
+            style={{ flex: 1 }}
+            placeholder='请填写最大值'
+            onChange={setMax}
+          />
+        </div>
+      )}
+
+      {curIndex === STOCKTAKING_TYPES.CHECK && (
+        <MyTable
+          rowSelection={{
+            type: 'checkbox',
+            onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
+              setCheckedList(selectedRows)
+            }
+          }}
+          columnsTemp={[
+            ['txt', '库位号', 'siteNum'],
+            ['txt', '编号类型', 'numName'],
+            ['txt', '藏品编号', 'num'],
+            ['txt', '藏品名称', 'name'],
+            ['ping', '数量', 'pcs', 'pcsUnit'],
+            ['txt', '库存状态', 'statusStorage']
+          ]}
+          list={list}
+        />
+      )}
+    </Modal>
+  )
+}

+ 116 - 0
src/pages/D_storeManage/D7check/constants.tsx

@@ -0,0 +1,116 @@
+import { selectObj } from '@/utils/select'
+import { D7CHECK_COLLECTION_RESULT_ENUM, D7CheckSearchType, ID7CheckParams } from './types'
+import { statusObj, statusStorageObj } from '@/utils/tableData'
+import { Radio } from 'antd'
+
+export const DEFAULT_D7CHECK_PARAMS: ID7CheckParams = {
+  pageNum: 1,
+  pageSize: 10,
+  num: '',
+  userType: '',
+  deptName: '',
+  userName: '',
+  status: ''
+}
+
+export const D7CHECK_PARAM_ROWS: D7CheckSearchType[] = [
+  { name: '移库日期范围', key: 'date2', type: '日期选择' },
+  { name: '移库单编号', key: 'num', type: '输入框' },
+  { name: '发起部门', key: 'deptName', type: '输入框' },
+  { name: '发起人', key: 'userName', type: '输入框' },
+  { name: '发起日期范围', key: 'date', type: '日期选择' },
+  { name: '申请状态', key: 'status', type: '下拉框', data: selectObj['流程申请状态'] },
+  { name: '选择角色', key: 'userType', type: '下拉框', data: selectObj['角色'] }
+]
+
+export const D7CHECK_TABLE_COLUMNS = [
+  ['txt', '移库日期', 'date'],
+  ['txt', '移库单编号', 'num'],
+  ['txt', '分库缩写', 'sonNum'],
+  ['txt', '发起部门', 'deptName'],
+  ['txt', '发起人', 'creatorName'],
+  ['txt', '发起日期', 'createTime'],
+  ['txtChange', '申请状态', 'status', statusObj]
+]
+
+export const D7CHECK_COLUMNS = [
+  ['img', '封面图', 'thumb'],
+  ['txt', '编号类型', 'numName'],
+  ['txt', '藏品编号', 'goodsNum'],
+  ['txt', '藏品名称', 'goodsName'],
+  ['ping', '数量', 'pcs', 'pcsUnit'],
+  ['txtChange', '库存状态', 'statusStorage', statusStorageObj],
+  [
+    'input',
+    '放置位置',
+    'address',
+    {
+      maxLength: 20,
+      placeholder: '请填写内容,不超过20字'
+    }
+  ],
+  ['datePicker', '借出日期 *', 'startDate'],
+  ['datePicker', '预计归还日期 *', 'endDate']
+]
+
+export const D7CEHCK_COLLECTION_RESULT_OPTIONS = [
+  {
+    label: '待盘点',
+    value: D7CHECK_COLLECTION_RESULT_ENUM.PENDING
+  },
+  {
+    label: '在库',
+    value: D7CHECK_COLLECTION_RESULT_ENUM.IN
+  },
+  {
+    label: '不在库',
+    value: D7CHECK_COLLECTION_RESULT_ENUM.OUT
+  }
+]
+
+export const D7CHECK_COLLECTION_COLUMNS = [
+  ['txt', '登记号类型', 'numName'],
+  ['txt', '编号', 'num'],
+  ['txt', '藏品分库号', 'siteNum'],
+  ['txt', '名称', 'name'],
+  ['txtC', '年代', 'dictAge'],
+  ['txtC', '质地', 'dictTexture3'],
+  ['ping', '计件数量', 'pcs', 'pcsUnit'],
+  ['txt', '级别', 'dictLevel'],
+  ['txtC', '文物现状', 'dictTorn'],
+  [
+    'input',
+    '* 盘点人',
+    'checker',
+    {
+      maxLength: 20,
+      placeholder: '请填写'
+    }
+  ],
+  [
+    'custom',
+    '盘点结果',
+    'statusCheck',
+    {
+      render(readOnly?: boolean) {
+        return (
+          <Radio.Group
+            optionType='button'
+            size='small'
+            disabled={readOnly}
+            options={D7CEHCK_COLLECTION_RESULT_OPTIONS}
+          />
+        )
+      }
+    }
+  ],
+  [
+    'input',
+    '备注',
+    'remark',
+    {
+      maxLength: 20,
+      placeholder: '请填写'
+    }
+  ]
+]

+ 64 - 0
src/pages/D_storeManage/D7check/index.module.scss

@@ -1,4 +1,68 @@
 .D7check {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 24px 24px 0;
+  position: relative;
   :global {
+    .C1top {
+      display: flex;
+      justify-content: space-between;
+      .C1topll {
+        display: flex;
+        & > div {
+          display: flex;
+          align-items: center;
+          position: relative;
+          &:not(:last-child) {
+            margin-right: 15px;
+          }
+          & > span {
+            position: absolute;
+            top: -18px;
+            left: 0;
+            pointer-events: none;
+          }
+        }
+      }
+
+      .C1toprrSuo {
+        width: 100%;
+        margin-top: 15px;
+        text-align: right;
+      }
+
+      .C1toprrKai {
+        position: relative;
+        top: 10px;
+        width: 310px;
+        height: 84px;
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+      }
+
+      .C1topllAll {
+        width: 100%;
+        & > div {
+          flex: 1;
+          .ant-input {
+            width: 100%;
+          }
+          .ant-select {
+            width: 100%;
+          }
+        }
+      }
+    }
+    .C1top2 {
+      margin: 15px 0;
+      justify-content: flex-end;
+    }
+    .ant-select-selection-placeholder {
+      color: black !important;
+    }
+    .ant-table-cell {
+      padding: 8px !important;
+    }
   }
 }

+ 257 - 2
src/pages/D_storeManage/D7check/index.tsx

@@ -1,10 +1,265 @@
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import styles from './index.module.scss'
+import { Button, Cascader, DatePicker, Input, Select } from 'antd'
+import { useDispatch, useSelector } from 'react-redux'
+import store, { RootState } from '@/store'
+import history, { btnFlagFu } from '@/utils/history'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import MyTable from '@/components/MyTable'
+import { D7CHECK_PARAM_ROWS, D7CHECK_TABLE_COLUMNS, DEFAULT_D7CHECK_PARAMS } from './constants'
+import { D7CheckSearchType, ID7CheckItem, ID7CheckParams } from './types'
+import { D7_APIdel, D7_APIList } from '@/store/action/D7check'
+import { filterEmptyStrings } from '@/utils/objects'
+import { MessageFu } from '@/utils/message'
+import { statusObj } from '@/utils/tableData'
+
+const { RangePicker } = DatePicker
+
 function D7check() {
+  // 从仓库拿数据
+  const tableInfo = useSelector((state: RootState) => state.D7check.tableInfo)
+  const [formData, setFormData] = useState({ ...DEFAULT_D7CHECK_PARAMS })
+  const formDataRef = useRef({ ...DEFAULT_D7CHECK_PARAMS })
+  const formDataOldRef = useRef({ ...DEFAULT_D7CHECK_PARAMS })
+  const dispatch = useDispatch()
+
+  // 输入框的改变
+  const txtChangeFu = useCallback(
+    (txt: string, key: keyof ID7CheckParams) => {
+      setFormData({
+        ...formData,
+        [key]: txt
+      })
+    },
+    [formData]
+  )
+
+  // 顶部筛选
+  const searchDom = useCallback(
+    (arr: D7CheckSearchType[]) => {
+      return arr.map(item => {
+        return (
+          <div key={item.name}>
+            <span>{item.name}:</span>
+            {item.type === '输入框' ? (
+              <Input
+                placeholder='请输入'
+                maxLength={30}
+                value={formData[item.key]}
+                onChange={e => txtChangeFu(e.target.value, item.key)}
+              />
+            ) : item.type === '下拉框' ? (
+              <Select
+                options={item.data}
+                placeholder='全部'
+                allowClear={true}
+                value={formData[item.key as 'num'] ? formData[item.key as 'num'] : null}
+                onChange={e => setFormData({ ...formData, [item.key]: e })}
+              />
+            ) : item.type === '日期选择' ? (
+              <RangePicker
+                format='YYYY-MM-DD'
+                allowClear={true}
+                onChange={(e, dateStrings) => setFormData({ ...formData, [item.key]: dateStrings })}
+              />
+            ) : (
+              <Cascader
+                options={item.data}
+                placeholder='全部'
+                fieldNames={{ label: 'name', value: 'id', children: 'children' }}
+                allowClear={true}
+                value={
+                  formData[item.key as 'num']
+                    ? (formData[item.key as 'num'] as string).split(',')
+                    : []
+                }
+                onChange={e => setFormData({ ...formData, [item.key]: e ? e.join(',') : '' })}
+              />
+            )}
+          </div>
+        )
+      })
+    },
+    [formData, txtChangeFu]
+  )
+
+  // 点击搜索的 时间戳
+  const [timeKey, setTimeKey] = useState(0)
+  // 点击搜索
+  const clickSearch = useCallback(() => {
+    setFormData({ ...formData, pageNum: 1 })
+    setTimeout(() => {
+      setTimeKey(Date.now())
+    }, 50)
+  }, [formData])
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setFormData({ ...DEFAULT_D7CHECK_PARAMS })
+    setTimeout(() => {
+      setTimeKey(Date.now())
+    }, 50)
+  }, [])
+
+  // 页码变化
+  const paginationChange = useCallback(
+    (pageNum: number, pageSize: number) => {
+      setFormData({ ...formData, pageNum, pageSize })
+      setTimeout(() => {
+        setTimeKey(Date.now())
+      }, 50)
+    },
+    [formData]
+  )
+
+  // 封装发送请求的函数
+  const getListFu = useCallback(() => {
+    const { date, ...rest } = formDataRef.current
+    if (Array.isArray(date) && date.length) {
+      // @ts-ignore
+      rest.startTime = date[0]
+      // @ts-ignore
+      rest.endTime = date[1]
+    }
+    formDataOldRef.current = rest
+    dispatch(D7_APIList(filterEmptyStrings(rest)))
+  }, [dispatch])
+
+  // 点击操作按钮
+  const tableBtnFu = useCallback((id: any, key: string) => {
+    history.push(`/check_edit/${key}/${id}`)
+  }, [])
+
+  // 点击删除
+  const delTableFu = useCallback(
+    async (id: any) => {
+      const res = await D7_APIdel(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功')
+        getListFu()
+      }
+    },
+    [getListFu]
+  )
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: any) => {
+          let obj = btnFlagFu(item)
+          return !Object.values(obj).some(Boolean) ? (
+            '-'
+          ) : (
+            <>
+              {obj['编辑'] ? (
+                <Button size='small' type='text' onClick={() => tableBtnFu(item.id, '2')}>
+                  编辑
+                </Button>
+              ) : null}
+
+              {obj['审批'] ? (
+                <Button size='small' type='text' onClick={() => tableBtnFu(item.id, '3')}>
+                  审批
+                </Button>
+              ) : null}
+              {obj['查看'] ? (
+                <Button size='small' type='text' onClick={() => tableBtnFu(item.id, '4')}>
+                  查看
+                </Button>
+              ) : null}
+
+              {obj['删除'] ? (
+                <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+              ) : null}
+            </>
+          )
+        }
+      }
+    ]
+  }, [delTableFu, tableBtnFu])
+
+  // 点击导出
+  const deriveFu = useCallback(async () => {
+    const res = await D7_APIList(
+      {
+        ...formDataOldRef.current,
+        pageNum: 1,
+        pageSize: 99999
+      },
+      true
+    )
+
+    if (res.code === 0) {
+      if (res.data.records.length <= 0) return MessageFu.warning('当前搜索条件没有数据!')
+      store.dispatch({
+        type: 'layout/exInfo',
+        payload: {
+          name: '藏品盘点',
+          show: true,
+          arr: [
+            { key: 'date', txt: '移库日期' },
+            { key: 'num', txt: '移库单编号' },
+            { key: 'sonNum', txt: '分库缩写' },
+            { key: 'deptName', txt: '发起部门' },
+            { key: 'creatorName', txt: '发起人' },
+            { key: 'createTime', txt: '发起日期' },
+            { key: 'status', txt: '申请状态' }
+          ],
+          data: res.data.records.map((v: ID7CheckItem) => ({
+            ...v,
+            status: statusObj[v.status as 1]
+          }))
+        }
+      })
+    }
+  }, [])
+
+  useEffect(() => {
+    getListFu()
+  }, [getListFu, timeKey])
+
+  useEffect(() => {
+    formDataRef.current = formData
+  }, [formData])
+
   return (
     <div className={styles.D7check}>
       <div className='pageTitle'>藏品盘点</div>
-      <p>待开发</p>
+
+      {/* 第一行 */}
+      <div className='C1top'>
+        <div className='C1topll C1topllAll'>{searchDom(D7CHECK_PARAM_ROWS)}</div>
+      </div>
+
+      {/* 第二行 */}
+      <div className='C1top C1top2'>
+        <Button type='primary' onClick={deriveFu}>
+          批量导出
+        </Button>
+        &emsp;
+        <Button type='primary' onClick={() => history.push('/check_edit/1/null')}>
+          新增
+        </Button>
+        &emsp;
+        <Button type='primary' onClick={clickSearch}>
+          查询
+        </Button>
+        &emsp;
+        <Button onClick={resetSelectFu}>重置</Button>
+      </div>
+
+      {/* 表格 */}
+      <MyTable
+        yHeight={580}
+        list={tableInfo.list}
+        columnsTemp={D7CHECK_TABLE_COLUMNS}
+        lastBtn={tableLastBtn}
+        pageNum={formData.pageNum}
+        pageSize={formData.pageSize}
+        total={tableInfo.total}
+        onChange={(pageNum, pageSize) => paginationChange(pageNum, pageSize)}
+      />
     </div>
   )
 }

+ 28 - 0
src/pages/D_storeManage/D7check/types.ts

@@ -0,0 +1,28 @@
+import { FourTableType } from '@/pages/B_enterTibet/B1collect/type'
+
+export interface ID7CheckItem extends FourTableType {}
+
+export type D7CheckSearchType = {
+  name: string
+  key: keyof ID7CheckParams
+  type: '输入框' | '下拉框' | '级联' | '日期选择'
+  data?: any[]
+}
+
+export interface ID7CheckParams {
+  pageSize: number
+  pageNum: number
+  num: string
+  userType: string
+  deptName: string
+  userName: string
+  status: string
+  date?: string[]
+  date2?: string[]
+}
+
+export enum D7CHECK_COLLECTION_RESULT_ENUM {
+  PENDING = 1,
+  IN = 2,
+  OUT = 3
+}

+ 12 - 0
src/pages/Layout/data.ts

@@ -426,5 +426,17 @@ export const routerSon: RouterTypeRow[] = [
     name: '资源使用-新增/编辑/审批/查看',
     path: '/wealth_edit/:key/:id',
     Com: React.lazy(() => import('../C_goodsManage/C21wealth/C21edit'))
+  },
+  {
+    id: 23,
+    name: '人员出入库-新增/编辑/审批/查看',
+    path: '/staff_edit/:key/:id',
+    Com: React.lazy(() => import('../D_storeManage/D3staff/D3edit'))
+  },
+  {
+    id: 24,
+    name: '藏品盘点-新增/编辑/审批/查看',
+    path: '/check_edit/:key/:id',
+    Com: React.lazy(() => import('../D_storeManage/D7check/D7edit'))
   }
 ]

+ 2 - 2
src/store/action/C1ledger.ts

@@ -20,8 +20,8 @@ export const API_goodsInfo = (id: number) => {
 /**
  * 藏品-弹窗-选择藏品
  */
-export const API_goodsNowAdd = (url: string, data: any) => {
-  return http.post(url, data)
+export const API_goodsNowAdd = (url: string, data: any, type: 'get' | 'post' = 'post') => {
+  return http[type](url, data)
 }
 
 /**

+ 69 - 0
src/store/action/D3staff.ts

@@ -0,0 +1,69 @@
+import http from '@/utils/http'
+import { AppDispatch } from '..'
+
+/**
+ * 人员出入库-列表
+ */
+export const D3_APIList = (data: any, exportFlag = false): any => {
+  if (exportFlag) return http.post('/cms/orderMember/page', data)
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post('/cms/orderMember/page', data)
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total
+      }
+
+      dispatch({ type: 'D3/getList', payload: obj })
+    }
+  }
+}
+
+/**
+ * 人员出入库-删除
+ */
+export const D3_APIdel = (id: number) => {
+  return http.get(`cms/orderMember/remove/${id}`)
+}
+
+/**
+ * 人员出入库-获取详情
+ */
+export const D3_APIgetInfo = (id: number) => {
+  return http.get(`cms/orderMember/detail/${id}`)
+}
+
+/**
+ * 人员出入库-创建订单
+ */
+export const D3_APIcreate = () => {
+  return http.get('/cms/orderMember/create')
+}
+
+/**
+ * 人员出入库-存草稿
+ */
+export const D3_APIsaveDraft = (data: any) => {
+  return http.post('cms/orderMember/saveDraft', data)
+}
+
+/**
+ * 人员出入库-创建
+ */
+export const D3_APIsaveCreate = (data: any) => {
+  return http.post('cms/orderMember/saveCreate', data)
+}
+
+/**
+ * 人员出入库-编辑保存
+ */
+export const D3_APIsaveApply = (data: any) => {
+  return http.post('cms/orderMember/saveApply', data)
+}
+
+/**
+ * 人员出入库-审批
+ */
+export const D3_APIsaveAudit = (data: any) => {
+  return http.post('cms/orderMember/audit', data)
+}

+ 73 - 0
src/store/action/D7check.ts

@@ -0,0 +1,73 @@
+import http from '@/utils/http'
+import { AppDispatch } from '..'
+
+/**
+ * 藏品盘点-列表
+ */
+export const D7_APIList = (data: any, exportFlag = false): any => {
+  if (exportFlag) return http.post('/cms/orderCheck/page', data)
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post('/cms/orderCheck/page', data)
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total
+      }
+
+      dispatch({ type: 'D7/getList', payload: obj })
+    }
+  }
+}
+
+export const D7_APIGoodList = (data: any) => {
+  return http.post('/cms/orderCheck/goods/getList', data)
+}
+
+/**
+ * 藏品盘点-删除
+ */
+export const D7_APIdel = (id: number) => {
+  return http.get(`cms/orderCheck/remove/${id}`)
+}
+
+/**
+ * 藏品盘点-获取详情
+ */
+export const D7_APIgetInfo = (id: number) => {
+  return http.get(`cms/orderCheck/detail/${id}`)
+}
+
+/**
+ * 藏品盘点-创建订单
+ */
+export const D7_APIcreate = () => {
+  return http.get('/cms/orderCheck/create')
+}
+
+/**
+ * 藏品盘点-存草稿
+ */
+export const D7_APIsaveDraft = (data: any) => {
+  return http.post('cms/orderCheck/saveDraft', data)
+}
+
+/**
+ * 藏品盘点-创建
+ */
+export const D7_APIsaveCreate = (data: any) => {
+  return http.post('cms/orderCheck/saveCreate', data)
+}
+
+/**
+ * 藏品盘点-编辑保存
+ */
+export const D7_APIsaveApply = (data: any) => {
+  return http.post('cms/orderCheck/saveApply', data)
+}
+
+/**
+ * 藏品盘点-审批
+ */
+export const D7_APIsaveAudit = (data: any) => {
+  return http.post('cms/orderCheck/audit', data)
+}

+ 28 - 0
src/store/reducer/D3staff.ts

@@ -0,0 +1,28 @@
+import { ID3StaffItem } from '@/pages/D_storeManage/D3staff/types'
+
+// 初始化状态
+const initState = {
+  // 列表数据
+  tableInfo: {
+    list: [] as ID3StaffItem[],
+    total: 0
+  }
+}
+
+// 定义 action 类型
+type Props = {
+  type: 'D3/getList'
+  payload: { list: ID3StaffItem[]; total: number }
+}
+
+// reducer
+export default function userReducer(state = initState, action: Props) {
+  switch (action.type) {
+    // 获取列表数据
+    case 'D3/getList':
+      return { ...state, tableInfo: action.payload }
+
+    default:
+      return state
+  }
+}

+ 28 - 0
src/store/reducer/D7check.ts

@@ -0,0 +1,28 @@
+import { ID7CheckItem } from '@/pages/D_storeManage/D7check/types'
+
+// 初始化状态
+const initState = {
+  // 列表数据
+  tableInfo: {
+    list: [] as ID7CheckItem[],
+    total: 0
+  }
+}
+
+// 定义 action 类型
+type Props = {
+  type: 'D7/getList'
+  payload: { list: ID7CheckItem[]; total: number }
+}
+
+// reducer
+export default function userReducer(state = initState, action: Props) {
+  switch (action.type) {
+    // 获取列表数据
+    case 'D7/getList':
+      return { ...state, tableInfo: action.payload }
+
+    default:
+      return state
+  }
+}

+ 5 - 1
src/store/reducer/index.ts

@@ -31,6 +31,8 @@ import A3flow from './A3flow'
 import F1exhibition from './F1exhibition'
 import C21wealth from './C21wealth'
 import A4voucher from './A4voucher'
+import D7check from './D7check'
+import D3staff from './D3staff'
 
 // 合并 reducer
 const rootReducer = combineReducers({
@@ -62,7 +64,9 @@ const rootReducer = combineReducers({
   A3flow,
   F1exhibition,
   C21wealth,
-  A4voucher
+  A4voucher,
+  D7check,
+  D3staff
 })
 
 // 默认导出

+ 9 - 0
src/utils/objects.ts

@@ -3,3 +3,12 @@ import { pickBy } from 'lodash'
 export const filterEmptyStrings = <T extends object>(obj: T): Partial<T> => {
   return pickBy(obj, value => value !== '') as Partial<T>
 }
+
+export const areAllCheckersFilled = (target: string, obj: Record<string, any>) => {
+  return Object.keys(obj)
+    .filter(key => key.endsWith(`-${target}`))
+    .every(key => {
+      const value = obj[key]
+      return value !== undefined && value !== ''
+    })
+}