index.tsx 12 KB

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