index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. import BreadTit from "@/components/BreadTit";
  2. import { RootState } from "@/store";
  3. import { Button, Input, Pagination, Select, Table } from "antd";
  4. import { useCallback, useEffect, useMemo, useRef, useState } from "react";
  5. import { useDispatch, useSelector } from "react-redux";
  6. import styles from "./index.module.scss";
  7. import { UnorderedListOutlined, AppstoreOutlined } from "@ant-design/icons";
  8. import classNames from "classnames";
  9. import ImageLazy from "@/components/ImageLazy";
  10. import history from "@/utils/history";
  11. import { useLocation } from "react-router-dom";
  12. import dayjs from "dayjs";
  13. import ExportJsonExcel from "js-export-excel";
  14. import { getObject2List } from "@/store/action/object2";
  15. import http from "@/utils/http";
  16. import { Empty } from "antd";
  17. import { obj3InStorage } from "@/utils/dataChange";
  18. import { MessageFu } from "@/utils/message";
  19. const { Option } = Select;
  20. export default function Object2() {
  21. const dispatch = useDispatch();
  22. // 从仓库中获取藏品编号名称下拉数据
  23. const options = useSelector(
  24. (state: RootState) => state.loginStore.selectAll["藏品编号名称"]
  25. );
  26. // 从仓库中获取表格数据(图片展示数据)
  27. const results = useSelector((state: RootState) => state.object2Store.info2);
  28. // 封装发送请求的函数
  29. const getList = () => {
  30. const data = {
  31. ...tableSelect,
  32. pageNum: pageNumRef.current,
  33. searchType: value,
  34. };
  35. dispatch(getObject2List(data));
  36. // console.log("------", data);
  37. };
  38. // 获取地址栏参数
  39. const location = useLocation();
  40. // 如果有参数 根据参数页码在次发送请求
  41. useEffect(() => {
  42. const urlParam = location.state || {};
  43. if (urlParam.k && urlParam.k !== "1")
  44. setTableSelect({ ...tableSelect, pageNum: Number(urlParam.k) });
  45. // eslint-disable-next-line react-hooks/exhaustive-deps
  46. }, [location]);
  47. // 筛选表格的数据
  48. const [tableSelect, setTableSelect] = useState<any>({
  49. dictNum: null,
  50. searchKey: "",
  51. pageSize: 10,
  52. pageNum: 1,
  53. });
  54. // 图片页面和列表页面的切换
  55. const [cutShow, setCutShow] = useState("cutShow1");
  56. // 当前图片查看或者表格查看数据统一
  57. const cutShowRef = useRef("1");
  58. // 进页面如果 d的值为2 切换到表格显示
  59. useEffect(() => {
  60. const urlParam = location.state || {};
  61. if (urlParam.d && urlParam.d === "2") {
  62. cutShowRef.current = "2";
  63. window.setTimeout(() => {
  64. setCutShow("cutShow2");
  65. }, 20);
  66. }
  67. }, [location.state]);
  68. const cutShowFu = useCallback((val: string) => {
  69. cutShowRef.current = val === "cutShow1" ? "1" : "2";
  70. setCutShow(val);
  71. }, []);
  72. // 当前页码统一
  73. const pageNumRef = useRef(1);
  74. useEffect(() => {
  75. pageNumRef.current = tableSelect.pageNum;
  76. }, [tableSelect.pageNum]);
  77. // 防止返回的时候发送了2次请求来对应页码
  78. const getListRef = useRef(-1);
  79. useEffect(() => {
  80. clearTimeout(getListRef.current);
  81. getListRef.current = window.setTimeout(() => {
  82. getList();
  83. }, 100);
  84. // eslint-disable-next-line react-hooks/exhaustive-deps
  85. }, [tableSelect]);
  86. // 藏品来源下拉框改变
  87. const handleChange = (val: string) => {
  88. setTableSelect({ ...tableSelect, dictNum: val, pageNum: 1 });
  89. };
  90. // 搜索输入框下拉
  91. const [value, setValue] = useState("name");
  92. const valueChangeFu = (val: string) => {
  93. if (tableSelect.searchKey) {
  94. // 根据输入框的值重新发送请求
  95. setTableSelect({ ...tableSelect, searchType: val });
  96. }
  97. setValue(val);
  98. };
  99. const nameTime = useRef(-1);
  100. const nameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  101. clearTimeout(nameTime.current);
  102. nameTime.current = window.setTimeout(() => {
  103. setTableSelect({ ...tableSelect, searchKey: e.target.value, pageNum: 1 });
  104. }, 500);
  105. };
  106. // 关于表格的数据
  107. const paginationChange = (pageNum: number, pageSize: number) => {
  108. setTableSelect({ ...tableSelect, pageNum, pageSize });
  109. };
  110. const columns = useMemo(() => {
  111. return [
  112. {
  113. title: "缩略图",
  114. render: (item: any) => (
  115. <ImageLazy width={120} height={70} src={item.thumb} />
  116. ),
  117. },
  118. {
  119. title: "藏品编号名称",
  120. dataIndex: "dictNum",
  121. },
  122. {
  123. title: "藏品编号",
  124. render: (item: any) => (item.num ? item.num : "-"),
  125. },
  126. {
  127. title: "藏品名称",
  128. dataIndex: "name",
  129. },
  130. {
  131. title: "年代",
  132. dataIndex: "dictAge",
  133. },
  134. {
  135. title: "质地",
  136. dataIndex: "dictTexture",
  137. },
  138. {
  139. title: "展示状态",
  140. render: (item: any) => (item.display ? "是" : "否"),
  141. },
  142. {
  143. title: "状态",
  144. dataIndex: "storageStatusTxt",
  145. },
  146. {
  147. title: "操作",
  148. render: (item: any) => (
  149. <>
  150. <Button
  151. type="text"
  152. danger
  153. onClick={() =>
  154. history.push(
  155. `/object/2/look?k=${pageNumRef.current}&d=${cutShowRef.current}&id=${item.id}`
  156. )
  157. }
  158. >
  159. 查看
  160. </Button>
  161. </>
  162. ),
  163. },
  164. ];
  165. // eslint-disable-next-line react-hooks/exhaustive-deps
  166. }, []);
  167. // 点击导出
  168. const deriveFu = useCallback(async () => {
  169. if (results.list.length === 0)
  170. return MessageFu.warning("当前搜索条件没有数据!");
  171. const name = dayjs(new Date()).format("YYYYMMDDHHmmss");
  172. const res = await http.post("cms/ledger/pageList", {
  173. ...tableSelect,
  174. pageSize: 9999,
  175. searchType: value,
  176. });
  177. const sheetData = res.data.records;
  178. sheetData.forEach((v: any) => {
  179. if (v.size && v.size.length) {
  180. const sizeArr = v.size.split(",");
  181. v.sizeRes = `(通长)${sizeArr[0]}cm;(通宽)${sizeArr[1]}cm;(通高)${sizeArr[2]}cm`;
  182. }
  183. v.qualityRes = "-";
  184. if (v.quality && v.quality.length) {
  185. const qualityArr = v.quality.split(",");
  186. v.qualityRes = qualityArr[0] + qualityArr[1];
  187. }
  188. v.namePrimitive = v.namePrimitive ? v.namePrimitive : "-";
  189. v.num = v.num ? v.num : "-";
  190. v.ageSpecific = v.ageSpecific ? v.ageSpecific : "-";
  191. v.repair = v.repair ? v.repair : "-";
  192. v.checkInYear = v.checkInYear ? v.checkInYear : "-";
  193. v.author = v.author ? v.author : "-";
  194. v.vision = v.vision ? v.vision : "-";
  195. v.onFile = v.onFile ? v.onFile : "-";
  196. v.description = v.description ? v.description : "-";
  197. v.storageAncestorName = v.storageAncestor
  198. ? obj3InStorage(v.storageAncestor)
  199. : "-";
  200. v.outLocation = v.outLocation ? v.outLocation : "-";
  201. v.display = v.display ? "是" : "否";
  202. });
  203. const option = {
  204. fileName: name,
  205. datas: [
  206. {
  207. sheetData,
  208. sheetName: name,
  209. sheetFilter: [
  210. "name",
  211. "namePrimitive",
  212. "dictNum",
  213. "num",
  214. "dictAge",
  215. "dictTexture",
  216. "ageSpecific",
  217. "dictGoodType",
  218. "pcs",
  219. "dictLevel",
  220. "sizeRes",
  221. "sizeSpecific",
  222. "dictQualityScope",
  223. "qualityRes",
  224. "complete",
  225. "repair",
  226. "dictCheckInScope",
  227. "checkInYear",
  228. "author",
  229. "vision",
  230. "onFile",
  231. "description",
  232. "storageAncestorName",
  233. "outLocation",
  234. "display",
  235. ],
  236. sheetHeader: [
  237. "藏品名称",
  238. "原名",
  239. "藏品编号名称",
  240. "藏品编号",
  241. "年代",
  242. "文物质地",
  243. "具体年代",
  244. "文物类别",
  245. "实际数量",
  246. "文物级别",
  247. "外形尺寸",
  248. "具体尺寸",
  249. "质量范围",
  250. "具体质量",
  251. "完残程度",
  252. "保存状态",
  253. "入藏时间范围",
  254. "入藏年度",
  255. "著者",
  256. "版本",
  257. "存卷",
  258. "来源说明",
  259. "入库位置",
  260. "出库位置",
  261. "展示状态",
  262. ],
  263. columnWidths: [
  264. 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  265. 10, 10, 10, 10, 10, 10, 10,
  266. ],
  267. },
  268. ],
  269. };
  270. const toExcel = new ExportJsonExcel(option); //new
  271. toExcel.saveExcel(); //保存
  272. }, [results.list, tableSelect, value]);
  273. return (
  274. <div className={styles.Object2}>
  275. <div className="breadTit">
  276. <BreadTit>
  277. <div className="breadTitRow active">藏品总账</div>
  278. </BreadTit>
  279. </div>
  280. <div className="objectSonMain">
  281. {/* 顶部搜索和筛选 */}
  282. <div className="searchBox">
  283. <div className="row">
  284. <span>藏品编号名称:</span>
  285. <Select
  286. placeholder="请选择"
  287. allowClear
  288. style={{ width: 150 }}
  289. value={tableSelect.dictNum}
  290. onChange={handleChange}
  291. options={options.map((v: any) => ({
  292. label: v.name,
  293. value: v.name,
  294. }))}
  295. />
  296. </div>
  297. <div className="row">
  298. <span>搜索:</span>
  299. <Select
  300. style={{ width: 100 }}
  301. value={value}
  302. onChange={(val) => valueChangeFu(val)}
  303. >
  304. <Option value="name">藏品名称</Option>
  305. <Option value="age">藏品年代</Option>
  306. <Option value="texture">藏品质地</Option>
  307. </Select>
  308. <Input
  309. maxLength={10}
  310. style={{ width: 150 }}
  311. placeholder="请输入"
  312. allowClear
  313. onChange={(e) => nameChange(e)}
  314. />
  315. </div>
  316. <div className="row">
  317. <Button onClick={deriveFu}>导出</Button>
  318. </div>
  319. <div className="row">
  320. <div
  321. onClick={() => cutShowFu("cutShow1")}
  322. className={classNames(
  323. "cutShow",
  324. cutShow === "cutShow1" ? "active" : ""
  325. )}
  326. >
  327. <AppstoreOutlined />
  328. </div>
  329. <div
  330. onClick={() => cutShowFu("cutShow2")}
  331. className={classNames(
  332. "cutShow",
  333. "cutShow2",
  334. cutShow === "cutShow2" ? "active" : ""
  335. )}
  336. >
  337. <UnorderedListOutlined />
  338. </div>
  339. </div>
  340. </div>
  341. {/* 图片展示列表 */}
  342. <div className="imgList" hidden={cutShow !== "cutShow1"}>
  343. {results.list.length ? (
  344. results.list.map((v: any) => (
  345. <div
  346. title={v.name}
  347. onClick={() =>
  348. history.push(
  349. `/object/2/look?k=${pageNumRef.current}&d=${cutShowRef.current}&id=${v.id}`
  350. )
  351. }
  352. key={v.id}
  353. className="imgListRow"
  354. >
  355. <ImageLazy
  356. noLook={true}
  357. width={236}
  358. height={200}
  359. src={v.thumb}
  360. />
  361. <p>{v.name}</p>
  362. </div>
  363. ))
  364. ) : (
  365. <div className="imgListNone">
  366. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  367. </div>
  368. )}
  369. {}
  370. </div>
  371. {/* 表格展示列表 */}
  372. <div className="tableBox" hidden={cutShow !== "cutShow2"}>
  373. <Table
  374. scroll={{ y: 450 }}
  375. dataSource={results.list}
  376. columns={columns}
  377. rowKey="id"
  378. pagination={false}
  379. />
  380. </div>
  381. {/* 从表格里面拆出来的分页 */}
  382. <div className="pageBox" hidden={!results.total}>
  383. <Pagination
  384. showQuickJumper
  385. showSizeChanger
  386. current={tableSelect.pageNum}
  387. pageSize={tableSelect.pageSize}
  388. onChange={paginationChange}
  389. total={results.total}
  390. />
  391. </div>
  392. </div>
  393. </div>
  394. );
  395. }