chenlei 1 день назад
Родитель
Сommit
57c2689906

+ 21 - 0
src/pages/Dmanage/D4resource/D4edit/ResourceDownLog/index.module.scss

@@ -0,0 +1,21 @@
+.ResourceDownLog {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal {
+      width: 800px !important;
+    }
+    .ant-modal-body {
+      padding-top: 10px !important;
+      border-top: 1px solid #ccc;
+      .ant-table-cell {
+        padding: 8px !important;
+      }
+    }
+    .ResourceDownLogBtn {
+      margin-top: 15px;
+      text-align: center;
+    }
+  }
+}

+ 55 - 0
src/pages/Dmanage/D4resource/D4edit/ResourceDownLog/index.tsx

@@ -0,0 +1,55 @@
+import React, { useCallback, useEffect, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Modal } from 'antd'
+import MyTable from '@/components/MyTable'
+import { D4API_downloadLog } from '@/store/action/Dmanage/D4resource'
+import { MessageFu } from '@/utils/message'
+
+type Props = {
+  ids: number[]
+  closeFu: () => void
+}
+
+function ResourceDownLog({ closeFu, ids }: Props) {
+  const [list, setList] = useState<any[]>([])
+
+  const getList = useCallback(async () => {
+    if (!ids.length) {
+      MessageFu.warning('暂无藏品')
+      return
+    }
+    const res = await D4API_downloadLog(ids)
+    if (res.code === 0) {
+      setList(res.data || [])
+    }
+  }, [ids])
+
+  useEffect(() => {
+    getList()
+  }, [getList])
+
+  return (
+    <Modal wrapClassName={styles.ResourceDownLog} title='下载记录' open={true} footer={[]}>
+      <MyTable
+        yHeight={500}
+        classKey='ResourceDownLog'
+        list={list}
+        columnsTemp={[
+          ['txt', '藏品登记号', 'joinNum'],
+          ['txt', '藏品名称', 'joinName'],
+          ['txt', '下载人员', 'creatorName'],
+          ['txt', '下载时间', 'createTime']
+        ]}
+        pagingInfo={false}
+      />
+
+      <div className='ResourceDownLogBtn'>
+        <Button onClick={closeFu}>关闭</Button>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoResourceDownLog = React.memo(ResourceDownLog)
+
+export default MemoResourceDownLog

+ 40 - 6
src/pages/Dmanage/D4resource/D4edit/index.tsx

@@ -6,9 +6,16 @@ import { InfoProvider, useInfo } from '@/pages/Zother/InfoContext'
 import SonGoodsList from '@/pages/Zother/SonGoodsList'
 import FileArchive from '@/pages/Zother/FileArchive'
 import { getDictFu, selectObj } from '@/utils/dataChange'
-import { D4_APIgetClueList, D4API_obj } from '@/store/action/Dmanage/D4resource'
+import {
+  D4_APIgetClueList,
+  D4API_downloadFiles,
+  D4API_obj
+} from '@/store/action/Dmanage/D4resource'
+import ResourceDownLog from './ResourceDownLog'
 import { Button, Checkbox } from 'antd'
 import { useParams } from 'react-router-dom'
+import { baseURL } from '@/utils/http'
+import { MessageFu } from '@/utils/message'
 
 const rowArr = [
   {
@@ -50,13 +57,14 @@ const rowArr = [
 ]
 
 function D4editContent() {
-  const { info } = useInfo() as { info: any }
+  const { info, snaps } = useInfo() as { info: any; snaps: any[] }
   const { key } = useParams<any>()
   const [resourceType, setResourceType] = useState<string[]>(
     key === '1' ? selectObj['附件类型'].map((v: any) => v.value) : []
   )
   const canEdit = useMemo(() => ['1', '2'].includes(key), [key])
   const isOk = useMemo(() => info.status === 4, [info.status])
+  const [showDownLog, setShowDownLog] = useState(false)
 
   const handleResourceTypeChange = useCallback((val: string[]) => {
     setResourceType(val)
@@ -73,6 +81,20 @@ function D4editContent() {
     setResourceType(info.snapType.split(','))
   }, [info.snapType])
 
+  const handleDownloadAll = useCallback(async () => {
+    const ids = snaps.map(v => v.id).filter(Boolean)
+    if (!ids.length) {
+      MessageFu.warning('暂无藏品可下载')
+      return
+    }
+    const res: any = await D4API_downloadFiles(ids)
+    if (res?.code === 0 && res?.data) {
+      const path = res.data as string
+      const fullUrl = path.startsWith('http') ? path : `${baseURL}${path}`
+      window.open(fullUrl)
+    }
+  }, [snaps])
+
   return (
     <div className={styles.D4edit} id='editBox'>
       <div className='editMain'>
@@ -96,8 +118,8 @@ function D4editContent() {
           </div>
           {isOk && (
             <div>
-              <Button>查看下载记录</Button>
-              <Button>下载全部资源</Button>
+              <Button onClick={() => setShowDownLog(true)}>查看下载记录</Button>
+              <Button onClick={handleDownloadAll}>下载全部资源</Button>
             </div>
           )}
         </div>
@@ -115,8 +137,13 @@ function D4editContent() {
                   <Button
                     size='small'
                     type='text'
-                    onClick={() => {
-                      // TODO: 调用下载资源接口,传入 item.id
+                    onClick={async () => {
+                      const res: any = await D4API_downloadFiles([item.id])
+                      if (res?.code === 0 && res?.data) {
+                        const path = res.data as string
+                        const fullUrl = path.startsWith('http') ? path : `${baseURL}${path}`
+                        window.open(fullUrl)
+                      }
                     }}
                   >
                     下载资源
@@ -129,6 +156,13 @@ function D4editContent() {
         {/* 附件归档 */}
         <FileArchive />
 
+        {showDownLog && (
+          <ResourceDownLog
+            ids={snaps.map(v => v.id).filter(Boolean)}
+            closeFu={() => setShowDownLog(false)}
+          />
+        )}
+
         {/* 底部按钮 */}
         <EditBtn
           path='/resource'

+ 11 - 9
src/pages/Fstorehouse/F3outStorage/F3edit/index.tsx

@@ -80,21 +80,23 @@ function F3editContent() {
   }
 
   useEffect(() => {
-    const urlAll = window.location.href
-    if (urlAll.includes('?showId=')) {
-      const showIdStr = urlAll.split('?showId=')[1]?.split('&')[0]?.split('#')[0]
-      if (showIdStr) {
-        const showId = Number(showIdStr)
-        setInfoFu({ showId } as any)
-      }
+    if (!info.num) return
+    const hash = window.location.hash
+    const queryIndex = hash.indexOf('?')
+    const search = queryIndex >= 0 ? hash.slice(queryIndex) : ''
+    const params = new URLSearchParams(search)
+    const showIdStr = params.get('showId')
+    const showName = params.get('showName')
+    if (showIdStr) {
+      const showId = Number(showIdStr)
+      setInfoFu((v: any) => ({ ...v, showId, ...(showName != null && { showName }) }))
     }
-  }, [setInfoFu])
+  }, [info.num, setInfoFu])
 
   return (
     <div className={styles.F3edit} id='editBox'>
       <div className='editMain'>
         {/* 顶部 */}
-        {/* TODO: 借展归还待完善 */}
         <EditTop
           pageTxt='藏品出库'
           rowArr={rowArr}

+ 1 - 1
src/pages/Fstorehouse/F4check/F4edit/index.tsx

@@ -20,7 +20,7 @@ import MyTable from '@/components/MyTable'
 import { GoodsType } from '@/pages/Zother/SonGoodsList/data'
 import { openLink } from '@/utils/history'
 
-const rowArr = rowArrTemp('入库')
+const rowArr = rowArrTemp('盘点')
 const registerMenu = [
   {
     key: 'accident',

+ 80 - 4
src/pages/Hexhibits/H1loan/H1detail/index.tsx

@@ -6,13 +6,15 @@ import {
   H1_APIgetInfo,
   H1_APIsave,
   H1_APIdelete,
-  H1_APIgetShowGoodPage
+  H1_APIgetShowGoodPage,
+  H1_APIupdateRegion
 } from '@/store/action/Hexhibits/H1loan'
 import { API_getFileListByIds } from '@/store/action/Cledger/C4file'
 import ExhibitionModal, { ExhibitionFormValues } from '../components/ExhibitionModal'
+import RegionSettingModal from '../components/RegionSettingModal'
 import { MessageFu } from '@/utils/message'
 import MyPopconfirm from '@/components/MyPopconfirm'
-import history from '@/utils/history'
+import history, { openLink } from '@/utils/history'
 import dayjs from 'dayjs'
 import { baseURL } from '@/utils/http'
 import { FileListType } from '@/components/Z3upFiles/data'
@@ -57,6 +59,10 @@ function H1detail() {
   const [info, setInfo] = useState<DetailInfo>({})
   const [fileList, setFileList] = useState<FileListType[]>([])
   const [exhibitionModalOpen, setExhibitionModalOpen] = useState(false)
+  const [regionSettingOpen, setRegionSettingOpen] = useState(false)
+  const [regionEditList, setRegionEditList] = useState<
+    { id: number; goodNum: string; goodName: string; region: string; address: string }[]
+  >([])
 
   const getInfo = useCallback(async () => {
     if (!id) return
@@ -191,6 +197,61 @@ function H1detail() {
     setTimeout(() => setGoodTimeKey(Date.now()), 50)
   }, [])
 
+  const openRegionSetting = useCallback(() => {
+    const list = goodList.map((item: any) => ({
+      id: item.id,
+      goodNum: item.goodNum || '',
+      goodName: item.goodName || '',
+      region: item.region || '',
+      address: item.address || ''
+    }))
+    setRegionEditList(list)
+    setRegionSettingOpen(true)
+  }, [goodList])
+
+  const updateRegionEditItem = useCallback(
+    (index: number, field: 'region' | 'address', value: string) => {
+      setRegionEditList(prev =>
+        prev.map((item, i) => (i === index ? { ...item, [field]: value } : item))
+      )
+    },
+    []
+  )
+
+  const handleRegionSubmit = useCallback(async () => {
+    const payload = regionEditList.map(item => ({
+      id: item.id,
+      region: item.region || '',
+      address: item.address || ''
+    }))
+    const res = await H1_APIupdateRegion(payload)
+    if (res?.code === 0) {
+      MessageFu.success('展位设置成功')
+      setRegionSettingOpen(false)
+      setGoodTimeKey(Date.now())
+    } else {
+      MessageFu.error(res?.message || '展位设置失败')
+    }
+  }, [regionEditList])
+
+  const goodTableLastBtn = useMemo(
+    () => [
+      {
+        title: '操作',
+        render: (item: any) => (
+          <Button
+            size='small'
+            type='text'
+            onClick={() => openLink(`/goodsLook/${item.goodId ?? item.id}`)}
+          >
+            查看
+          </Button>
+        )
+      }
+    ],
+    []
+  )
+
   const regionOptions = useMemo(() => {
     const r = info.region
     if (!r) return []
@@ -268,9 +329,14 @@ function H1detail() {
         <div className='H1detailMainTitle'>
           <span>展品清单</span>
           <div>
-            <Button>展位设置</Button>
+            <Button onClick={openRegionSetting} disabled={!info.id || !goodList.length}>
+              展位设置
+            </Button>
             <Button
-              onClick={() => info.id && history.push(`/outStorage_edit/1/null?showId=${info.id}`)}
+              onClick={() =>
+                info.id &&
+                history.push(`/outStorage_edit/1/null?showId=${info.id}&showName=${info.name}`)
+              }
               disabled={!info.id}
             >
               借展出库
@@ -342,6 +408,7 @@ function H1detail() {
             pageSize={goodFormData.pageSize}
             yHeight={400}
             onChange={goodPaginationChange}
+            lastBtn={goodTableLastBtn}
           />
         </div>
       </div>
@@ -353,6 +420,15 @@ function H1detail() {
         initialValues={info}
         initialFileList={fileList}
       />
+
+      <RegionSettingModal
+        open={regionSettingOpen}
+        onCancel={() => setRegionSettingOpen(false)}
+        dataSource={regionEditList}
+        regionOptions={regionOptions}
+        onUpdateItem={updateRegionEditItem}
+        onSubmit={handleRegionSubmit}
+      />
     </div>
   )
 }

+ 79 - 0
src/pages/Hexhibits/H1loan/components/RegionSettingModal.tsx

@@ -0,0 +1,79 @@
+import React from 'react'
+import { Button, Input, Modal, Select, Table } from 'antd'
+
+export type RegionEditItem = {
+  id: number
+  goodNum: string
+  goodName: string
+  region: string
+  address: string
+}
+
+type Props = {
+  open: boolean
+  onCancel: () => void
+  dataSource: RegionEditItem[]
+  regionOptions: { label: string; value: string }[]
+  onUpdateItem: (index: number, field: 'region' | 'address', value: string) => void
+  onSubmit: () => void
+}
+
+function RegionSettingModal({
+  open,
+  onCancel,
+  dataSource,
+  regionOptions,
+  onUpdateItem,
+  onSubmit
+}: Props) {
+  return (
+    <Modal title='展位设置' open={open} onCancel={onCancel} footer={null} width={800}>
+      <Table
+        dataSource={dataSource}
+        rowKey='id'
+        pagination={false}
+        scroll={{ y: 600 }}
+        columns={[
+          { title: '藏品登记号', dataIndex: 'goodNum', width: 120 },
+          { title: '藏品名称', dataIndex: 'goodName', width: 150 },
+          {
+            title: '展区',
+            dataIndex: 'region',
+            width: 150,
+            render: (_: any, record: RegionEditItem, index: number) => (
+              <Select
+                placeholder='请选择展区'
+                allowClear
+                value={record.region || undefined}
+                onChange={v => onUpdateItem(index, 'region', v || '')}
+                options={regionOptions}
+                style={{ width: '100%' }}
+              />
+            )
+          },
+          {
+            title: '具体位置',
+            dataIndex: 'address',
+            render: (_: any, record: RegionEditItem, index: number) => (
+              <Input
+                placeholder='请填写具体位置'
+                maxLength={100}
+                showCount
+                value={record.address}
+                onChange={e => onUpdateItem(index, 'address', e.target.value)}
+              />
+            )
+          }
+        ]}
+      />
+      <div style={{ marginTop: 16, textAlign: 'right' }}>
+        <Button onClick={onCancel}>取消</Button>
+        <Button type='primary' onClick={onSubmit} style={{ marginLeft: 8 }}>
+          提交
+        </Button>
+      </div>
+    </Modal>
+  )
+}
+
+export default React.memo(RegionSettingModal)

+ 14 - 0
src/store/action/Dmanage/D4resource.ts

@@ -36,3 +36,17 @@ export const D4API_obj = {
   撤回: (id: number) => APIbase('get', `cms/order/resource/revocation/${id}`),
   删除: (id: number) => APIbase('get', `cms/order/resource/remove/${id}`)
 }
+
+/**
+ * 藏品附件 -根据附件id批量下载附件
+ */
+export const D4API_downloadFiles = (ids: number[]) => {
+  return http.post('cms/order/resource/downloadBatchZip', ids)
+}
+
+/**
+ * 资源使用 - 下载记录
+ */
+export const D4API_downloadLog = (ids: number[]) => {
+  return http.post('cms/order/resource/downloadLog', ids)
+}

+ 9 - 0
src/store/action/Hexhibits/H1loan.ts

@@ -36,3 +36,12 @@ export const H1_APIdelete = (id: number): any => {
 export const H1_APIgetShowGoodPage = (data: any): any => {
   return http.post('cms/show/showGoodPage', data)
 }
+
+/**
+ * 展位设置 - 更新展区与具体位置
+ */
+export const H1_APIupdateRegion = (
+  data: { id: number; region: string; address: string }[]
+): any => {
+  return http.post('cms/show/updateRegion', data)
+}

+ 2 - 2
src/utils/http.ts

@@ -7,8 +7,8 @@ import { domShowFu } from './domShow'
 
 export const envFlag = process.env.NODE_ENV === 'development'
 
-const baseUrlTemp = 'https://sit-qingdaobeer.4dage.com' // 测试环境
-// const baseUrlTemp = 'http://192.168.20.61:8112' // 线下环境
+// const baseUrlTemp = 'https://sit-qingdaobeer.4dage.com' // 测试环境
+const baseUrlTemp = 'http://192.168.20.61:8112' // 线下环境
 
 const baseFlag = baseUrlTemp.includes('https://')
 

+ 5 - 5
src/utils/tableData.ts

@@ -291,12 +291,12 @@ export const staffTableC = [
 
 // 借展详情-展品清单
 export const showGoodTableC = [
-  ['txt', '藏品登记号', 'num'],
-  ['img', '封面', 'thumb'],
-  ['txtCTag', '藏品标签', 'tagDictId'],
-  ['txt', '藏品名称', 'name'],
+  ['txt', '藏品登记号', 'goodNum'],
+  ['img', '封面', 'goodThumb'],
+  ['txtCTag', '藏品标签', 'goodTag'],
+  ['txt', '藏品名称', 'goodName'],
   ['txt', '展区', 'region'],
-  ['txt', '具体位置', 'siteLoc'],
+  ['txt', '具体位置', 'address'],
   ['select', '展览状态', 'status', selectObj['展览状态']]
 ]