index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. import { PageContainer } from '@ant-design/pro-layout';
  2. import type { ActionType, ProColumns } from '@jetlinks/pro-table';
  3. import {
  4. ArrowDownOutlined,
  5. BarsOutlined,
  6. BugOutlined,
  7. DeleteOutlined,
  8. EditOutlined,
  9. EyeOutlined,
  10. PlusOutlined,
  11. TeamOutlined,
  12. UnorderedListOutlined,
  13. } from '@ant-design/icons';
  14. import { message, Space, Upload } from 'antd';
  15. import { useRef, useState } from 'react';
  16. import { useIntl } from '@@/plugin-locale/localeExports';
  17. import { downloadObject } from '@/utils/util';
  18. import Service from '@/pages/notice/Config/service';
  19. import { observer } from '@formily/react';
  20. import SearchComponent from '@/components/SearchComponent';
  21. import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
  22. import { history, useLocation } from 'umi';
  23. import { model } from '@formily/reactive';
  24. import moment from 'moment';
  25. import { PermissionButton, ProTableCard } from '@/components';
  26. import NoticeConfig from '@/components/ProTableCard/CardItems/noticeConfig';
  27. import Debug from '@/pages/notice/Config/Debug';
  28. import Log from '@/pages/notice/Config/Log';
  29. import { typeList } from '@/components/ProTableCard/CardItems/noticeTemplate';
  30. import usePermissions from '@/hooks/permission';
  31. import SyncUser from '@/pages/notice/Config/SyncUser';
  32. export const service = new Service('notifier/config');
  33. export const state = model<{
  34. current?: ConfigItem;
  35. debug?: boolean;
  36. log?: boolean;
  37. syncUser: boolean;
  38. }>({
  39. debug: false,
  40. log: false,
  41. syncUser: false,
  42. });
  43. const Config = observer(() => {
  44. const intl = useIntl();
  45. const actionRef = useRef<ActionType>();
  46. const location = useLocation<{ id: string }>();
  47. const { permission: configPermission } = usePermissions('notice');
  48. const id = (location as any).query?.id;
  49. const columns: ProColumns<ConfigItem>[] = [
  50. {
  51. dataIndex: 'name',
  52. title: '配置名称',
  53. },
  54. {
  55. dataIndex: 'provider',
  56. title: '通知方式',
  57. renderText: (text, record) => typeList[record.type][record.provider],
  58. },
  59. {
  60. dataIndex: 'description',
  61. title: '说明',
  62. },
  63. {
  64. title: intl.formatMessage({
  65. id: 'pages.data.option',
  66. defaultMessage: '操作',
  67. }),
  68. valueType: 'option',
  69. align: 'center',
  70. width: 200,
  71. render: (text, record) => [
  72. (id === 'dingTalk' || id === 'weixin') && (
  73. <PermissionButton
  74. tooltip={{
  75. title: '同步用户',
  76. }}
  77. style={{ padding: 0 }}
  78. type="link"
  79. onClick={() => {
  80. state.syncUser = true;
  81. state.current = record;
  82. }}
  83. >
  84. <TeamOutlined />
  85. </PermissionButton>
  86. ),
  87. <PermissionButton
  88. key="edit"
  89. type="link"
  90. style={{ padding: 0 }}
  91. isPermission={configPermission.update}
  92. onClick={async () => {
  93. // setLoading(true);
  94. state.current = record;
  95. history.push(getMenuPathByParams(MENUS_CODE['notice/Config/Detail'], id));
  96. }}
  97. tooltip={{
  98. title: intl.formatMessage({
  99. id: 'pages.data.option.edit',
  100. defaultMessage: '编辑',
  101. }),
  102. }}
  103. >
  104. <EditOutlined />
  105. </PermissionButton>,
  106. <PermissionButton
  107. type="link"
  108. style={{ padding: 0 }}
  109. isPermission={configPermission.export}
  110. onClick={() =>
  111. downloadObject(
  112. record,
  113. `通知配置${record.name}-${moment(new Date()).format('YYYY/MM/DD HH:mm:ss')}`,
  114. )
  115. }
  116. key="download"
  117. tooltip={{
  118. title: intl.formatMessage({
  119. id: 'pages.data.option.download',
  120. defaultMessage: '下载配置',
  121. }),
  122. }}
  123. >
  124. <ArrowDownOutlined />
  125. </PermissionButton>,
  126. <PermissionButton
  127. type="link"
  128. style={{ padding: 0 }}
  129. isPermission={configPermission.debug}
  130. key="debug"
  131. onClick={() => {
  132. state.debug = true;
  133. state.current = record;
  134. }}
  135. tooltip={{
  136. title: intl.formatMessage({
  137. id: 'pages.notice.option.debug',
  138. defaultMessage: '调试',
  139. }),
  140. }}
  141. >
  142. <BugOutlined />
  143. </PermissionButton>,
  144. <PermissionButton
  145. type="link"
  146. style={{ padding: 0 }}
  147. isPermission={configPermission.log}
  148. key="record"
  149. onClick={() => {
  150. state.log = true;
  151. }}
  152. tooltip={{
  153. title: intl.formatMessage({
  154. id: 'pages.data.option.record',
  155. defaultMessage: '通知记录',
  156. }),
  157. }}
  158. >
  159. <BarsOutlined />
  160. </PermissionButton>,
  161. <PermissionButton
  162. style={{ padding: 0 }}
  163. type="link"
  164. popConfirm={{
  165. onConfirm: async () => {
  166. await service.remove(record.id);
  167. message.success(
  168. intl.formatMessage({
  169. id: 'pages.data.option.success',
  170. defaultMessage: '操作成功!',
  171. }),
  172. );
  173. actionRef.current?.reload();
  174. },
  175. title: '确认删除',
  176. }}
  177. tooltip={{
  178. title: intl.formatMessage({
  179. id: 'pages.data.option.remove',
  180. defaultMessage: '删除',
  181. }),
  182. }}
  183. key="remove"
  184. >
  185. <DeleteOutlined />
  186. </PermissionButton>,
  187. ],
  188. },
  189. ];
  190. const [param, setParam] = useState({});
  191. return (
  192. <PageContainer>
  193. <SearchComponent
  194. defaultParam={[{ column: 'type$IN', value: id }]}
  195. field={columns}
  196. onSearch={(data) => {
  197. actionRef.current?.reset?.();
  198. setParam(data);
  199. }}
  200. />
  201. <ProTableCard<ConfigItem>
  202. rowKey="id"
  203. actionRef={actionRef}
  204. search={false}
  205. params={param}
  206. columns={columns}
  207. headerTitle={
  208. <Space>
  209. <PermissionButton
  210. isPermission={configPermission.add}
  211. onClick={() => {
  212. state.current = undefined;
  213. history.push(getMenuPathByParams(MENUS_CODE['notice/Config/Detail'], id));
  214. }}
  215. key="button"
  216. icon={<PlusOutlined />}
  217. type="primary"
  218. >
  219. {intl.formatMessage({
  220. id: 'pages.data.option.add',
  221. defaultMessage: '新增',
  222. })}
  223. </PermissionButton>
  224. <Upload
  225. disabled={!configPermission.import}
  226. key={'import'}
  227. showUploadList={false}
  228. beforeUpload={(file) => {
  229. const reader = new FileReader();
  230. reader.readAsText(file);
  231. reader.onload = async (result) => {
  232. const text = result.target?.result as string;
  233. if (!file.type.includes('json')) {
  234. message.warning('文件内容格式错误');
  235. return;
  236. }
  237. try {
  238. const data = JSON.parse(text || '{}');
  239. const res: any = await service.savePatch(data);
  240. if (res.status === 200) {
  241. message.success('操作成功');
  242. actionRef.current?.reload();
  243. }
  244. } catch {
  245. message.warning('文件内容格式错误');
  246. }
  247. };
  248. return false;
  249. }}
  250. >
  251. <PermissionButton isPermission={configPermission.import} style={{ marginLeft: 12 }}>
  252. 导入
  253. </PermissionButton>
  254. </Upload>
  255. <PermissionButton
  256. popConfirm={{
  257. title: '确认导出当前页数据?',
  258. onConfirm: async () => {
  259. const resp: any = await service.queryNoPagingPost({ ...param, paging: false });
  260. if (resp.status === 200) {
  261. downloadObject(resp.result, '通知配置数据');
  262. message.success('导出成功');
  263. } else {
  264. message.error('导出错误');
  265. }
  266. },
  267. }}
  268. isPermission={configPermission.export}
  269. >
  270. 导出
  271. </PermissionButton>
  272. </Space>
  273. }
  274. gridColumn={3}
  275. request={async (params) =>
  276. service.query({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
  277. }
  278. cardRender={(record) => (
  279. <NoticeConfig
  280. {...record}
  281. type={id}
  282. detail={
  283. <div
  284. style={{ fontSize: 18, padding: 8 }}
  285. onClick={() => {
  286. state.current = record;
  287. history.push(getMenuPathByParams(MENUS_CODE['notice/Config/Detail'], id));
  288. }}
  289. >
  290. <EyeOutlined />
  291. </div>
  292. }
  293. actions={[
  294. (record.provider === 'dingTalkMessage' || record.provider === 'corpMessage') && (
  295. <PermissionButton
  296. key="syncUser"
  297. isPermission={true}
  298. type="link"
  299. onClick={() => {
  300. state.syncUser = true;
  301. state.current = record;
  302. }}
  303. >
  304. <TeamOutlined />
  305. 同步用户
  306. </PermissionButton>
  307. ),
  308. <PermissionButton
  309. isPermission={configPermission.update}
  310. type={'link'}
  311. key="edit"
  312. onClick={async () => {
  313. state.current = record;
  314. history.push(getMenuPathByParams(MENUS_CODE['notice/Config/Detail'], id));
  315. }}
  316. >
  317. <EditOutlined />
  318. 编辑
  319. </PermissionButton>,
  320. <PermissionButton
  321. type={'link'}
  322. key="debug"
  323. isPermission={configPermission.debug}
  324. onClick={() => {
  325. state.debug = true;
  326. state.current = record;
  327. }}
  328. >
  329. <BugOutlined />
  330. 调试
  331. </PermissionButton>,
  332. <PermissionButton
  333. type={'link'}
  334. key="export"
  335. isPermission={configPermission.export}
  336. onClick={() =>
  337. downloadObject(
  338. record,
  339. `通知配置${record.name}-${moment(new Date()).format('YYYY/MM/DD HH:mm:ss')}`,
  340. )
  341. }
  342. >
  343. <ArrowDownOutlined />
  344. 导出
  345. </PermissionButton>,
  346. <PermissionButton
  347. type={'link'}
  348. key="log"
  349. isPermission={configPermission.log}
  350. onClick={() => {
  351. state.log = true;
  352. state.current = record;
  353. }}
  354. >
  355. <UnorderedListOutlined />
  356. 通知记录
  357. </PermissionButton>,
  358. <PermissionButton
  359. key="delete"
  360. isPermission={configPermission.delete}
  361. popConfirm={{
  362. title: '确认删除?',
  363. onConfirm: async () => {
  364. await service.remove(record.id);
  365. actionRef.current?.reset?.();
  366. },
  367. }}
  368. type={'link'}
  369. >
  370. <DeleteOutlined />
  371. </PermissionButton>,
  372. ]}
  373. />
  374. )}
  375. />
  376. <Debug />
  377. {state.log && <Log />}
  378. {state.syncUser && <SyncUser />}
  379. </PageContainer>
  380. );
  381. });
  382. export default Config;