index.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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, Input, Popconfirm, Select, Table } from "antd";
  10. import { A1addType, TableSelectType, options1, options2 } from "./data";
  11. import { useDispatch, useSelector } from "react-redux";
  12. import {
  13. A1_APIgetlist,
  14. A1_APIgetlistDerive,
  15. A1_APIremove,
  16. } from "@/store/action/A1Camera";
  17. import { RootState } from "@/store";
  18. import { A1ListType } from "@/types";
  19. import ExportJsonExcel from "js-export-excel";
  20. import { MessageFu } from "@/utils/message";
  21. import dayjs from "dayjs";
  22. import AddCamera from "./AddCamera";
  23. import LogCamera from "./LogCamera";
  24. function A1Camera() {
  25. const dispatch = useDispatch();
  26. // 筛选和分页
  27. const [tableSelect, setTableSelect] = useState<TableSelectType>({
  28. cameraSn: "",
  29. searchKey: "",
  30. status: "全部",
  31. typeIn: "全部",
  32. pageSize: 10,
  33. pageNum: 1,
  34. });
  35. const tableSelectRef = useRef({} as TableSelectType);
  36. useEffect(() => {
  37. tableSelectRef.current = { ...tableSelect };
  38. }, [tableSelect]);
  39. // 输入框的改变
  40. const txtChangeFu = useCallback(
  41. (txt: string, key: "cameraSn" | "searchKey") => {
  42. setTableSelect({ ...tableSelect, [key]: txt });
  43. },
  44. [tableSelect]
  45. );
  46. // 点击搜索的 时间戳
  47. const [timeKey, setTimeKey] = useState(-1);
  48. // 点击搜索
  49. const clickSearch = useCallback(() => {
  50. setTableSelect({ ...tableSelect, pageNum: 1 });
  51. setTimeout(() => {
  52. setTimeKey(Date.now());
  53. }, 50);
  54. }, [tableSelect]);
  55. // 发送接口的函数
  56. const getListFu = useCallback(() => {
  57. const obj = {
  58. ...tableSelectRef.current,
  59. status:
  60. tableSelectRef.current.status === "全部"
  61. ? ""
  62. : tableSelectRef.current.status,
  63. typeIn:
  64. tableSelectRef.current.typeIn === "全部"
  65. ? ""
  66. : tableSelectRef.current.typeIn,
  67. };
  68. dispatch(A1_APIgetlist(obj));
  69. }, [dispatch]);
  70. useEffect(() => {
  71. getListFu();
  72. }, [getListFu, timeKey]);
  73. // 从仓库获取列表
  74. const A1TableList = useSelector(
  75. (state: RootState) => state.A1Camera.A1TableList
  76. );
  77. // 页码变化
  78. const paginationChange = useCallback(
  79. () => (pageNum: number, pageSize: number) => {
  80. setTableSelect({ ...tableSelect, pageNum, pageSize });
  81. setTimeout(() => {
  82. setTimeKey(Date.now());
  83. }, 50);
  84. },
  85. [tableSelect]
  86. );
  87. // 点击删除
  88. const delByIdFu = useCallback(
  89. async (id: number) => {
  90. const res = await A1_APIremove(id);
  91. if (res.code === 0) {
  92. MessageFu.success("删除成功!");
  93. getListFu();
  94. }
  95. },
  96. [getListFu]
  97. );
  98. // 点击导出
  99. const deriveFu = useCallback(async () => {
  100. if (A1TableList.list.length === 0)
  101. return MessageFu.warning("当前搜索条件没有数据!");
  102. const name = "相机管理" + dayjs(new Date()).format("YYYY-MM-DD HH:mm");
  103. const res = await A1_APIgetlistDerive({
  104. ...tableSelect,
  105. status: tableSelect.status === "全部" ? "" : tableSelect.status,
  106. typeIn: tableSelect.typeIn === "全部" ? "" : tableSelect.typeIn,
  107. pageNum: 1,
  108. pageSize: 99999,
  109. });
  110. if (res.code === 0) {
  111. if (res.data.records.length <= 0)
  112. return MessageFu.warning("当前搜索条件没有数据!");
  113. const option = {
  114. fileName: name,
  115. datas: [
  116. {
  117. sheetData: res.data.records.map((v: A1ListType) => ({
  118. ...v,
  119. typeIn: v.typeIn === "pc" ? "系统" : "移动端",
  120. remark: v.remark || "(空)",
  121. pmName: v.id === 1 ? "管理员" : v.pmName || "(空)",
  122. })),
  123. sheetName: name,
  124. sheetFilter: [
  125. "cameraSn",
  126. "pmName",
  127. "status",
  128. "typeIn",
  129. "updateTime",
  130. "remark",
  131. ],
  132. sheetHeader: [
  133. "相机SN码",
  134. "项目经理",
  135. "相机工况",
  136. "录入方式",
  137. "最近编辑时间",
  138. "备注",
  139. ],
  140. columnWidths: [10, 10, 10, 10, 10, 20],
  141. },
  142. ],
  143. };
  144. const toExcel = new ExportJsonExcel(option); //new
  145. toExcel.saveExcel(); //保存
  146. }
  147. }, [A1TableList.list.length, tableSelect]);
  148. const columns = useMemo(() => {
  149. return [
  150. {
  151. title: "相机SN码",
  152. dataIndex: "cameraSn",
  153. },
  154. {
  155. title: "项目经理",
  156. render: (item: A1ListType) => {
  157. if (item.id === 1) return "管理员";
  158. else {
  159. return item.pmName || "(空)";
  160. }
  161. },
  162. },
  163. {
  164. title: "相机工况",
  165. dataIndex: "status",
  166. },
  167. {
  168. title: "录入方式",
  169. render: (item: A1ListType) =>
  170. item.typeIn === "pc" ? "系统" : "移动端",
  171. },
  172. {
  173. title: "最近编辑时间",
  174. dataIndex: "updateTime",
  175. },
  176. {
  177. title: "备注",
  178. render: (item: A1ListType) =>
  179. item.remark ? (
  180. item.remark.length >= 25 ? (
  181. <span style={{ cursor: "pointer" }} title={item.remark}>
  182. {item.remark.substring(0, 25) + "..."}
  183. </span>
  184. ) : (
  185. item.remark
  186. )
  187. ) : (
  188. "(空)"
  189. ),
  190. },
  191. {
  192. title: "操作",
  193. render: (item: A1ListType) => (
  194. <>
  195. <Button
  196. size="small"
  197. type="text"
  198. onClick={() => setLogSn(item.cameraSn)}
  199. >
  200. 领用记录
  201. </Button>
  202. <Button
  203. size="small"
  204. type="text"
  205. onClick={() => setOpenInfo({ id: item.id, txt: "编辑" })}
  206. >
  207. 编辑
  208. </Button>
  209. <Popconfirm
  210. title="删除后无法恢复,是否删除?"
  211. okText="删除"
  212. cancelText="取消"
  213. onConfirm={() => delByIdFu(item.id)}
  214. okButtonProps={{ loading: false }}
  215. >
  216. <Button size="small" type="text" danger>
  217. 删除
  218. </Button>
  219. </Popconfirm>
  220. </>
  221. ),
  222. },
  223. ];
  224. }, [delByIdFu]);
  225. // 点击重置
  226. const [inputKey, setInputKey] = useState(1);
  227. const resetSelectFu = useCallback(() => {
  228. // 把2个输入框和时间选择器清空
  229. setInputKey(Date.now());
  230. setTableSelect({
  231. cameraSn: "",
  232. searchKey: "",
  233. status: "全部",
  234. typeIn: "全部",
  235. pageSize: 10,
  236. pageNum: 1,
  237. });
  238. setTimeout(() => {
  239. setTimeKey(Date.now());
  240. }, 50);
  241. }, []);
  242. // 点击新增和编辑的数据
  243. const [openInfo, setOpenInfo] = useState<A1addType>({ id: 0, txt: "" });
  244. // 左上角的 title
  245. const leftTitle = useMemo(() => {
  246. const obj = {
  247. "": "相机管理",
  248. 新增: "新增相机",
  249. 编辑: "编辑相机",
  250. };
  251. return obj[openInfo.txt];
  252. }, [openInfo.txt]);
  253. // 点击 领用记录
  254. const [logSn, setLogSn] = useState("");
  255. return (
  256. <div className={styles.A1Camera}>
  257. <div className="pageTitle">
  258. {leftTitle}
  259. {logSn ? " - 领用记录" : ""}
  260. </div>
  261. {/* 顶部筛选 */}
  262. <div className="A1top">
  263. {/* 左侧输入框 */}
  264. <div className="A1top1">
  265. <div className="A1topRow">
  266. <span>SN码:</span>
  267. <Input
  268. key={inputKey}
  269. maxLength={10}
  270. style={{ width: 190 }}
  271. placeholder="请输入SN码,最多10字"
  272. allowClear
  273. onChange={(e) => txtChangeFu(e.target.value, "cameraSn")}
  274. />
  275. </div>
  276. <div className="A1topRow">
  277. <span>项目经理:</span>
  278. <Input
  279. key={inputKey}
  280. maxLength={10}
  281. style={{ width: 190 }}
  282. placeholder="请输入姓名,最多10字"
  283. allowClear
  284. onChange={(e) => txtChangeFu(e.target.value, "searchKey")}
  285. />
  286. </div>
  287. <div className="A1topRow">
  288. <span>相机工况:</span>
  289. <Select
  290. style={{ width: 150 }}
  291. value={tableSelect.status}
  292. onChange={(e) => setTableSelect({ ...tableSelect, status: e })}
  293. options={options1}
  294. />
  295. </div>
  296. <div className="A1topRow">
  297. <span>录入方式:</span>
  298. <Select
  299. style={{ width: 150 }}
  300. value={tableSelect.typeIn}
  301. onChange={(e) => setTableSelect({ ...tableSelect, typeIn: e })}
  302. options={options2}
  303. />
  304. </div>
  305. </div>
  306. {/* 右侧按钮 */}
  307. <div className="A1top2">
  308. <Button onClick={resetSelectFu}>重置</Button>&emsp;
  309. <Button type="primary" onClick={clickSearch}>
  310. 查询
  311. </Button>
  312. &emsp;
  313. <Button
  314. type="primary"
  315. onClick={() => setOpenInfo({ id: -1, txt: "新增" })}
  316. >
  317. 新增
  318. </Button>
  319. &emsp;
  320. <Button type="primary" onClick={deriveFu}>
  321. 导出表格
  322. </Button>
  323. </div>
  324. </div>
  325. {/* 表格主体 */}
  326. <div className="tableMain">
  327. <Table
  328. scroll={{ y: 625 }}
  329. dataSource={A1TableList.list}
  330. columns={columns}
  331. rowKey="id"
  332. pagination={{
  333. showQuickJumper: true,
  334. position: ["bottomCenter"],
  335. showSizeChanger: true,
  336. current: tableSelect.pageNum,
  337. pageSize: tableSelect.pageSize,
  338. total: A1TableList.total,
  339. onChange: paginationChange(),
  340. }}
  341. />
  342. </div>
  343. {/* 新增 编辑 查看 出来的页面 */}
  344. {openInfo.id ? (
  345. <AddCamera
  346. openInfo={openInfo}
  347. closeFu={() => setOpenInfo({ id: 0, txt: "" })}
  348. upTableFu={getListFu}
  349. addTableFu={resetSelectFu}
  350. />
  351. ) : null}
  352. {/* 领用记录 */}
  353. {logSn ? <LogCamera logSn={logSn} closeFu={() => setLogSn("")} /> : null}
  354. {/* 右下角的列表数量 */}
  355. <div className="tableNumBox">
  356. 共 <span>{A1TableList.total}</span> 条数据
  357. </div>
  358. </div>
  359. );
  360. }
  361. const MemoA1Camera = React.memo(A1Camera);
  362. export default MemoA1Camera;