lanxin 2 روز پیش
والد
کامیت
f122d87340

+ 2 - 1
package.json

@@ -65,8 +65,9 @@
   "devDependencies": {
     "@types/history": "^5.0.0",
     "@types/react-router-dom": "^5.3.3",
+    "@types/xlsx": "^0.0.36",
     "customize-cra": "^1.0.0",
     "react-app-rewired": "^2.2.1"
   },
   "homepage": "."
-}
+}

+ 129 - 13
src/pages/Cledger/C1ledger/index.tsx

@@ -1,16 +1,16 @@
-import React, { useMemo } from 'react'
+import React, { useMemo, useState } from 'react'
 import styles from './index.module.scss'
 import { authorityFu } from '@/utils/authority'
-import { selectObj, getDictFu } from '@/utils/dataChange'
+import { selectObj, getDictFu, resJiLianFu } from '@/utils/dataChange'
 import history, { openLink } from '@/utils/history'
 import TableList from '@/pages/Zother/TableList'
 import { useSelector } from 'react-redux'
 import { RootState } from '@/store'
-import { API_getGoodsList } from '@/store/action/Cledger/C1ledger'
+import { API_getGoodsList, API_getGoodsListAll } from '@/store/action/Cledger/C1ledger'
 import { baseFormData } from '@/pages/Zother/data'
 import { goodsSonTableC } from '@/utils/tableData'
