shaogen1995 1 месяц назад
Родитель
Сommit
9a11910eba

+ 1 - 0
后台管理/src/pages/A0goodsInfo/index.tsx

@@ -50,6 +50,7 @@ function A0goodsInfo() {
             onClick={() => {
               authorityFu(500, '您没有藏品修改页面权限', () => {
                 if (goodsInfo.status === 2) MessageFu.warning('该藏品修改审核中,无法重复修改')
+                else if (goodsInfo.status === 3) MessageFu.warning('该藏品删除审核中,无法修改')
                 else setIsEdit(true)
               })
             }}

+ 87 - 0
后台管理/src/pages/C3storageMove/C3look/index.module.scss

@@ -1,4 +1,91 @@
 .C3look {
+  background-color: #fff;
+  border-radius: 10px;
+  font-size: 16px;
+  overflow: auto;
+  padding: 20px;
   :global {
+    .C3lTit {
+      font-weight: 700;
+      font-size: 18px;
+      color: var(--themeColor);
+      margin-right: 20px;
+    }
+
+    .C3lTit2 {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+    }
+
+    .C3lTop {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      border-bottom: 1px solid #ccc;
+      padding-bottom: 15px;
+
+      .C3lTopll {
+        display: flex;
+        align-items: center;
+      }
+      .C3lToprr {
+        position: absolute;
+        top: 20px;
+        right: 20px;
+        z-index: 10;
+      }
+      .C3lTopllBtn {
+        pointer-events: none;
+      }
+    }
+
+    .C3form {
+      display: flex;
+      flex-wrap: wrap;
+      display: flex;
+      justify-content: space-between;
+      border-bottom: 1px solid #ccc;
+      padding: 15px 0;
+      margin-bottom: 15px;
+      padding-right: 15%;
+    }
+    .C3formRow {
+      width: 49%;
+      display: flex;
+      margin-bottom: 15px;
+      .C3formRowll {
+        position: relative;
+        width: 110px;
+        font-weight: 700;
+        text-align: right;
+        min-height: 32px;
+        line-height: 32px;
+        & > span {
+          color: #ff4d4f;
+        }
+      }
+
+      .C3formRowrr {
+        width: calc(100% - 110px);
+        .ant-btn {
+          margin-right: 20px;
+        }
+      }
+      .C3formRowrr2 {
+        height: 32px;
+        line-height: 32px;
+      }
+    }
+    .C3formRowAll {
+      width: 100%;
+    }
+
+    .ant-table-wrapper {
+      margin-top: 15px;
+      .ant-table-cell {
+        padding: 8px !important;
+      }
+    }
   }
 }

+ 454 - 2
后台管理/src/pages/C3storageMove/C3look/index.tsx

@@ -1,9 +1,461 @@
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import styles from './index.module.scss'
+import { useParams } from 'react-router-dom'
+import { API_getGoodsInfo } from '@/store/action/B1ledger'
+import { B1listType } from '@/pages/B1ledger/data'
+import {
+  C3_APIaduit,
+  C3_APIcreate,
+  C3_APIgetInfo,
+  C3_APIresubmit
+} from '@/store/action/C3storageMove'
+import { statusSelect } from '@/utils/select'
+import { siteLocChange } from '@/utils/deriveFu'
+import { C2lookPageStaObj, locTxtChangeFu, locTxtValueFu } from '@/pages/C2storageIn/data'
+import { Button, DatePicker, Input } from 'antd'
+import history, { backPageFu, openLink } from '@/utils/history'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import { MessageFu } from '@/utils/message'
+import dayjs from 'dayjs'
+import TextArea from 'antd/es/input/TextArea'
+import Z3upFiles from '@/components/Z3upFiles'
+import MyTable from '@/components/MyTable'
+import { auditTableC, goodsSelectTableC } from '@/utils/tableData'
+import A0selectGoods from '@/pages/A0selectGoods'
 function C3look() {
+  const { key, id } = useParams<any>()
+  // key:1-新增 2-重新提交/编辑 3-查看 4-审批
+
+  // 从藏品信息模块进来,带上当前藏品信息
+  const isGoodsInfoRu = useCallback(async (id: number) => {
+    const res = await API_getGoodsInfo(id)
+    if (res.code === 0) {
+      setSnaps([res.data])
+    }
+  }, [])
+
+  useEffect(() => {
+    const urlAll = window.location.href
+    if (key === '1' && urlAll.includes('?oldId=')) {
+      isGoodsInfoRu(Number(urlAll.split('?oldId=')[1]))
+    }
+  }, [isGoodsInfoRu, key])
+
+  // 顶部数据
+  const [info, setInfo] = useState({} as B1listType)
+
+  // 新增的时候进页面创建订单
+  const createFu = useCallback(async () => {
+    const res = await C3_APIcreate()
+    if (res.code === 0) {
+      setInfo(res.data)
+    }
+  }, [])
+
+  // 获取详情
+  const getInfoFu = useCallback(async () => {
+    const res = await C3_APIgetInfo(id)
+    if (res.code === 0) {
+      // console.log('获取详情:', res)
+      const data = res.data
+      setInfo(data)
+      // 设置附件(需要异步)
+
+      setTimeout(() => {
+        filesRef.current?.showList(data.files || [])
+      }, 100)
+
+      // 藏品清单快照信息id对比
+      const arrTemp: any = []
+      const snapsTemp = data.snaps || []
+
+      snapsTemp.forEach((v: any) => {
+        snapsID2ref.current.push({ goodsId: v.goodsId, id: v.id })
+
+        const obj = JSON.parse(v.snap || '{}')
+        if (obj.id) obj.id2 = v.id
+
+        arrTemp.push({ ...obj })
+      })
+
+      setSnaps(arrTemp)
+    }
+  }, [id])
+
+  useEffect(() => {
+    if (key === '1') createFu()
+    else if (['2', '3', '4'].includes(key)) getInfoFu()
+  }, [createFu, getInfoFu, key])
+
+  // 申请状态
+  const topStatusRes = useMemo(() => {
+    let txt = '创建订单'
+    const obj = statusSelect.find(v => v.value === info.status)
+    if (obj) txt = obj.label
+    return txt
+  }, [info.status])
+
+  // 审批的sta
+  const [auditSta, setAuDitSta] = useState('')
+  const [rtfOpinion, setRtfOpinion] = useState('')
+
+  const boxRef = useRef<HTMLDivElement>(null)
+
+  // 上传附件的ref
+  const filesRef = useRef<any>(null)
+
+  // 藏品清单 和 快照数据
+
+  const [snaps, setSnaps] = useState<B1listType[]>([])
+  const delSnapIdsRef = useRef<number[]>([])
+
+  const snapsID2ref = useRef<{ goodsId: number; id: number }[]>([])
+
+  const goodsTableBtn = useMemo(() => {
+    return [
+      {
+        title: '移库前位置',
+        render: (item: B1listType) => siteLocChange(item.siteLoc)
+      },
+      {
+        title: '移至',
+        render: (item: B1listType) => {
+          return (
+            <>
+              {['柜号', '层数', '层格编号'].map((txt, index) => (
+                <div key={index} className='C2TableTxt'>
+                  <Input
+                    readOnly={['3', '4'].includes(key)}
+                    placeholder={['3', '4'].includes(key) ? '(空)' : `请输入${txt}`}
+                    maxLength={10}
+                    value={locTxtValueFu(index, item.siteOut)}
+                    showCount
+                    onChange={e =>
+                      setSnaps(
+                        snaps.map(v => ({
+                          ...v,
+                          siteOut:
+                            v.id === item.id
+                              ? locTxtChangeFu(index, e.target.value.trim(), item.siteOut)
+                              : v.siteOut
+                        }))
+                      )
+                    }
+                  />
+                </div>
+              ))}
+            </>
+          )
+        }
+      },
+      {
+        title: '操作',
+        render: (item: B1listType) => {
+          return (
+            <>
+              <Button size='small' type='text' onClick={() => openLink(`/goodsLook/${item.id}`)}>
+                查看
+              </Button>
+              {['3', '4'].includes(key) ? null : (
+                <MyPopconfirm
+                  txtK='删除'
+                  onConfirm={() => {
+                    if (item.id2 && !delSnapIdsRef.current.includes(item.id2))
+                      delSnapIdsRef.current.push(item.id2)
+
+                    setSnaps(snaps.filter(v => v.id !== item.id))
+                  }}
+                />
+              )}
+            </>
+          )
+        }
+      }
+    ]
+  }, [key, snaps])
+
+  // 点击提交
+  const btnOk = useCallback(async () => {
+    if (key === '4') {
+      // 审批
+      if (!auditSta) {
+        MessageFu.warning('请选择审批结果')
+        boxRef.current?.scrollTo({ top: 0, behavior: 'smooth' })
+        return
+      }
+
+      const res = await C3_APIaduit({
+        orderId: info.id,
+        rtfOpinion,
+        status: auditSta === '同意' ? 1 : 2
+      })
+
+      if (res.code === 0) {
+        MessageFu.success('审批成功')
+        history.replace(`/storageMove_look/3/${info.id}`)
+      }
+    } else if (['1', '2'].includes(key)) {
+      // 新增和重新提交
+
+      // 处理日期格式
+      if (!info.date) {
+        MessageFu.warning('请选择移库日期')
+        boxRef.current?.scrollTo({ top: 0, behavior: 'smooth' })
+        return
+      }
+
+      if (!info.num) {
+        MessageFu.warning('请输入移库单编号')
+        boxRef.current?.scrollTo({ top: 0, behavior: 'smooth' })
+        return
+      }
+
+      if (snaps.length === 0) return MessageFu.warning('请添加藏品')
+
+      // 附件
+      let fileIds = ''
+      const fileArr: any[] = filesRef.current?.filesRes()
+      if (fileArr && fileArr.length) fileIds = fileArr.map(v => v.id).join(',')
+
+      const snapsRes = snaps.map(v => ({
+        goodsId: v.id,
+        id: v.id2 ? v.id2 : null,
+        orderId: info.id,
+        siteOut: v.siteOut,
+        snap: JSON.stringify(v)
+      }))
+
+      const obj = {
+        date: info.date,
+        delSnapIds: delSnapIdsRef.current.length ? delSnapIdsRef.current : '',
+        fileIds,
+        goodIds: snaps.map(v => v.id).join(','),
+        id: info.id,
+        num: info.num,
+        reason: info.reason,
+        snaps: snapsRes
+      }
+
+      // if (1 + 1 === 2) {
+      //   console.log(123, obj)
+      //   return
+      // }
+
+      const res = await C3_APIresubmit(obj)
+
+      if (res.code === 0) {
+        MessageFu.success(key === '1' ? '创建订单成功' : '重新提交成功')
+        history.replace(`/storageMove_look/3/${info.id}`)
+      }
+    }
+  }, [auditSta, info, key, rtfOpinion, snaps])
+
+  // 点击新增打开弹窗
+  const [addShow, setAddShow] = useState(false)
+
   return (
     <div className={styles.C3look}>
-      <h1>C3look</h1>
+      <div className='pageTitle'>藏品移库 - {Reflect.get(C2lookPageStaObj, key)}</div>
+
+      {info.id ? (
+        <>
+          <div className='C3lTop'>
+            <div className='C3lTopll'>
+              <div className='C3lTit'>申请信息</div>
+              <div className='C3lTopllBtn'>
+                <Button type='dashed'>{topStatusRes}</Button>
+              </div>
+            </div>
+            <div className='C3lToprr'>
+              {key !== '3' ? (
+                <>
+                  <Button type='primary' onClick={btnOk}>
+                    提交
+                  </Button>
+                  &emsp;
+                </>
+              ) : null}
+
+              {['1', '2'].includes(key) ? (
+                <MyPopconfirm txtK='返回' onConfirm={() => backPageFu('/storageMove')} />
+              ) : (
+                <Button onClick={() => backPageFu('/storageMove')}>返回</Button>
+              )}
+            </div>
+          </div>
+
+          <div className='C3form'>
+            {['3', '4'].includes(key) ? (
+              <>
+                <div className='C3formRow'>
+                  <div className='C3formRowll'>订单类型:</div>
+                  <div className='C3formRowrr C3formRowrr2'>藏品移库</div>
+                </div>
+
+                <div className='C3formRow'>
+                  <div className='C3formRowll'>发起人员:</div>
+                  <div className='C3formRowrr C3formRowrr2'>
+                    {info.creatorName + ' - ' + info.createTime}
+                  </div>
+                </div>
+              </>
+            ) : null}
+
+            <div className='C3formRow'>
+              <div className='C3formRowll'>
+                <span>* </span>移库日期:
+              </div>
+              <div className='C3formRowrr'>
+                <DatePicker
+                  disabled={['3', '4'].includes(key)}
+                  allowClear={false}
+                  value={info.date ? dayjs(info.date) : null}
+                  onChange={e => setInfo({ ...info, date: dayjs(e).format('YYYY-MM-DD') })}
+                />
+              </div>
+            </div>
+
+            <div className='C3formRow'>
+              <div className='C3formRowll'>
+                <span>* </span>移库单编号:
+              </div>
+              <div className='C3formRowrr'>
+                <Input
+                  value={info.num}
+                  onChange={e => setInfo({ ...info, num: e.target.value.trim() })}
+                  readOnly={['3', '4'].includes(key)}
+                  placeholder='请输入内容'
+                  maxLength={30}
+                  showCount
+                />
+              </div>
+            </div>
+
+            <div className='C3formRow C3formRowAll'>
+              <div className='C3formRowll'>事由说明:</div>
+              <div className='C3formRowrr'>
+                <TextArea
+                  value={info.reason}
+                  onChange={e => setInfo({ ...info, reason: e.target.value })}
+                  readOnly={['3', '4'].includes(key)}
+                  placeholder={['3', '4'].includes(key) ? '(空)' : '请输入内容'}
+                  maxLength={1000}
+                  showCount
+                />
+              </div>
+            </div>
+
+            {['3', '4'].includes(key) ? (
+              <div style={{ width: '100%', height: '10px' }}></div>
+            ) : null}
+
+            <div className='C3formRow C3formRowAll'>
+              <div className='C3formRowll'>附件:</div>
+              <div className='C3formRowrr'>
+                <Z3upFiles
+                  size={500}
+                  isLook={['3', '4'].includes(key)}
+                  ref={filesRef}
+                  fileCheck={false}
+                  dirCode='storageMove_look'
+                  myUrl='cms/orderSite/move/upload'
+                />
+              </div>
+            </div>
+
+            {/* 审批相关 */}
+            {key === '4' ? (
+              <>
+                <div className='C3formRow C3formRowAll'>
+                  <div className='C3formRowll'>
+                    <span>* </span>审批结果:
+                  </div>
+                  <div className='C3formRowrr'>
+                    {['同意', '不同意'].map(v => (
+                      <Button
+                        key={v}
+                        onClick={() => setAuDitSta(v)}
+                        type={auditSta === v ? 'primary' : 'default'}
+                      >
+                        {v}
+                      </Button>
+                    ))}
+                  </div>
+                </div>
+                <div className='C3formRow C3formRowAll' style={{ marginBottom: 25 }}>
+                  <div className='C3formRowll'>审批意见:</div>
+                  <div className='C3formRowrr'>
+                    <TextArea
+                      value={rtfOpinion}
+                      onChange={e => setRtfOpinion(e.target.value)}
+                      placeholder='请输入内容'
+                      maxLength={200}
+                      showCount
+                    />
+                  </div>
+                </div>
+              </>
+            ) : null}
+          </div>
+
+          <div className='C3lTit2'>
+            <div className='C3lTit'>藏品清单</div>
+            {['1', '2'].includes(key) ? (
+              <Button type='primary' onClick={() => setAddShow(true)}>
+                新增
+              </Button>
+            ) : (
+              <div></div>
+            )}
+          </div>
+
+          <MyTable
+            list={snaps}
+            columnsTemp={goodsSelectTableC}
+            lastBtn={goodsTableBtn}
+            pagingInfo={false}
+          />
+
+          {['3', '4'].includes(key) ? (
+            <>
+              <div className='C3lTit'>申请流程</div>
+
+              <MyTable
+                list={info.audits || []}
+                columnsTemp={auditTableC}
+                pagingInfo={false}
+                widthSet={{ rtfOpinion: 600 }}
+              />
+            </>
+          ) : null}
+        </>
+      ) : null}
+
+      {/* 打开藏品选择弹窗 */}
+      {addShow ? (
+        <A0selectGoods
+          type='移库'
+          closeFu={() => setAddShow(false)}
+          oldCheckArr={snaps}
+          dataResFu={data => {
+            //需要过滤掉已经有id的-不替换数据,没有id的替换数据 因为数据可能已经在另外一个弹窗更新了
+            const nowIds = snaps.map(v => v.id)
+            let dataRes = data.map((v, i) => {
+              if (nowIds.includes(v.id)) return snaps[i]
+              else return v
+            })
+
+            dataRes.forEach(v => {
+              // id2表示的是自己这条数据的id id才是goodsId
+              const obj = snapsID2ref.current.find(c => c.goodsId === v.id)
+
+              if (obj) v.id2 = obj.id
+            })
+
+            setSnaps(dataRes)
+          }}
+        />
+      ) : null}
     </div>
   )
 }

+ 19 - 0
后台管理/src/pages/C3storageMove/index.module.scss

@@ -1,4 +1,23 @@
 .C3storageMove {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 20px;
   :global {
+    .C3top {
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 15px;
+      .C3topll {
+        display: flex;
+      }
+      .C3toprr {
+        .ant-btn {
+          margin-left: 15px;
+        }
+      }
+    }
+    .ant-table-cell {
+      padding: 8px !important;
+    }
   }
 }

+ 163 - 1
后台管理/src/pages/C3storageMove/index.tsx

@@ -1,9 +1,171 @@
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import styles from './index.module.scss'
+import { Button, DatePicker, Input, Select } from 'antd'
+import { useDispatch, useSelector } from 'react-redux'
+import { C2fromDataBase } from '../C2storageIn/data'
+import { C3_APIgetlist } from '@/store/action/C3storageMove'
+import { RootState } from '@/store'
+import { B1listType } from '../B1ledger/data'
+import history, { aduitBtnRoleFu, resubmitBtnRoleFu } from '@/utils/history'
+import { statusSelect } from '@/utils/select'
+import { C2devFu } from '@/utils/deriveFu'
+import MyTable from '@/components/MyTable'
+import { C2tableCFu } from '@/utils/tableData'
+
+const { RangePicker } = DatePicker
+
 function C3storageMove() {
+  const dispatch = useDispatch()
+  const [formData, setFormData] = useState({ ...C2fromDataBase, type: 'YK' })
+
+  const getListFu = useCallback(() => {
+    dispatch(C3_APIgetlist(formData))
+  }, [dispatch, formData])
+
+  useEffect(() => {
+    getListFu()
+  }, [getListFu])
+
+  // 输入框改变
+  const timeRef = useRef(-1)
+  const txtChangeFu = useCallback(
+    (e: React.ChangeEvent<HTMLInputElement>, key: 'num') => {
+      clearTimeout(timeRef.current)
+      timeRef.current = window.setTimeout(() => {
+        setFormData({
+          ...formData,
+          [key]: e.target.value,
+          pageNum: 1
+        })
+      }, 500)
+    },
+    [formData]
+  )
+
+  // 时间选择器改变
+  const timeChange = useCallback(
+    (date: any, dateString: any) => {
+      let startTime = ''
+      let endTime = ''
+      if (dateString[0] && dateString[1]) {
+        startTime = dateString[0] + ' 00:00:00'
+        endTime = dateString[1] + ' 23:59:59'
+      }
+      setFormData({ ...formData, startTime, endTime, pageNum: 1 })
+    },
+    [formData]
+  )
+
+  // 点击重置
+  const [inputKey, setInputKey] = useState(1)
+  const resetSelectFu = useCallback(() => {
+    // 把2个输入框和时间选择器清空
+    setInputKey(Date.now())
+    setFormData({ ...C2fromDataBase, type: 'YK' })
+  }, [])
+
+  // 从仓库拿数据
+  const tableInfo = useSelector((state: RootState) => state.C3storageMove.tableInfo)
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        render: (item: B1listType) => {
+          return (
+            <>
+              <Button
+                size='small'
+                type='text'
+                onClick={() => history.push(`/storageMove_look/3/${item.id}`)}
+              >
+                查看
+              </Button>
+
+              {aduitBtnRoleFu(item) ? (
+                <Button
+                  size='small'
+                  type='text'
+                  onClick={() => history.push(`/storageMove_look/4/${item.id}`)}
+                >
+                  审批
+                </Button>
+              ) : null}
+
+              {resubmitBtnRoleFu(item) ? (
+                <Button
+                  size='small'
+                  type='text'
+                  onClick={() => history.push(`/storageMove_look/2/${item.id}`)}
+                >
+                  重新提交
+                </Button>
+              ) : null}
+            </>
+          )
+        }
+      }
+    ]
+  }, [])
+
+  // 页码变化
+  const paginationChange = useCallback(
+    (pageNum: number, pageSize: number) => {
+      setFormData({ ...formData, pageNum, pageSize })
+    },
+    [formData]
+  )
+
   return (
     <div className={styles.C3storageMove}>
       <div className='pageTitle'>藏品移库</div>
+
+      <div className='C3top'>
+        <div className='C3topll' key={inputKey}>
+          <RangePicker
+            placeholder={['移库日期起', '移库日期终']}
+            style={{ width: 240 }}
+            onChange={timeChange}
+          />
+          &emsp;
+          <Input
+            placeholder='移库单编号'
+            maxLength={30}
+            showCount
+            allowClear
+            onChange={e => txtChangeFu(e, 'num')}
+            style={{ width: 200 }}
+          />
+          &emsp;
+          <Select
+            allowClear
+            style={{ width: 200 }}
+            placeholder='申请状态'
+            options={statusSelect}
+            value={formData.status}
+            onChange={e => setFormData({ ...formData, status: e })}
+          />
+          &emsp;
+        </div>
+        <div className='C3toprr'>
+          <Button onClick={resetSelectFu}>重置</Button>&emsp;
+          <Button type='primary' onClick={() => C2devFu(formData, '移库')}>
+            数据导出
+          </Button>
+        </div>
+      </div>
+
+      {/* 表格 */}
+      <MyTable
+        yHeight={655}
+        list={tableInfo.list}
+        columnsTemp={C2tableCFu('移库')}
+        lastBtn={tableLastBtn}
+        pageNum={formData.pageNum}
+        pageSize={formData.pageSize}
+        total={tableInfo.total}
+        onChange={(pageNum, pageSize) => paginationChange(pageNum, pageSize)}
+      />
     </div>
   )
 }

+ 5 - 0
后台管理/src/pages/C4storageOut/C4look/index.tsx

@@ -21,6 +21,7 @@ import MyTable from '@/components/MyTable'
 import { auditTableC, goodsSelectTableC } from '@/utils/tableData'
 import A0selectGoods from '@/pages/A0selectGoods'
 import { API_getGoodsInfo } from '@/store/action/B1ledger'
+import { siteLocChange } from '@/utils/deriveFu'
 function C4look() {
   const { key, id } = useParams<any>()
   // key:1-新增 2-重新提交/编辑 3-查看 4-审批
@@ -113,6 +114,10 @@ function C4look() {
   const goodsTableBtn = useMemo(() => {
     return [
       {
+        title: '出库前位置',
+        render: (item: B1listType) => siteLocChange(item.siteLoc)
+      },
+      {
         title: '去向',
         render: (item: B1listType) => {
           return (