index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. import React, {
  2. useCallback,
  3. useEffect,
  4. useMemo,
  5. useRef,
  6. useState,
  7. } from "react";
  8. import styles from "./index.module.scss";
  9. import { Button, Cascader, Input, Popconfirm, Select, Table } from "antd";
  10. import { useDispatch, useSelector } from "react-redux";
  11. import { A2FromDataType, options1 } from "./data";
  12. import {
  13. A2_APIgetCity,
  14. A2_APIgetlist,
  15. A2_APIgetlistDerive,
  16. A2_APIremoves,
  17. } from "@/store/action/A2Psychz";
  18. import { RootState } from "@/store";
  19. import { A2tableType } from "@/types";
  20. import { MessageFu } from "@/utils/message";
  21. import { A1addType } from "../A1Camera/data";
  22. import AddPsychz from "./AddPsychz";
  23. import dayjs from "dayjs";
  24. import ExportJsonExcel from "js-export-excel";
  25. function A2Psychz() {
  26. // 站址地区的数据-下拉框
  27. const [optionsCity, setOptionsCity] = useState<any>([]);
  28. const getCityFu = useCallback(async () => {
  29. const res = await A2_APIgetCity();
  30. if (res.code === 0) {
  31. const obj = res.data;
  32. const arr = [];
  33. for (const k in obj) {
  34. const temp1: any = {
  35. value: k,
  36. label: k,
  37. children: [],
  38. };
  39. const children1Obj = Reflect.get(obj, k);
  40. for (const k2 in children1Obj) {
  41. const children2Arr = Reflect.get(children1Obj, k2);
  42. const objTemp = {
  43. value: k2,
  44. label: k2,
  45. children: children2Arr.map((v2: any) => ({
  46. value: v2.region,
  47. label: v2.region,
  48. })),
  49. };
  50. temp1.children.push(objTemp);
  51. }
  52. arr.push(temp1);
  53. }
  54. setOptionsCity(arr);
  55. // console.log(123, res);
  56. }
  57. }, []);
  58. useEffect(() => {
  59. getCityFu();
  60. }, [getCityFu]);
  61. const dispatch = useDispatch();
  62. // 筛选和分页
  63. const [tableSelect, setTableSelect] = useState<A2FromDataType>({
  64. siteArr: undefined,
  65. province: "",
  66. city: "",
  67. region: "",
  68. searchKey: "",
  69. pmUser: "",
  70. typeIn: "",
  71. pageSize: 10,
  72. pageNum: 1,
  73. });
  74. const tableSelectRef = useRef({} as A2FromDataType);
  75. useEffect(() => {
  76. tableSelectRef.current = { ...tableSelect };
  77. }, [tableSelect]);
  78. // 点击搜索的 时间戳
  79. const [timeKey, setTimeKey] = useState(-1);
  80. // 点击搜索
  81. const clickSearch = useCallback(() => {
  82. setTableSelect({ ...tableSelect, pageNum: 1 });
  83. setTimeout(() => {
  84. setTimeKey(Date.now());
  85. }, 50);
  86. }, [tableSelect]);
  87. // 发送接口的函数
  88. const getListFu = useCallback(() => {
  89. const objTemp: any = {};
  90. if (tableSelectRef.current.siteArr) {
  91. const temp = tableSelectRef.current.siteArr;
  92. objTemp.province = temp[0] || "";
  93. objTemp.city = temp[1] || "";
  94. objTemp.region = temp[2] || "";
  95. }
  96. const obj = {
  97. ...tableSelectRef.current,
  98. ...objTemp,
  99. };
  100. dispatch(A2_APIgetlist(obj));
  101. }, [dispatch]);
  102. useEffect(() => {
  103. getListFu();
  104. }, [getListFu, timeKey]);
  105. // 输入框的改变
  106. const txtChangeFu = useCallback(
  107. (txt: string, key: "pmUser" | "searchKey") => {
  108. setTableSelect({ ...tableSelect, [key]: txt });
  109. },
  110. [tableSelect]
  111. );
  112. // 点击重置
  113. const [inputKey, setInputKey] = useState(1);
  114. const resetSelectFu = useCallback(() => {
  115. // 把2个输入框和时间选择器清空
  116. setInputKey(Date.now());
  117. setTableSelect({
  118. siteArr: undefined,
  119. province: "",
  120. city: "",
  121. region: "",
  122. searchKey: "",
  123. pmUser: "",
  124. typeIn: "",
  125. pageSize: 10,
  126. pageNum: 1,
  127. });
  128. setTimeout(() => {
  129. setTimeKey(Date.now());
  130. }, 50);
  131. }, []);
  132. // 从仓库获取列表
  133. const A2TableList = useSelector(
  134. (state: RootState) => state.A2Psychz.A2TableList
  135. );
  136. // 页码变化
  137. const paginationChange = useCallback(
  138. () => (pageNum: number, pageSize: number) => {
  139. setTableSelect({ ...tableSelect, pageNum, pageSize });
  140. setTimeout(() => {
  141. setTimeKey(Date.now());
  142. }, 50);
  143. },
  144. [tableSelect]
  145. );
  146. // 点击删除
  147. const delByIdFu = useCallback(
  148. async (id: number) => {
  149. const res = await A2_APIremoves(id);
  150. if (res.code === 0) {
  151. MessageFu.success("删除成功!");
  152. getListFu();
  153. getCityFu();
  154. }
  155. },
  156. [getCityFu, getListFu]
  157. );
  158. const columns = useMemo(() => {
  159. return [
  160. {
  161. title: "站址地区",
  162. render: (item: A2tableType) =>
  163. !item.province && !item.city && !item.region
  164. ? "(空)"
  165. : `${item.province}-${item.city}-${item.region}`,
  166. },
  167. {
  168. title: "详细地址",
  169. render: (item: A2tableType) =>
  170. item.address ? (
  171. item.address.length >= 25 ? (
  172. <span style={{ cursor: "pointer" }} title={item.address}>
  173. {item.address.substring(0, 25) + "..."}
  174. </span>
  175. ) : (
  176. item.address
  177. )
  178. ) : (
  179. "(空)"
  180. ),
  181. },
  182. {
  183. title: "站址名称",
  184. render: (item: A2tableType) => item.name || "(空)",
  185. },
  186. {
  187. title: "站址编号",
  188. render: (item: A2tableType) => item.siteNum || "(空)",
  189. },
  190. {
  191. title: "机房编码",
  192. dataIndex: "roomNum",
  193. },
  194. {
  195. title: "项目经理",
  196. render: (item: A2tableType) => {
  197. if (item.pmUserId === 1) return "管理员";
  198. else {
  199. return item.pmName || "(空)";
  200. }
  201. },
  202. },
  203. {
  204. title: "最近编辑时间",
  205. dataIndex: "updateTime",
  206. },
  207. {
  208. title: "录入方式",
  209. render: (item: A2tableType) =>
  210. item.typeIn === "pc"
  211. ? "系统"
  212. : item.typeIn === "app-scan"
  213. ? "移动端扫码"
  214. : "移动端手工",
  215. },
  216. {
  217. title: "操作",
  218. render: (item: A2tableType) => (
  219. <>
  220. <Button
  221. size="small"
  222. type="text"
  223. onClick={() => setOpenInfo({ id: item.id, txt: "编辑" })}
  224. >
  225. 编辑
  226. </Button>
  227. <Popconfirm
  228. title="删除后无法恢复,是否删除?"
  229. okText="删除"
  230. cancelText="取消"
  231. onConfirm={() => delByIdFu(item.id)}
  232. okButtonProps={{ loading: false }}
  233. >
  234. <Button size="small" type="text" danger>
  235. 删除
  236. </Button>
  237. </Popconfirm>
  238. </>
  239. ),
  240. },
  241. ];
  242. }, [delByIdFu]);
  243. const [openInfo, setOpenInfo] = useState<A1addType>({ id: 0, txt: "" });
  244. // 点击导出
  245. const deriveFu = useCallback(async () => {
  246. if (A2TableList.list.length === 0)
  247. return MessageFu.warning("当前搜索条件没有数据!");
  248. const name = "机房管理" + dayjs(new Date()).format("YYYY-MM-DD HH:mm");
  249. const objTemp: any = {};
  250. if (tableSelectRef.current.siteArr) {
  251. const temp = tableSelectRef.current.siteArr;
  252. objTemp.province = temp[0] || "";
  253. objTemp.city = temp[1] || "";
  254. objTemp.region = temp[2] || "";
  255. }
  256. const res = await A2_APIgetlistDerive({
  257. ...tableSelectRef.current,
  258. ...objTemp,
  259. pageNum: 1,
  260. pageSize: 99999,
  261. });
  262. if (res.code === 0) {
  263. if (res.data.records.length <= 0)
  264. return MessageFu.warning("当前搜索条件没有数据!");
  265. const option = {
  266. fileName: name,
  267. datas: [
  268. {
  269. sheetData: res.data.records.map((v: A2tableType) => ({
  270. ...v,
  271. myCity:
  272. !v.province && !v.city && !v.region
  273. ? "(空)"
  274. : `${v.province}-${v.city}-${v.region}`,
  275. address: v.address || "(空)",
  276. name: v.name || "(空)",
  277. siteNum: v.siteNum || "(空)",
  278. pmName: v.pmUserId === 1 ? "管理员" : v.pmName || "(空)",
  279. typeIn:
  280. v.typeIn === "pc"
  281. ? "系统"
  282. : v.typeIn === "app-scan"
  283. ? "移动端扫码"
  284. : "移动端手工",
  285. })),
  286. sheetName: name,
  287. sheetFilter: [
  288. "myCity",
  289. "address",
  290. "name",
  291. "siteNum",
  292. "roomNum",
  293. "pmName",
  294. "updateTime",
  295. "typeIn",
  296. ],
  297. sheetHeader: [
  298. "站址地区",
  299. "详细地址",
  300. "站址名称",
  301. "站址编号",
  302. "机房编码",
  303. "项目经理",
  304. "最近编辑时间",
  305. "录入方式",
  306. ],
  307. columnWidths: [10, 10, 10, 10, 10, 10, 10, 10],
  308. },
  309. ],
  310. };
  311. const toExcel = new ExportJsonExcel(option); //new
  312. toExcel.saveExcel(); //保存
  313. }
  314. }, [A2TableList.list.length]);
  315. return (
  316. <div className={styles.A2Psychz}>
  317. <div className="pageTitle">
  318. {openInfo.txt === "新增"
  319. ? "新增机房"
  320. : openInfo.txt === "编辑"
  321. ? "编辑机房"
  322. : "机房管理"}
  323. </div>
  324. {/* 顶部筛选 */}
  325. <div className="A2top">
  326. {/* 左侧输入框 */}
  327. <div className="A2top1">
  328. <div className="A2topRow">
  329. <span>站址地区:</span>
  330. <Cascader
  331. changeOnSelect
  332. style={{ width: 240 }}
  333. options={optionsCity}
  334. value={tableSelect.siteArr}
  335. placeholder="全部"
  336. onChange={(e) =>
  337. setTableSelect({
  338. ...tableSelect,
  339. siteArr: e as string[],
  340. })
  341. }
  342. />
  343. </div>
  344. <div className="A2topRow">
  345. <span>搜索项:</span>
  346. <Input
  347. key={inputKey}
  348. maxLength={24}
  349. style={{ width: 322 }}
  350. placeholder="请输入站址名称/站置编号/机房编码,最多24字"
  351. allowClear
  352. onChange={(e) => txtChangeFu(e.target.value, "searchKey")}
  353. />
  354. </div>
  355. </div>
  356. <div className="A2top2">
  357. <div>
  358. <div className="A2topRow">
  359. <span>项目经理:</span>
  360. <Input
  361. key={inputKey}
  362. maxLength={10}
  363. style={{ width: 240 }}
  364. placeholder="请输入姓名,最多10字"
  365. allowClear
  366. onChange={(e) => txtChangeFu(e.target.value, "pmUser")}
  367. />
  368. </div>
  369. <div className="A2topRow">
  370. <span>录入方式:</span>
  371. <Select
  372. style={{ width: 150 }}
  373. value={tableSelect.typeIn}
  374. onChange={(e) => setTableSelect({ ...tableSelect, typeIn: e })}
  375. options={options1}
  376. />
  377. </div>
  378. </div>
  379. {/* 按钮 */}
  380. <div>
  381. <Button onClick={resetSelectFu}>重置</Button>&emsp;
  382. <Button type="primary" onClick={clickSearch}>
  383. 查询
  384. </Button>
  385. &emsp;
  386. <Button
  387. type="primary"
  388. onClick={() => setOpenInfo({ id: -1, txt: "新增" })}
  389. >
  390. 新增
  391. </Button>
  392. &emsp;
  393. <Button type="primary" onClick={deriveFu}>
  394. 导出表格
  395. </Button>
  396. </div>
  397. </div>
  398. </div>
  399. {/* 表格主体 */}
  400. <div className="tableMain">
  401. <Table
  402. scroll={{ y: 578 }}
  403. dataSource={A2TableList.list}
  404. columns={columns}
  405. rowKey="id"
  406. pagination={{
  407. showQuickJumper: true,
  408. position: ["bottomCenter"],
  409. showSizeChanger: true,
  410. current: tableSelect.pageNum,
  411. pageSize: tableSelect.pageSize,
  412. total: A2TableList.total,
  413. onChange: paginationChange(),
  414. }}
  415. />
  416. </div>
  417. {/* 新增和编辑出来的页面 */}
  418. {openInfo.id ? (
  419. <AddPsychz
  420. openInfo={openInfo}
  421. closeFu={() => setOpenInfo({ id: 0, txt: "" })}
  422. upTableFu={() => {
  423. getListFu();
  424. getCityFu();
  425. }}
  426. addTableFu={() => {
  427. resetSelectFu();
  428. getCityFu();
  429. }}
  430. />
  431. ) : null}
  432. {/* 右下角的列表数量 */}
  433. <div className="tableNumBox">
  434. 共 <span>{A2TableList.total}</span> 条数据
  435. </div>
  436. </div>
  437. );
  438. }
  439. const MemoA2Psychz = React.memo(A2Psychz);
  440. export default MemoA2Psychz;