-import { Button, Dropdown } from 'antd'
-
+import { Button, Dropdown, Modal, Radio, Checkbox } from 'antd'
+import { exportExcelFile } from '@/utils/xlsxExport'
 const C1topSearch = [
   {
     type: 'input',
@@ -61,13 +61,13 @@ const C1topSearch = [
   },
   {
     type: 'select',
-    key: 'xxx',
+    key: 'siteStatus',
     placeholder: '库存状态',
     options: selectObj['藏品库存状态']
   },
   {
     type: 'select',
-    key: 'xxxx',
+    key: 'siteLoc',
     placeholder: `搜索库房位置`
   }
 ]
@@ -82,10 +82,66 @@ const C1baseFormData = {
 const columnsTempAdd = [
   ...goodsSonTableC(false),
   ['select', '入藏状态', 'status', selectObj['藏品入藏状态']],
-  ['txt', '库存状态', 'xxx'],
-  ['txt', '库房位置', 'xxx']
+  ['txt', '库存状态', 'siteStatus'],
+  ['txt', '库房位置', 'siteLoc']
 ]
 
+const ExportModal = ({
+  open,
+  availableYears,
+  onConfirm,
+  onCancel
+}: {
+  open: boolean
+  availableYears: number[] | string[]
+  onConfirm: (exportType: number, years: number[]) => void
+  onCancel: () => void
+}) => {
+  const [exportValue, setExportValue] = useState<number>(1)
+  const [selectedYears, setSelectedYears] = useState<number[]>([])
+
+  const onExportTypeChange = (e: any) => {
+    setExportValue(e.target.value)
+  }
+
+  return (
+    <Modal
+      title='数据导出'
+      open={open}
+      onOk={() => onConfirm(exportValue, selectedYears)}
+      onCancel={onCancel}
+      okText='导出'
+      cancelText='取消'
+    >
+      <span style={{ marginBottom: 16 }}>导出范围:</span>
+
+      <Radio.Group
+        onChange={onExportTypeChange}
+        value={exportValue}
+        options={[
+          { value: 1, label: '所有年份' },
+          { value: 2, label: '按年份' }
+        ]}
+      />
+
+      {exportValue === 2 && (
+        <div style={{ marginTop: 24 }}>
+          <Checkbox.Group
+            style={{ flexDirection: 'column', gap: '5px' }}
+            options={availableYears.map(year => ({
+              label: `${year}年`,
+              value: year
+            }))}
+            value={selectedYears}
+            onChange={checkedValues => setSelectedYears(checkedValues as number[])}
+          />
+          <div style={{ opacity: '0.5', marginTop: '10px' }}>上述年份为藏品制档日期所在年份</div>
+        </div>
+      )}
+    </Modal>
+  )
+}
+
 function C1ledger() {
   const tableInfo = useSelector((state: RootState) => state.C1ledger.tableInfo)
 
@@ -160,8 +216,62 @@ function C1ledger() {
     }
   }, [])
 
-  const dataExport = () => {
-    console.log('数据导出了')
+  const [allData, setAllData] = useState([])
+  const [isModalOpen, setIsModalOpen] = useState(false)
+  const [availableYears, setAvailableYears] = useState<any>([])
+  const showModal = async () => {
+    setIsModalOpen(true)
+    const res = await API_getGoodsListAll()
+    setAllData(res.data.records)
+    //获取年份信息
+    const years = Array.from(
+      new Set(
+        res.data.records
+          .map((item: any) => item.createTime?.slice(0, 4))
+          .filter(Boolean) as string[]
+      )
+    ).sort((a, b) => Number(b) - Number(a))
+    setAvailableYears(years)
+  }
+
+  const dataExport = async (exportType: number = 1, years: number[] = []) => {
+    // 根据导出范围筛选数据:
+    // exportType === 1:所有年份,不做筛选
+    // exportType === 2:按年份,只保留所选年份的数据
+    const filteredData =
+      exportType === 2 && years.length
+        ? allData.filter((item: any) => {
+            if (!item.createTime) return false
+            const yearStr = item.createTime.slice(0, 4)
+            const yearNum = yearStr
+            return years.includes(yearNum)
+          })
+        : allData
+
+    const listData = filteredData.map((item: any) => {
+      return {
+        藏品登记号: item.num,
+        封面: item.thumb,
+        藏品标签: item.tagDictId,
+        藏品名称: item.name,
+        级别: item.level,
+        类别: resJiLianFu(item.typeDictId),
+        年代: resJiLianFu(item.ageDictId),
+        质地: resJiLianFu(item.textureDictId),
+        完残程度: item.tornLevel,
+        数量: item.pcs,
+        入藏状态: item.status,
+        库存状态: item.siteStatus,
+        库房位置: item.siteLoc
+      }
+    })
+    console.log(years)
+    exportExcelFile(
+      listData,
+      [100, 100, 100, 100, 100, 200, 200, 200, 100, 100, 100, 100, 100],
+      '藏品总账数据'
+    )
+    setIsModalOpen(false)
   }
 
   // 故事管理/藏品总账定制右侧内容
@@ -183,12 +293,18 @@ function C1ledger() {
         <Dropdown menu={{ items: rightBtnOptions['weihu'] }} trigger={['click']}>
           <Button type='primary'>藏品维护</Button>
         </Dropdown>
-        <Button type='primary' onClick={dataExport}>
+        <Button type='primary' onClick={() => console.log(123)}>
           数据导入
         </Button>
-        <Button type='primary' onClick={dataExport}>
+        <Button type='primary' onClick={showModal}>
           数据导出
         </Button>
+        <ExportModal
+          open={isModalOpen}
+          availableYears={availableYears}
+          onConfirm={dataExport}
+          onCancel={() => setIsModalOpen(false)}
+        />
         <Button type='primary' onClick={clickSearch}>
           查询
         </Button>

+ 17 - 5
src/pages/Eculture/E2story/index.tsx

@@ -2,7 +2,7 @@ import React, { useMemo, useCallback } from 'react'
 import styles from './index.module.scss'
 import { useSelector } from 'react-redux'
 import { RootState } from '@/store'
-import { E2_APIgetList, E2_APIdel } from '@/store/action/Eculture/E2story'
+import { E2_APIgetList, E2_APIdel, E2_APIgetListAll } from '@/store/action/Eculture/E2story'
 import { MessageFu } from '@/utils/message'
 import TableList from '@/pages/Zother/TableList'
 import { baseFormData } from '@/pages/Zother/data'
@@ -11,6 +11,7 @@ import { storyTableC } from '@/utils/tableData'
 import { Button } from 'antd'
 import history from '@/utils/history'
 import { useDispatch } from 'react-redux'
+import { exportExcelFile } from '@/utils/xlsxExport'
 
 const E2topSearch = [
   {
@@ -32,10 +33,6 @@ const E2topSearch = [
 
 const D1baseFormData = baseFormData()
 
-const dataExport = () => {
-  console.log('数据导出了')
-}
-
 function D1register() {
   const dispatch = useDispatch()
   // 从仓库拿数据
@@ -56,6 +53,21 @@ function D1register() {
     [getListFu]
   )
 
+  // 数据导出
+  const dataExport = async () => {
+    const allData = await E2_APIgetListAll()
+    const listData = allData.data.records.map((item: any) => {
+      return {
+        故事标题: item.name,
+        关联藏品: item.goodName,
+        藏品标签: item.tagName,
+        录入人: item.creatorName,
+        录入日期: item.createTime
+      }
+    })
+    exportExcelFile(listData, [100, 200, 100, 100, 150], '故事管理数据')
+  }
+
   // 故事管理定制右侧内容
   const storyTableListToprr = ({
     clickSearch,

+ 19 - 0
src/store/action/Cledger/C1ledger.ts

@@ -26,6 +26,25 @@ export const API_getGoodsList = (data: any): any => {
 }
 
 /**
+ * 藏品总账-获取藏品全部数据
+ */
+export const API_getGoodsListAll = () => {
+  return http.post(`cms/good/ledger/page`, {
+    pageSize: 9999,
+    pageNum: 1,
+    businessStartTime: '',
+    businessEndTime: '',
+    searchKey: '',
+    startTime: '',
+    endTime: '',
+    status: '',
+    typeDictId: '',
+    ageDictId: '',
+    textureDictId: ''
+  })
+}
+
+/**
  * 藏品总账-获取藏品列表
  */
 export const API_getGoodsLists = (data: any): any => {

+ 16 - 0
src/store/action/Eculture/E2story.ts

@@ -19,6 +19,22 @@ export const E2_APIgetList = (data: any): any => {
 }
 
 /**
+ * 故事 - 获取全部数据
+ */
+export const E2_APIgetListAll = () => {
+  return http.post('cms/story/page', {
+    pageSize: 9999,
+    pageNum: 1,
+    businessStartTime: '',
+    businessEndTime: '',
+    searchKey: '',
+    startTime: '',
+    endTime: '',
+    status: ''
+  })
+}
+
+/**
  * 故事 - 删除
  */
 export const E2_APIdel = (id: string | string[]) => {

+ 23 - 0
src/utils/xlsxExport.ts

@@ -0,0 +1,23 @@
+import * as xlsx from 'xlsx'
+import { WorkBook } from 'xlsx/types'
+
+export function exportExcelFile(
+  array: any[],
+  width?: number[],
+  fileName = '展馆预约记录',
+  sheetName = '表1'
+) {
+  // 设置列宽或默认150
+  const columnWidths = width
+    ? width.map((w, index) => ({ wpx: w }))
+    : Array(Object.keys(array[0]).length).fill({ wpx: 150 })
+  const jsonWorkSheet = xlsx.utils.json_to_sheet(array)
+  jsonWorkSheet['!cols'] = columnWidths
+  const workBook: WorkBook = {
+    SheetNames: [sheetName],
+    Sheets: {
+      [sheetName]: jsonWorkSheet
+    }
+  }
+  return xlsx.writeFile(workBook, `${fileName}.xlsx`)
+}

+ 20 - 13
yarn.lock

@@ -2513,6 +2513,13 @@
   dependencies:
     "@types/node" "*"
 
+"@types/xlsx@^0.0.36":
+  version "0.0.36"
+  resolved "https://registry.npmmirror.com/@types/xlsx/-/xlsx-0.0.36.tgz#b5062003e5c5374ab4f08fdd3bf69da4d4013af8"
+  integrity sha512-mvfrKiKKMErQzLMF8ElYEH21qxWCZtN59pHhWGmWCWFJStYdMWjkDSAy6mGowFxHXaXZWe5/TW7pBUiWclIVOw==
+  dependencies:
+    xlsx "*"
+
 "@types/yargs-parser@*":
   version "21.0.3"
   resolved "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
@@ -11143,6 +11150,19 @@ ws@^8.13.0:
   resolved "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4"
   integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==
 
+xlsx@*, xlsx@^0.18.5:
+  version "0.18.5"
+  resolved "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0"
+  integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==
+  dependencies:
+    adler-32 "~1.3.0"
+    cfb "~1.2.1"
+    codepage "~1.15.0"
+    crc-32 "~1.2.1"
+    ssf "~0.11.2"
+    wmf "~1.0.1"
+    word "~0.3.0"
+
 xlsx@0.16.3:
   version "0.16.3"
   resolved "https://registry.npmmirror.com/xlsx/-/xlsx-0.16.3.tgz#7a91a75eb939db4961122da6f949b8a8f0c8af1a"
@@ -11158,19 +11178,6 @@ xlsx@0.16.3:
     wmf "~1.0.1"
     word "~0.3.0"
 
-xlsx@^0.18.5:
-  version "0.18.5"
-  resolved "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0"
-  integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==
-  dependencies:
-    adler-32 "~1.3.0"
-    cfb "~1.2.1"
-    codepage "~1.15.0"
-    crc-32 "~1.2.1"
-    ssf "~0.11.2"
-    wmf "~1.0.1"
-    word "~0.3.0"
-
 xml-name-validator@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"