index.tsx 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. import { PageContainer } from '@ant-design/pro-layout';
  2. import Service from '@/pages/rule-engine/Instance/serivce';
  3. import type { InstanceItem } from '@/pages/rule-engine/Instance/typings';
  4. import { useEffect, useRef, useState } from 'react';
  5. import type { ActionType, ProColumns } from '@jetlinks/pro-table';
  6. import {
  7. DeleteOutlined,
  8. EditOutlined,
  9. EyeOutlined,
  10. PlayCircleOutlined,
  11. PlusOutlined,
  12. StopOutlined,
  13. } from '@ant-design/icons';
  14. import { Button, Tooltip } from 'antd';
  15. import { useIntl } from '@@/plugin-locale/localeExports';
  16. import SearchComponent from '@/components/SearchComponent';
  17. import { BadgeStatus, PermissionButton, ProTableCard } from '@/components';
  18. import RuleInstanceCard from '@/components/ProTableCard/CardItems/ruleInstance';
  19. import Save from '@/pages/rule-engine/Instance/Save';
  20. import SystemConst from '@/utils/const';
  21. import { StatusColorEnum } from '@/components/BadgeStatus';
  22. import useLocation from '@/hooks/route/useLocation';
  23. import { onlyMessage } from '@/utils/util';
  24. export const service = new Service('rule-engine/instance');
  25. const Instance = () => {
  26. const intl = useIntl();
  27. const actionRef = useRef<ActionType>();
  28. const [visible, setVisible] = useState<boolean>(false);
  29. const [current, setCurrent] = useState<Partial<InstanceItem>>({});
  30. const [searchParams, setSearchParams] = useState<any>({});
  31. const { permission } = PermissionButton.usePermission('rule-engine/Instance');
  32. const location = useLocation();
  33. useEffect(() => {
  34. const { state } = location;
  35. if (state && state.save) {
  36. setCurrent({});
  37. setVisible(true);
  38. }
  39. }, [location]);
  40. const tools = (record: InstanceItem) => [
  41. <PermissionButton
  42. isPermission={permission.update}
  43. key="warning"
  44. onClick={() => {
  45. setCurrent(record);
  46. setVisible(true);
  47. }}
  48. type={'link'}
  49. style={{ padding: 0 }}
  50. >
  51. <EditOutlined />
  52. 编辑
  53. </PermissionButton>,
  54. <PermissionButton
  55. type={'link'}
  56. key={'state'}
  57. style={{ padding: 0 }}
  58. popConfirm={{
  59. title: `确认${record.state.value !== 'disable' ? '禁用' : '启用'}`,
  60. onConfirm: async () => {
  61. if (record.state.value !== 'disable') {
  62. await service.stopRule(record.id);
  63. } else {
  64. await service.startRule(record.id);
  65. }
  66. onlyMessage(
  67. intl.formatMessage({
  68. id: 'pages.data.option.success',
  69. defaultMessage: '操作成功!',
  70. }),
  71. );
  72. actionRef.current?.reload();
  73. },
  74. }}
  75. isPermission={permission.action}
  76. >
  77. {record.state.value !== 'disable' ? <StopOutlined /> : <PlayCircleOutlined />}
  78. {record.state.value !== 'disable' ? '禁用' : '启用'}
  79. </PermissionButton>,
  80. <PermissionButton
  81. isPermission={permission.delete}
  82. disabled={record.state.value !== 'disable'}
  83. tooltip={{
  84. title: record.state.value !== 'disable' ? '请先禁用,再删除' : '删除',
  85. }}
  86. popConfirm={{
  87. title: '确认删除',
  88. disabled: record.state.value !== 'disable',
  89. onConfirm: async () => {
  90. if (record.state.value === 'disable') {
  91. await service.remove(record.id);
  92. onlyMessage(
  93. intl.formatMessage({
  94. id: 'pages.data.option.success',
  95. defaultMessage: '操作成功!',
  96. }),
  97. );
  98. actionRef.current?.reload();
  99. } else {
  100. onlyMessage('未停止不能删除', 'error');
  101. }
  102. },
  103. }}
  104. key="delete"
  105. type="link"
  106. >
  107. <DeleteOutlined />
  108. </PermissionButton>,
  109. ];
  110. const columns: ProColumns<InstanceItem>[] = [
  111. {
  112. dataIndex: 'name',
  113. title: intl.formatMessage({
  114. id: 'pages.table.name',
  115. defaultMessage: '名称',
  116. }),
  117. ellipsis: true,
  118. fixed: 'left',
  119. },
  120. {
  121. dataIndex: 'state',
  122. title: '状态',
  123. render: (text: any, record: any) => (
  124. <BadgeStatus
  125. status={record.state?.value}
  126. text={record.state?.text}
  127. statusNames={{
  128. started: StatusColorEnum.success,
  129. disable: StatusColorEnum.error,
  130. }}
  131. />
  132. ),
  133. valueType: 'select',
  134. valueEnum: {
  135. started: {
  136. text: '正常',
  137. status: 'started',
  138. },
  139. disable: {
  140. text: '禁用',
  141. status: 'disable',
  142. },
  143. },
  144. },
  145. {
  146. dataIndex: 'description',
  147. title: '说明',
  148. ellipsis: true,
  149. },
  150. {
  151. title: intl.formatMessage({
  152. id: 'pages.data.option',
  153. defaultMessage: '操作',
  154. }),
  155. valueType: 'option',
  156. align: 'center',
  157. width: 200,
  158. fixed: 'right',
  159. render: (text, record) => [
  160. <PermissionButton
  161. isPermission={permission.update}
  162. key="warning"
  163. onClick={() => {
  164. setCurrent(record);
  165. setVisible(true);
  166. }}
  167. type={'link'}
  168. style={{ padding: 0 }}
  169. tooltip={{
  170. title: intl.formatMessage({
  171. id: 'pages.data.option.edit',
  172. defaultMessage: '编辑',
  173. }),
  174. }}
  175. >
  176. <EditOutlined />
  177. </PermissionButton>,
  178. <Button
  179. type="link"
  180. style={{ padding: 0 }}
  181. key={'view'}
  182. onClick={() => {
  183. window.open(`/${SystemConst.API_BASE}/rule-editor/index.html#flow/${record.id}`);
  184. }}
  185. >
  186. <Tooltip
  187. title={intl.formatMessage({
  188. id: 'pages.ruleEngine.option.detail',
  189. defaultMessage: '查看',
  190. })}
  191. >
  192. <EyeOutlined />
  193. </Tooltip>
  194. </Button>,
  195. <PermissionButton
  196. type={'link'}
  197. key={'state'}
  198. style={{ padding: 0 }}
  199. popConfirm={{
  200. title: `确认${record.state.value !== 'disable' ? '禁用' : '启用'}`,
  201. onConfirm: async () => {
  202. if (record.state.value !== 'disable') {
  203. await service.stopRule(record.id);
  204. } else {
  205. await service.startRule(record.id);
  206. }
  207. onlyMessage(
  208. intl.formatMessage({
  209. id: 'pages.data.option.success',
  210. defaultMessage: '操作成功!',
  211. }),
  212. );
  213. actionRef.current?.reload();
  214. },
  215. }}
  216. isPermission={permission.action}
  217. tooltip={{
  218. title: record.state.value !== 'disable' ? '禁用' : '启用',
  219. }}
  220. >
  221. {record.state.value !== 'disable' ? <StopOutlined /> : <PlayCircleOutlined />}
  222. </PermissionButton>,
  223. <PermissionButton
  224. isPermission={permission.delete}
  225. style={{ padding: 0 }}
  226. disabled={record.state.value !== 'disable'}
  227. tooltip={{
  228. title: record.state.value !== 'disable' ? '请先禁用,再删除' : '删除',
  229. }}
  230. popConfirm={{
  231. title: '确认删除',
  232. disabled: record.state.value !== 'disable',
  233. onConfirm: async () => {
  234. if (record.state.value === 'disable') {
  235. const resp: any = await service.remove(record.id);
  236. if (resp.status === 200) {
  237. onlyMessage(
  238. intl.formatMessage({
  239. id: 'pages.data.option.success',
  240. defaultMessage: '操作成功!',
  241. }),
  242. );
  243. actionRef.current?.reload();
  244. }
  245. } else {
  246. onlyMessage('未停止不能删除', 'error');
  247. }
  248. },
  249. }}
  250. key="button"
  251. type="link"
  252. >
  253. <DeleteOutlined />
  254. </PermissionButton>,
  255. ],
  256. },
  257. ];
  258. return (
  259. <PageContainer>
  260. <SearchComponent<InstanceItem>
  261. field={columns}
  262. target="device-instance"
  263. onSearch={(data) => {
  264. // 重置分页数据
  265. actionRef.current?.reset?.();
  266. setSearchParams(data);
  267. }}
  268. />
  269. <ProTableCard<InstanceItem>
  270. columns={columns}
  271. actionRef={actionRef}
  272. params={searchParams}
  273. scroll={{ x: 1366 }}
  274. columnEmptyText={''}
  275. options={{ fullScreen: true }}
  276. request={(params) =>
  277. service.query({
  278. ...params,
  279. sorts: [
  280. {
  281. name: 'createTime',
  282. order: 'desc',
  283. },
  284. ],
  285. })
  286. }
  287. rowKey="id"
  288. search={false}
  289. pagination={{ pageSize: 10 }}
  290. headerTitle={[
  291. <PermissionButton
  292. isPermission={permission.add}
  293. key="add"
  294. onClick={() => {
  295. setVisible(true);
  296. setCurrent({});
  297. }}
  298. icon={<PlusOutlined />}
  299. type="primary"
  300. tooltip={{
  301. title: intl.formatMessage({
  302. id: 'pages.data.option.add',
  303. defaultMessage: '新增',
  304. }),
  305. }}
  306. >
  307. 新增
  308. </PermissionButton>,
  309. ]}
  310. cardRender={(record) => (
  311. <RuleInstanceCard
  312. {...record}
  313. actions={tools(record)}
  314. detail={
  315. <div
  316. style={{ padding: 8, fontSize: 24 }}
  317. onClick={() => {
  318. window.open(`/${SystemConst.API_BASE}/rule-editor/index.html#flow/${record.id}`);
  319. }}
  320. >
  321. <EyeOutlined />
  322. </div>
  323. }
  324. />
  325. )}
  326. />
  327. {visible && (
  328. <Save
  329. data={current}
  330. close={() => {
  331. setVisible(false);
  332. actionRef.current?.reload();
  333. }}
  334. />
  335. )}
  336. </PageContainer>
  337. );
  338. };
  339. export default Instance;