complex.jsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. import React, {
  2. useRef,
  3. useState,
  4. useEffect,
  5. forwardRef,
  6. useImperativeHandle,
  7. } from "react";
  8. import { Form, Input, Select, message } from "antd";
  9. import { Modal, Button, Table, Radio } from "antd";
  10. import Formular from "./components/Formular";
  11. import API2 from "../../../api/alarm";
  12. import styles from "./complex.module.less";
  13. import oneNode from "./components/oneNode";
  14. import { useMemoizedFn } from "ahooks";
  15. const { Search } = Input;
  16. function TranslateText(arr) {
  17. const dtLanguage = localStorage.getItem("dtLanguage");
  18. if (!Array.isArray(arr)) {
  19. return arr;
  20. }
  21. if (arr.length < 2 && arr.length > 0) {
  22. return arr?.[0];
  23. }
  24. if (dtLanguage === "en") {
  25. return arr?.[1];
  26. }
  27. return arr?.[0];
  28. }
  29. const Complex = (props, ref) => {
  30. const { editId, groupList = [], showList } = props;
  31. const [form] = Form.useForm();
  32. const formuRef = useRef();
  33. // const [alarmId, setAlarmId] = useState(searchParams.get('alarm_id'))
  34. // const [token, setToken] = useState(searchParams.get('token'))
  35. // const [apiUrl, setApiUrl] = useState(decodeURIComponent(searchParams.get('api_url')) + '/')
  36. const [data, setData] = useState();
  37. const [loading, setLoading] = useState(false);
  38. const [deviceList, setDeviceList] = useState([]);
  39. const [paginationProps, setPaginationProps] = useState({
  40. pageSize: 10,
  41. current: 1,
  42. showTotal: (total) => `共${total}条`,
  43. // showQuickJumper: true,
  44. // showSizeChanger:true,
  45. // size:'Large',
  46. });
  47. const [alarmId, setAlarmId] = useState(null);
  48. const [type, setType] = useState(0);
  49. const [ruleOptions, setRuleOptions] = useState([]);
  50. const handleTableChange = async (pagination) => {
  51. setPaginationProps({ ...pagination, showTotal: (total) => `共${total}条` });
  52. // setCurrentPage(pagination.current);
  53. // setPageSize(pagination.pageSize)
  54. };
  55. useEffect(() => {
  56. onSearch("");
  57. }, []);
  58. useEffect(() => {
  59. async function run() {
  60. if (alarmId && alarmId != -1) {
  61. const { state, data } = await API2.detailAlarm(Number(alarmId));
  62. form.setFieldsValue({
  63. name: data.name,
  64. alarm_level: data.alarm_level,
  65. group_id: data.group_id,
  66. });
  67. formuRef.current.backEndInput(data.formula);
  68. setData(data);
  69. } else {
  70. form.resetFields();
  71. setData(null);
  72. }
  73. }
  74. run();
  75. }, [alarmId]);
  76. const onModalOk = useMemoizedFn(async () => {
  77. if (type === 0) {
  78. props.onConfirm(null);
  79. return;
  80. }
  81. if (alarmId == -1) {
  82. const value = await form.validateFields();
  83. const obj = {
  84. ...value,
  85. formula: formuRef.current.getFinalStr(),
  86. ext_notify_list: [],
  87. is_complex: true,
  88. type: 1,
  89. sub_type: 12,
  90. status: 1,
  91. defer_unit: 2,
  92. };
  93. const { state } = await API2.addRule(obj);
  94. if (state === 0) {
  95. message.success("保存成功");
  96. props.onConfirm();
  97. }
  98. } else {
  99. const value = await form.validateFields();
  100. const obj = {
  101. ...data,
  102. ...value,
  103. formula: formuRef.current.getFinalStr(),
  104. ext_notify_list: [],
  105. };
  106. const { state } = await API2.editRule(obj);
  107. if (state === 0) {
  108. message.success("保存成功");
  109. props.onConfirm(data.id);
  110. }
  111. }
  112. form.resetFields();
  113. props.onConfirm();
  114. });
  115. useImperativeHandle(ref, () => {
  116. return {
  117. ok: onModalOk,
  118. };
  119. });
  120. const symbClick = (e) => {
  121. let innerText = e.target.innerText;
  122. if (innerText === "≥") {
  123. innerText = ">=";
  124. } else if (innerText === "≤") {
  125. innerText = "<=";
  126. } else if (innerText === "&&(and)") {
  127. innerText = "&&";
  128. } else if (innerText === "||(or)") {
  129. innerText = "||";
  130. }
  131. formuRef.current.dtInsertFormular(innerText);
  132. if (innerText === "()") {
  133. //判断为括号则把光标移到括号中间
  134. formuRef.current.moveInTextNode();
  135. }
  136. };
  137. const insertToFomular = (poi) => {
  138. const { point_id, name } = poi;
  139. const res = oneNode(point_id, name);
  140. formuRef.current.dtInsertFormular(res);
  141. };
  142. const columns = [
  143. {
  144. title: TranslateText(["点位编号", "Point id"]),
  145. dataIndex: "point_id",
  146. ellipsis: true,
  147. },
  148. {
  149. title: TranslateText(["点位名称", "Point name"]),
  150. dataIndex: "name",
  151. ellipsis: true,
  152. },
  153. ];
  154. const onSearch = async (v) => {
  155. const res = await API2.searchPoint({
  156. key_word: v ?? "",
  157. count: 50,
  158. type: 1,
  159. no_child: true,
  160. });
  161. if (res.state === 0) {
  162. setDeviceList(res.data || []);
  163. return;
  164. }
  165. setDeviceList([]);
  166. };
  167. const clickTableRow = (record) => {
  168. // child.current.handlePickPoint({name:record.name, point_id:record.point_id})
  169. insertToFomular({ name: record.name, point_id: record.point_id });
  170. };
  171. const onModalCancel = () => {
  172. props.onConfirm();
  173. form.resetFields();
  174. };
  175. useEffect(() => {
  176. function run() {
  177. if (editId && editId !== -1) {
  178. setAlarmId(editId);
  179. if (showList) {
  180. setType(1);
  181. }
  182. } else if (showList) {
  183. setType(0);
  184. }
  185. }
  186. run();
  187. }, [editId, showList]);
  188. useEffect(() => {
  189. async function run() {
  190. if (showList) {
  191. const res = await API2.getRuleList();
  192. setRuleOptions(
  193. res?.data?.rules?.map((item) => ({
  194. label: item.name,
  195. value: item.id,
  196. }))
  197. );
  198. }
  199. }
  200. run();
  201. }, [showList]);
  202. useEffect(() => {
  203. if (type === 2) {
  204. setAlarmId(-1);
  205. } else if (alarmId === -1 && type !== 2) {
  206. setAlarmId(null);
  207. }
  208. }, [type, alarmId]);
  209. return (
  210. <div className={styles.wrapper}>
  211. <div className="main">
  212. <div className="left">
  213. <Form
  214. name="basic"
  215. autoComplete="off"
  216. form={form}
  217. requiredMark={false}
  218. labelAlign="right"
  219. colon={false}
  220. labelCol={{
  221. span: 4,
  222. }}
  223. wrapperCol={{
  224. span: 15,
  225. }}
  226. >
  227. {showList && (
  228. <>
  229. <Form.Item label="类型">
  230. <Radio.Group
  231. value={type}
  232. onChange={(e) => setType(e.target.value)}
  233. >
  234. <Radio value={0}>无规则</Radio>
  235. <Radio value={1}>关联规则</Radio>
  236. <Radio value={2}>新建规则</Radio>
  237. </Radio.Group>
  238. </Form.Item>
  239. {type === 1 && (
  240. <Form.Item label="关联规则">
  241. <Select
  242. value={alarmId}
  243. onChange={setAlarmId}
  244. style={{ width: 240 }}
  245. options={ruleOptions}
  246. placeholder={TranslateText(["请选择", "Please choose"])}
  247. />
  248. </Form.Item>
  249. )}
  250. </>
  251. )}
  252. {(!showList || type !== 0) && (
  253. <>
  254. <Form.Item
  255. label={TranslateText(["告警名称", "Alarm name"])}
  256. name="name"
  257. rules={[
  258. {
  259. required: true,
  260. message: TranslateText([
  261. "请输入告警名称",
  262. "Please input",
  263. ]),
  264. },
  265. ]}
  266. >
  267. <Input
  268. placeholder={TranslateText([
  269. "请输入告警名称",
  270. "Please input",
  271. ])}
  272. style={{ width: "240px" }}
  273. />
  274. </Form.Item>
  275. <Form.Item
  276. label={TranslateText(["条件符号", "Symbol"])}
  277. // name="symb"
  278. >
  279. <div className="symb" style={{ width: "500px" }}>
  280. <Button type="primary" onClick={symbClick}>
  281. ()
  282. </Button>
  283. <Button type="primary" onClick={symbClick}>
  284. {"&&(and)"}
  285. </Button>
  286. <Button type="primary" onClick={symbClick}>
  287. {"||(or)"}
  288. </Button>
  289. <Button type="primary" onClick={symbClick}>
  290. </Button>
  291. <Button type="primary" onClick={symbClick}>
  292. {">"}
  293. </Button>
  294. <Button type="primary" onClick={symbClick}>
  295. =
  296. </Button>
  297. <Button type="primary" onClick={symbClick}>{`<`}</Button>
  298. <Button type="primary" onClick={symbClick}>
  299. </Button>
  300. <Button type="primary" onClick={symbClick}>
  301. +
  302. </Button>
  303. <Button type="primary" onClick={symbClick}>
  304. -
  305. </Button>
  306. <Button type="primary" onClick={symbClick}>
  307. ×
  308. </Button>
  309. <Button type="primary" onClick={symbClick}>
  310. ÷
  311. </Button>
  312. </div>
  313. </Form.Item>
  314. <Form.Item
  315. label={TranslateText(["条件编辑", "Edit"])}
  316. // name="formu"
  317. >
  318. <Formular ref={formuRef} key={`${type}-${alarmId}`} />
  319. </Form.Item>
  320. <Form.Item
  321. label={TranslateText(["告警组", "Alarm group"])}
  322. name={"group_id"}
  323. >
  324. <Select
  325. style={{ width: 240 }}
  326. options={[
  327. ...[
  328. {
  329. label: "未分组",
  330. value: 0,
  331. },
  332. ],
  333. ...(groupList?.map((item) => {
  334. return {
  335. label: item?.name,
  336. value: item?.id,
  337. };
  338. }) ?? []),
  339. ]}
  340. placeholder={TranslateText(["请选择", "Please choose"])}
  341. />
  342. </Form.Item>
  343. <Form.Item
  344. label={TranslateText(["告警级别", "Alarm level"])}
  345. name="alarm_level"
  346. rules={[
  347. {
  348. required: true,
  349. message: TranslateText([
  350. "请输入告警级别",
  351. "Please input",
  352. ]),
  353. },
  354. ]}
  355. >
  356. <Select
  357. placeholder={TranslateText(["请选择", "Please choose"])}
  358. style={{ width: "240px" }}
  359. >
  360. <Select.Option value={1}>
  361. {TranslateText(["低", "Low"])}
  362. </Select.Option>
  363. <Select.Option value={2}>
  364. {TranslateText(["中", "Medium"])}
  365. </Select.Option>
  366. <Select.Option value={3}>
  367. {TranslateText(["高", "High"])}
  368. </Select.Option>
  369. </Select>
  370. </Form.Item>
  371. </>
  372. )}
  373. </Form>
  374. </div>
  375. {(!showList || type !== 0) && (
  376. <>
  377. <div
  378. style={{
  379. borderRight: "1px solid rgba(255, 255, 255, 0.12)",
  380. marginLeft: "16px",
  381. }}
  382. ></div>
  383. <div className="right">
  384. <div className="header">
  385. <Search
  386. placeholder={TranslateText([
  387. "请输入点位名称",
  388. "Please input",
  389. ])}
  390. onSearch={onSearch}
  391. style={{ width: "240px" }}
  392. // className={styles.deviceListTreeSearch}
  393. />
  394. </div>
  395. <Table
  396. onRow={(record) => {
  397. return {
  398. onClick: (event) => {
  399. clickTableRow(record);
  400. }, // 点击行
  401. };
  402. }}
  403. key={deviceList}
  404. loading={loading}
  405. columns={columns}
  406. dataSource={deviceList}
  407. rowKey="point_id"
  408. // className="deviceListTable"
  409. pagination={paginationProps}
  410. onChange={handleTableChange}
  411. size="middle"
  412. />
  413. </div>
  414. </>
  415. )}
  416. </div>
  417. </div>
  418. );
  419. };
  420. export default forwardRef(Complex);