index.tsx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import { PageContainer } from '@ant-design/pro-layout';
  2. import type { ActionType, ProColumns } from '@jetlinks/pro-table';
  3. import ProTable from '@jetlinks/pro-table';
  4. import { message, Popconfirm, Tooltip } from 'antd';
  5. import { useRef, useState } from 'react';
  6. import { useIntl } from '@@/plugin-locale/localeExports';
  7. import {
  8. ControlOutlined,
  9. DeleteOutlined,
  10. EyeOutlined,
  11. PlusOutlined,
  12. StopOutlined,
  13. } from '@ant-design/icons';
  14. import { useHistory, useLocation } from 'umi';
  15. import { model } from '@formily/reactive';
  16. import { observer } from '@formily/react';
  17. import type { FirmwareItem } from '@/pages/device/Firmware/typings';
  18. import Save from './Save';
  19. import { onlyMessage } from '@/utils/util';
  20. import { PermissionButton, AIcon } from '@/components';
  21. import useDomFullHeight from '@/hooks/document/useDomFullHeight';
  22. import usePermissions from '@/hooks/permission';
  23. import SearchComponent from '@/components/SearchComponent';
  24. import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
  25. import { service } from '@/pages/device/Firmware';
  26. const UpgradeBtn = (props: { data: any; actions: any }) => {
  27. const { data, actions } = props;
  28. if (data.waiting > 0 && data?.state?.value === 'processing') {
  29. return (
  30. <a>
  31. <Tooltip title={'停止'}>
  32. <StopOutlined
  33. onClick={async () => {
  34. const resp = await service.stopTask(data.id);
  35. if (resp.status === 200) {
  36. message.success('操作成功!');
  37. actions?.reload();
  38. }
  39. }}
  40. />
  41. </Tooltip>
  42. </a>
  43. );
  44. } else if (data?.state?.value === 'canceled') {
  45. return (
  46. <a>
  47. <Tooltip title={'继续升级'}>
  48. <ControlOutlined
  49. onClick={async () => {
  50. const resp = await service.startTask(data.id, ['canceled']);
  51. if (resp.status === 200) {
  52. message.success('操作成功!');
  53. actions?.reload();
  54. }
  55. }}
  56. />
  57. </Tooltip>
  58. </a>
  59. );
  60. }
  61. return null;
  62. };
  63. export const state = model<{
  64. current?: FirmwareItem;
  65. visible: boolean;
  66. }>({
  67. visible: false,
  68. });
  69. const Task = observer(() => {
  70. const actionRef = useRef<ActionType>();
  71. const intl = useIntl();
  72. const { minHeight } = useDomFullHeight(`.firmware-task`, 24);
  73. const { permission } = usePermissions('device/Firmware');
  74. const [param, setParam] = useState({});
  75. const history = useHistory<Record<string, string>>();
  76. const location = useLocation<{ id: string }>();
  77. const id = (location as any).query?.id || localStorage.getItem('TaskId');
  78. const productId = (location as any).query?.productId || localStorage.getItem('TaskProductId');
  79. const columns: ProColumns<any>[] = [
  80. {
  81. title: '任务名称',
  82. ellipsis: true,
  83. dataIndex: 'name',
  84. },
  85. {
  86. title: '推送方式',
  87. ellipsis: true,
  88. dataIndex: 'mode',
  89. render: (text: any, record: any) => record?.mode?.text || '',
  90. valueType: 'select',
  91. valueEnum: {
  92. pull: {
  93. text: '设备拉取',
  94. status: 'pull',
  95. },
  96. push: {
  97. text: '平台推送',
  98. status: 'push',
  99. },
  100. },
  101. },
  102. {
  103. title: intl.formatMessage({
  104. id: 'pages.table.description',
  105. defaultMessage: '说明',
  106. }),
  107. ellipsis: true,
  108. dataIndex: 'description',
  109. },
  110. {
  111. title: '完成比例',
  112. ellipsis: true,
  113. hideInSearch: true,
  114. dataIndex: 'progress',
  115. renderText: (text) => <>{text}%</>,
  116. // valueType: 'digit',
  117. },
  118. {
  119. title: intl.formatMessage({
  120. id: 'pages.data.option',
  121. defaultMessage: '操作',
  122. }),
  123. valueType: 'option',
  124. width: 200,
  125. fixed: 'right',
  126. render: (text, record) => [
  127. <PermissionButton
  128. key={'api'}
  129. type={'link'}
  130. style={{ padding: 0 }}
  131. isPermission={true}
  132. tooltip={{
  133. title: '详情',
  134. }}
  135. onClick={() => {
  136. const url = getMenuPathByParams(MENUS_CODE['device/Firmware/Task/Detail'], record?.id);
  137. history.push(url);
  138. }}
  139. >
  140. <AIcon type={'icon-details'} />
  141. </PermissionButton>,
  142. <a
  143. onClick={() => {
  144. state.visible = true;
  145. state.current = record;
  146. }}
  147. key="link"
  148. >
  149. <Tooltip title="查看" key={'detail'}>
  150. <EyeOutlined />
  151. </Tooltip>
  152. </a>,
  153. <UpgradeBtn data={record} actions={actionRef.current} key="btn" />,
  154. <a key="delete">
  155. <Popconfirm
  156. title={
  157. record.waiting > 0 || record.processing > 0
  158. ? '删除将导致正在进行的任务终止,确定要删除吗?'
  159. : intl.formatMessage({
  160. id: 'pages.data.option.remove.tips',
  161. defaultMessage: '确认删除?',
  162. })
  163. }
  164. onConfirm={async () => {
  165. const resp = await service.deleteTask(record.id);
  166. if (resp.status === 200) {
  167. onlyMessage(
  168. intl.formatMessage({
  169. id: 'pages.data.option.success',
  170. defaultMessage: '操作成功!',
  171. }),
  172. );
  173. actionRef.current?.reload();
  174. } else {
  175. message.error(resp?.message || '删除失败!');
  176. }
  177. }}
  178. >
  179. <Tooltip
  180. title={intl.formatMessage({
  181. id: 'pages.data.option.remove',
  182. defaultMessage: '删除',
  183. })}
  184. >
  185. <DeleteOutlined />
  186. </Tooltip>
  187. </Popconfirm>
  188. </a>,
  189. ],
  190. },
  191. ];
  192. return (
  193. <PageContainer>
  194. <SearchComponent<FirmwareItem>
  195. field={columns}
  196. target="firmware-task"
  197. onSearch={(data) => {
  198. // 重置分页数据
  199. actionRef.current?.reset?.();
  200. setParam(data);
  201. }}
  202. defaultParam={[{ column: 'firmwareId', value: id }]}
  203. />
  204. <ProTable<FirmwareItem>
  205. scroll={{ x: 1366 }}
  206. tableClassName={'firmware-task'}
  207. tableStyle={{ minHeight }}
  208. search={false}
  209. params={param}
  210. rowKey="id"
  211. columnEmptyText={''}
  212. headerTitle={
  213. <div>
  214. <PermissionButton
  215. onClick={() => {
  216. state.visible = true;
  217. state.current = undefined;
  218. }}
  219. isPermission={permission.add}
  220. key="button"
  221. icon={<PlusOutlined />}
  222. type="primary"
  223. >
  224. {intl.formatMessage({
  225. id: 'pages.data.option.add',
  226. defaultMessage: '新增',
  227. })}
  228. </PermissionButton>
  229. </div>
  230. }
  231. request={async (params) =>
  232. service.task({
  233. ...params,
  234. sorts: [{ name: 'createTime', order: 'desc' }],
  235. })
  236. }
  237. columns={columns}
  238. actionRef={actionRef}
  239. />
  240. {state.visible && (
  241. <Save
  242. data={state.current}
  243. ids={{ id: id, productId: productId }}
  244. save={() => {
  245. state.visible = false;
  246. actionRef.current?.reload?.();
  247. }}
  248. close={() => {
  249. state.visible = false;
  250. }}
  251. />
  252. )}
  253. </PageContainer>
  254. );
  255. });
  256. export default Task;