@jiangood/admin-spring-boot-starter 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/config/dist/config.js +45 -0
  2. package/config/dist/index.js +19 -0
  3. package/config/dist/plugins/form-plugin.js +51 -0
  4. package/config/dist/plugins/route-plugin.js +72 -0
  5. package/package.json +41 -0
  6. package/src/app.js +1 -0
  7. package/src/asserts/welcome.png +0 -0
  8. package/src/forms/demoForm.jsx +16 -0
  9. package/src/framework/components/DownloadFileButton.d.ts +11 -0
  10. package/src/framework/components/DownloadFileButton.jsx +33 -0
  11. package/src/framework/components/Ellipsis.jsx +39 -0
  12. package/src/framework/components/Ellipsis.less +8 -0
  13. package/src/framework/components/Gap/index.d.ts +23 -0
  14. package/src/framework/components/Gap/index.jsx +46 -0
  15. package/src/framework/components/LinkButton.d.ts +14 -0
  16. package/src/framework/components/LinkButton.jsx +10 -0
  17. package/src/framework/components/NamedIcon.tsx +15 -0
  18. package/src/framework/components/Page/index.d.ts +17 -0
  19. package/src/framework/components/Page/index.jsx +30 -0
  20. package/src/framework/components/Page/index.less +10 -0
  21. package/src/framework/components/PageLoading.tsx +27 -0
  22. package/src/framework/components/ProModal/index.tsx +66 -0
  23. package/src/framework/components/ProTable/components/ToolBar/index.jsx +123 -0
  24. package/src/framework/components/ProTable/components/ToolBar/index.less +53 -0
  25. package/src/framework/components/ProTable/index.d.ts +42 -0
  26. package/src/framework/components/ProTable/index.jsx +260 -0
  27. package/src/framework/components/ProTable/index.less +14 -0
  28. package/src/framework/components/ProTable/utils/index.js +43 -0
  29. package/src/framework/components/ValueType/index.jsx +34 -0
  30. package/src/framework/components/ValueType/registry.jsx +27 -0
  31. package/src/framework/components/index.ts +17 -0
  32. package/src/framework/components/system/ButtonList.d.ts +9 -0
  33. package/src/framework/components/system/ButtonList.jsx +35 -0
  34. package/src/framework/components/system/HasPerm.tsx +14 -0
  35. package/src/framework/components/system/index.tsx +29 -0
  36. package/src/framework/components/view/ViewBooleanEnableDisable.tsx +20 -0
  37. package/src/framework/components/view/ViewEllipsis.d.ts +11 -0
  38. package/src/framework/components/view/ViewEllipsis.jsx +30 -0
  39. package/src/framework/components/view/ViewFile.d.ts +10 -0
  40. package/src/framework/components/view/ViewFile.jsx +49 -0
  41. package/src/framework/components/view/ViewFileButton.d.ts +10 -0
  42. package/src/framework/components/view/ViewFileButton.jsx +0 -0
  43. package/src/framework/components/view/ViewImage.d.ts +9 -0
  44. package/src/framework/components/view/ViewImage.jsx +60 -0
  45. package/src/framework/components/view/ViewRange/index.d.ts +16 -0
  46. package/src/framework/components/view/ViewRange/index.jsx +20 -0
  47. package/src/framework/components/view/ViewText.tsx +16 -0
  48. package/src/framework/components/view/index.ts +10 -0
  49. package/src/framework/field-components/FieldBoolean.d.ts +13 -0
  50. package/src/framework/field-components/FieldBoolean.jsx +76 -0
  51. package/src/framework/field-components/FieldDate.d.ts +27 -0
  52. package/src/framework/field-components/FieldDate.jsx +114 -0
  53. package/src/framework/field-components/FieldDateRange.d.ts +6 -0
  54. package/src/framework/field-components/FieldDateRange.jsx +104 -0
  55. package/src/framework/field-components/FieldDictSelect.d.ts +13 -0
  56. package/src/framework/field-components/FieldDictSelect.jsx +16 -0
  57. package/src/framework/field-components/FieldEditor.d.ts +10 -0
  58. package/src/framework/field-components/FieldEditor.jsx +58 -0
  59. package/src/framework/field-components/FieldNumberRange.d.ts +13 -0
  60. package/src/framework/field-components/FieldNumberRange.jsx +59 -0
  61. package/src/framework/field-components/FieldPercent.d.ts +12 -0
  62. package/src/framework/field-components/FieldPercent.jsx +27 -0
  63. package/src/framework/field-components/FieldRemoteSelect.d.ts +13 -0
  64. package/src/framework/field-components/FieldRemoteSelect.jsx +87 -0
  65. package/src/framework/field-components/FieldRemoteSelectMultiple.d.ts +13 -0
  66. package/src/framework/field-components/FieldRemoteSelectMultiple.jsx +86 -0
  67. package/src/framework/field-components/FieldRemoteSelectMultipleInline.d.ts +20 -0
  68. package/src/framework/field-components/FieldRemoteSelectMultipleInline.jsx +86 -0
  69. package/src/framework/field-components/FieldRemoteTree.d.ts +21 -0
  70. package/src/framework/field-components/FieldRemoteTree.jsx +45 -0
  71. package/src/framework/field-components/FieldRemoteTreeCascader.d.ts +23 -0
  72. package/src/framework/field-components/FieldRemoteTreeCascader.jsx +61 -0
  73. package/src/framework/field-components/FieldRemoteTreeSelect.d.ts +17 -0
  74. package/src/framework/field-components/FieldRemoteTreeSelect.jsx +67 -0
  75. package/src/framework/field-components/FieldRemoteTreeSelectMultiple.d.ts +17 -0
  76. package/src/framework/field-components/FieldRemoteTreeSelectMultiple.jsx +68 -0
  77. package/src/framework/field-components/FieldSysOrgTree.d.ts +12 -0
  78. package/src/framework/field-components/FieldSysOrgTree.jsx +23 -0
  79. package/src/framework/field-components/FieldSysOrgTreeSelect.d.ts +12 -0
  80. package/src/framework/field-components/FieldSysOrgTreeSelect.jsx +23 -0
  81. package/src/framework/field-components/FieldTable.d.ts +17 -0
  82. package/src/framework/field-components/FieldTable.jsx +108 -0
  83. package/src/framework/field-components/FieldTable.less +29 -0
  84. package/src/framework/field-components/FieldTableSelect.d.ts +19 -0
  85. package/src/framework/field-components/FieldTableSelect.jsx +59 -0
  86. package/src/framework/field-components/FieldUploadFile.d.ts +34 -0
  87. package/src/framework/field-components/FieldUploadFile.jsx +141 -0
  88. package/src/framework/field-components/index.ts +21 -0
  89. package/src/framework/field-components/system/OrgTree.tsx +61 -0
  90. package/src/framework/field-components/system/RoleTree.tsx +53 -0
  91. package/src/framework/field-components/system/index.ts +2 -0
  92. package/src/framework/index.ts +5 -0
  93. package/src/framework/pages/LoginPage.d.ts +15 -0
  94. package/src/framework/pages/LoginPage.jsx +132 -0
  95. package/src/framework/pages/LoginPage.less +53 -0
  96. package/src/framework/pages/LoginPageUtils.ts +35 -0
  97. package/src/framework/pages/index.ts +2 -0
  98. package/src/framework/utils/ArrUtils.ts +229 -0
  99. package/src/framework/utils/ColorsUtils.ts +378 -0
  100. package/src/framework/utils/DateUtils.ts +187 -0
  101. package/src/framework/utils/DeviceUtils.ts +46 -0
  102. package/src/framework/utils/DomUtils.ts +50 -0
  103. package/src/framework/utils/EventBusUtils.ts +144 -0
  104. package/src/framework/utils/MessageUtils.tsx +145 -0
  105. package/src/framework/utils/ObjectUtils.ts +118 -0
  106. package/src/framework/utils/StorageUtils.ts +50 -0
  107. package/src/framework/utils/StringUtils.ts +412 -0
  108. package/src/framework/utils/TreeUtils.ts +251 -0
  109. package/src/framework/utils/UrlUtils.ts +152 -0
  110. package/src/framework/utils/UuidUtils.ts +88 -0
  111. package/src/framework/utils/ValidateUtils.ts +28 -0
  112. package/src/framework/utils/index.ts +16 -0
  113. package/src/framework/utils/system/DictUtils.ts +97 -0
  114. package/src/framework/utils/system/FormRegistryUtils.ts +77 -0
  115. package/src/framework/utils/system/HttpUtils.ts +247 -0
  116. package/src/framework/utils/system/PageUtils.ts +163 -0
  117. package/src/framework/utils/system/PermUtils.ts +79 -0
  118. package/src/framework/utils/system/SysUtils.ts +97 -0
  119. package/src/framework/utils/system/ThemeUtils.ts +27 -0
  120. package/src/framework/utils/system/index.ts +7 -0
  121. package/src/framework/view-components/ViewApproveStatus.tsx +26 -0
  122. package/src/framework/view-components/ViewBoolean.tsx +6 -0
  123. package/src/framework/view-components/ViewFlowableInstanceProgress.d.ts +12 -0
  124. package/src/framework/view-components/ViewFlowableInstanceProgress.jsx +97 -0
  125. package/src/framework/view-components/ViewFlowableInstanceProgressButton.tsx +26 -0
  126. package/src/framework/view-components/ViewPassword.tsx +25 -0
  127. package/src/framework/view-components/ViewProps.ts +11 -0
  128. package/src/framework/view-components/index.ts +6 -0
  129. package/src/index.ts +2 -0
  130. package/src/layouts/PageRender.d.ts +22 -0
  131. package/src/layouts/PageRender.jsx +90 -0
  132. package/src/layouts/admin/HeaderRight.jsx +104 -0
  133. package/src/layouts/admin/TabPageRender.jsx +158 -0
  134. package/src/layouts/admin/index.jsx +161 -0
  135. package/src/layouts/admin/index.less +65 -0
  136. package/src/layouts/index.jsx +153 -0
  137. package/src/layouts/index.less +24 -0
  138. package/src/loading.jsx +18 -0
  139. package/src/pages/404.jsx +13 -0
  140. package/src/pages/about.jsx +14 -0
  141. package/src/pages/flowable/design/contextPad.js +50 -0
  142. package/src/pages/flowable/design/customTranslate/customTranslate.js +16 -0
  143. package/src/pages/flowable/design/customTranslate/translations-properties-panel.js +10 -0
  144. package/src/pages/flowable/design/customTranslate/translations.js +144 -0
  145. package/src/pages/flowable/design/descriptors/flowable.json +1109 -0
  146. package/src/pages/flowable/design/index.css +7 -0
  147. package/src/pages/flowable/design/index.jsx +171 -0
  148. package/src/pages/flowable/design/provider/FlowablePropertiesProvider.js +75 -0
  149. package/src/pages/flowable/design/provider/index.js +6 -0
  150. package/src/pages/flowable/design/provider/properties/ConditionDesign.jsx +175 -0
  151. package/src/pages/flowable/design/provider/properties/ConditionProps.jsx +76 -0
  152. package/src/pages/flowable/design/provider/properties/DelegateExpressionProps.js +54 -0
  153. package/src/pages/flowable/design/provider/properties/FormProps.js +55 -0
  154. package/src/pages/flowable/design/provider/properties/MultiInstanceProps.js +100 -0
  155. package/src/pages/flowable/design/provider/properties/UserTaskForm.jsx +48 -0
  156. package/src/pages/flowable/design/provider/properties/utils.jsx +35 -0
  157. package/src/pages/flowable/index.jsx +87 -0
  158. package/src/pages/flowable/monitor/definition.jsx +87 -0
  159. package/src/pages/flowable/monitor/instance/index.jsx +177 -0
  160. package/src/pages/flowable/monitor/instance/view.jsx +102 -0
  161. package/src/pages/flowable/monitor/task.jsx +98 -0
  162. package/src/pages/flowable/task/form.jsx +186 -0
  163. package/src/pages/flowable/task/index.jsx +184 -0
  164. package/src/pages/flowable/task/instance/view.jsx +85 -0
  165. package/src/pages/flowable/test/index.jsx +57 -0
  166. package/src/pages/index.jsx +25 -0
  167. package/src/pages/login.jsx +21 -0
  168. package/src/pages/system/api/ApiDoc.jsx +144 -0
  169. package/src/pages/system/api/index.jsx +268 -0
  170. package/src/pages/system/api/perm.jsx +69 -0
  171. package/src/pages/system/config/index.jsx +136 -0
  172. package/src/pages/system/dict/Dict.jsx +72 -0
  173. package/src/pages/system/dict/DictItem.jsx +177 -0
  174. package/src/pages/system/dict/index.jsx +25 -0
  175. package/src/pages/system/file/index.jsx +160 -0
  176. package/src/pages/system/job/index.jsx +324 -0
  177. package/src/pages/system/log/index.jsx +78 -0
  178. package/src/pages/system/org/index.jsx +262 -0
  179. package/src/pages/system/role/index.jsx +308 -0
  180. package/src/pages/system/role/perm.jsx +108 -0
  181. package/src/pages/system/sysManual/index.jsx +127 -0
  182. package/src/pages/system/user/UserPerm.jsx +97 -0
  183. package/src/pages/system/user/index.jsx +258 -0
  184. package/src/pages/test.jsx +200 -0
  185. package/src/pages/ureport/index.jsx +22 -0
  186. package/src/pages/userCenter/ChangePassword.jsx +63 -0
  187. package/src/pages/userCenter/index.jsx +90 -0
  188. package/src/pages/userCenter/manual.jsx +59 -0
  189. package/src/pages/userCenter/message.jsx +105 -0
  190. package/src/style/global.less +51 -0
@@ -0,0 +1,97 @@
1
+ import React from "react";
2
+ import {Empty, Modal, Skeleton, Table, Typography} from "antd";
3
+ import {Gap, HttpUtils,} from "../../framework";
4
+
5
+ /**
6
+ * 查看流程处理情况(不含表单)
7
+ */
8
+ export class ViewFlowableInstanceProgress extends React.Component {
9
+
10
+ state = {
11
+ instanceCommentList: [],
12
+ vars: {},
13
+
14
+ id: null,
15
+ starter: null,
16
+ startTime: null,
17
+ name: null,
18
+
19
+ data: {
20
+ commentList: [],
21
+ img: null
22
+ },
23
+ loading: true,
24
+
25
+ errorMsg: null
26
+ }
27
+
28
+
29
+ componentDidMount() {
30
+ const {value} = this.props;
31
+ HttpUtils.get("admin/flowable/my/getInstanceInfo", {businessKey: value}).then(rs => {
32
+ this.setState(rs)
33
+ this.setState({data: rs})
34
+ }).catch(e => {
35
+ this.setState({errorMsg: e})
36
+ }).finally(() => {
37
+ this.setState({loading: false})
38
+ })
39
+
40
+ }
41
+
42
+ onImgClick = () => {
43
+ const {data} = this.state
44
+
45
+ const {img} = data
46
+ Modal.info({
47
+ title: '流程图',
48
+ width: '70vw',
49
+ content: <div style={{width: '100%', overflow: 'auto', maxHeight: '80vh'}}><img src={img}/></div>
50
+ })
51
+ };
52
+
53
+ render() {
54
+ if (this.state.errorMsg) {
55
+ return <Empty description={this.state.errorMsg}></Empty>
56
+ }
57
+
58
+ const {data, loading} = this.state
59
+ const {commentList, img} = data
60
+ if (loading) {
61
+ return <Skeleton/>
62
+ }
63
+
64
+
65
+ return <>
66
+ <Typography.Title level={4}>{data.name}</Typography.Title>
67
+ <Typography.Text type="secondary">{data.starter} &nbsp;&nbsp; {data.startTime}</Typography.Text>
68
+ <Gap></Gap>
69
+ <img src={img} style={{maxWidth: '100%'}}
70
+ onClick={this.onImgClick}/>
71
+ <Gap></Gap>
72
+ <Table dataSource={commentList}
73
+
74
+ size='small'
75
+ pagination={false}
76
+ rowKey='id'
77
+ columns={[
78
+ {
79
+ dataIndex: 'content',
80
+ title: '操作'
81
+ },
82
+ {
83
+ dataIndex: 'user',
84
+ title: '处理人'
85
+ },
86
+ {
87
+ dataIndex: 'time',
88
+ title: '处理时间'
89
+ },
90
+ ]}
91
+ />
92
+ </>
93
+
94
+ }
95
+
96
+ }
97
+
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import {Button} from "antd";
3
+ import {MessageUtils,} from "../utils";
4
+ import {ViewStringProps} from "./ViewProps";
5
+ import {ViewFlowableInstanceProgress} from "./ViewFlowableInstanceProgress";
6
+
7
+
8
+ export class ViewFlowableInstanceProgressButton extends React.Component<ViewStringProps,any>{
9
+ state = {
10
+ open:false,
11
+ }
12
+
13
+ onClick = () => {
14
+ console.log('点击追踪流程')
15
+ let content = <ViewFlowableInstanceProgress value={this.props.value} />;
16
+ MessageUtils.alert(content,{
17
+ title:'流程审批信息',
18
+ width:800
19
+ })
20
+ };
21
+ render() {
22
+ return <Button onClick={this.onClick} size='small'>追踪流程</Button>
23
+ }
24
+
25
+
26
+ }
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import {Space} from "antd";
3
+ import {EyeInvisibleOutlined, EyeOutlined} from "@ant-design/icons";
4
+ import {ViewProps, ViewStringProps} from "./ViewProps";
5
+
6
+ export class ViewPassword extends React.Component<ViewStringProps,any> {
7
+
8
+ state = {
9
+ visible: false
10
+ }
11
+
12
+ render() {
13
+ let v = this.props.value;
14
+ if (v == null) {
15
+ return null
16
+ }
17
+ let visible = this.state.visible;
18
+ return <Space>
19
+ <span>{this.state.visible ? v : '******'}</span>
20
+ <a onClick={() => this.setState({visible: !visible})}>
21
+ {visible ? <EyeOutlined/> : <EyeInvisibleOutlined/>}
22
+ </a>
23
+ </Space>
24
+ }
25
+ }
@@ -0,0 +1,11 @@
1
+ export interface ViewProps {
2
+ value?: any;
3
+ }
4
+
5
+ export interface ViewStringProps {
6
+ value: string;
7
+ }
8
+
9
+ export interface ViewBooleanProps {
10
+ value: boolean;
11
+ }
@@ -0,0 +1,6 @@
1
+ // 查看组件,主要是value 属性
2
+ export * from './ViewPassword';
3
+ export * from './ViewBoolean';
4
+ export * from './ViewApproveStatus'
5
+ export * from './ViewFlowableInstanceProgress'
6
+ export * from './ViewFlowableInstanceProgressButton'
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./layouts"
2
+ export * from "./framework"
@@ -0,0 +1,22 @@
1
+ // @ts-ignore
2
+ import React from "react";
3
+
4
+ declare type PageRenderProps = {
5
+
6
+ /**
7
+ * 路径 如 /flowable/task/form
8
+ */
9
+ pathname: string;
10
+ /***
11
+ * 搜索参数 如 /?id=1
12
+ */
13
+ search?:string;
14
+
15
+ /***
16
+ * 是否把location信息透传到真正页面
17
+ */
18
+ passLocation?: boolean
19
+ };
20
+
21
+ export class PageRender extends React.Component<PageRenderProps, any> {
22
+ }
@@ -0,0 +1,90 @@
1
+ import {matchRoutes, useAppData} from "umi";
2
+ import React from "react";
3
+ import {Result} from "antd";
4
+ import {UrlUtils} from "../framework";
5
+
6
+ /**
7
+ * 通过指定 pathname 渲染页面
8
+ * @param props
9
+ * 为了规范,接收参数何router保持一致,
10
+ * pathname: 路径 如 /flowable/task/form
11
+ * search:搜索参数 如 /?id=1
12
+ *
13
+ * passLocation: 是否把location信息透传到真正页面
14
+ *
15
+ * @returns {React.JSX.Element|*}
16
+ * @constructor
17
+ */
18
+
19
+ let APP_DATA_CACHE = null
20
+
21
+
22
+ /**
23
+ * 写函数组件主要为了使用hooks
24
+ * @param props
25
+ * @returns {Element}
26
+ * @constructor
27
+ */
28
+ export function PageRender(props) {
29
+ let {pathname, search, passLocation} = props
30
+
31
+ let appData = useAppData()
32
+ if(Object.keys(appData).length === 0){
33
+ appData = APP_DATA_CACHE
34
+ }else {
35
+ APP_DATA_CACHE = appData;
36
+ }
37
+
38
+ return <_PageRender appData={appData} pathname={pathname} search={search}
39
+ passLocation={passLocation}/>
40
+ }
41
+
42
+ class _PageRender extends React.Component {
43
+
44
+ render() {
45
+ if (this.props.passLocation) {
46
+ return this.passLocationRender()
47
+ }
48
+ return this.defaultRender()
49
+ }
50
+
51
+ passLocationRender = () => {
52
+ let {pathname, search, appData} = this.props
53
+
54
+ const map = appData.routeComponents
55
+ const key = pathname.substring(1); // 移除第一个斜杠
56
+ let componentType = map[key] || map[key + '/index']
57
+ if (componentType) {
58
+ let params =search ? UrlUtils.getParams(search): {}
59
+ const location = {pathname, search, params}
60
+ return React.createElement(componentType, {location});
61
+ }
62
+ };
63
+
64
+
65
+ defaultRender = () => {
66
+ let {pathname, appData} = this.props
67
+ let matchArr = matchRoutes(appData.clientRoutes, pathname)
68
+
69
+ if (matchArr != null) {
70
+ if (pathname === '/') {
71
+ // 匹配结果为1,表示未定义index.jsx ,导致死循环
72
+ if (matchArr.length === 1) { // 如果项目中没有定义index.jsx
73
+ return <Result icon={null} title='未定义首页'></Result>
74
+ }
75
+ }
76
+ // 取最匹配的那个
77
+ const mathResult = matchArr[matchArr.length - 1].route
78
+ if(mathResult){
79
+ return mathResult.element;
80
+ }
81
+ }
82
+
83
+ // 如果实在找不到页面组件,则404
84
+ return <Result
85
+ status={404}
86
+ title='页面不存在!'
87
+ subTitle={<div>路由地址:{pathname}</div>}
88
+ />
89
+ };
90
+ }
@@ -0,0 +1,104 @@
1
+ import {Badge, Dropdown} from "antd";
2
+ import {NotificationOutlined, QuestionCircleOutlined, SettingOutlined, UserOutlined} from "@ant-design/icons";
3
+ import React from "react";
4
+ import {history} from "umi";
5
+ import {DeviceUtils, HttpUtils, MessageUtils, PageUtils, SysUtils} from "../../framework";
6
+
7
+
8
+ const ID = 'header-right';
9
+ export default class HeaderRight extends React.Component {
10
+
11
+ state = {
12
+ isMobileDevice: false
13
+ };
14
+
15
+ componentDidMount() {
16
+ document.dispatchEvent(new CustomEvent('componentDidMount', {detail: ID}))
17
+ if (DeviceUtils.isMobileDevice()) {
18
+ this.setState({isMobileDevice: true})
19
+ }
20
+ }
21
+
22
+
23
+
24
+ logout = () => {
25
+ HttpUtils.post('admin/auth/logout').then(async () => {
26
+ localStorage.clear()
27
+ await MessageUtils.alert('退出登录成功');
28
+ history.replace('/login')
29
+ }).catch(async e => {
30
+ let confirm = await MessageUtils.confirm('退出登录失败,是否清空缓存');
31
+ if (confirm) {
32
+ localStorage.clear();
33
+ history.replace('/login')
34
+ }
35
+ })
36
+ }
37
+
38
+ userCenter = () => {
39
+ PageUtils.open('/userCenter', '个人中心')
40
+ }
41
+
42
+ render() {
43
+ const info = SysUtils.getLoginInfo()
44
+
45
+ if (this.state.isMobileDevice) {
46
+ return <div className='header-right'>
47
+ <a onClick={this.logout}>退出</a>
48
+ </div>
49
+ }
50
+
51
+ return <div className='header-right'>
52
+
53
+ <div className='item'>
54
+ <UserOutlined/> {info.name}
55
+ </div>
56
+
57
+
58
+ <div className='item' onClick={() => PageUtils.open('/userCenter/message', '我的消息')}>
59
+ <Badge count={info.messageCount} size="small">
60
+ <NotificationOutlined/>
61
+ </Badge>
62
+ </div>
63
+
64
+ <div className='item' title='操作手册' onClick={() => PageUtils.open('/userCenter/manual', '操作手册')}>
65
+ <QuestionCircleOutlined/>
66
+ </div>
67
+
68
+
69
+ <div className='item'>
70
+
71
+ <Dropdown menu={{
72
+ onClick: ({key}) => {
73
+ switch (key) {
74
+ case 'userCenter':
75
+ this.userCenter()
76
+ break;
77
+ case 'logout':
78
+ this.logout();
79
+ break;
80
+ case 'about':
81
+ this.about()
82
+ break
83
+ }
84
+ },
85
+ items: [
86
+ {key: 'userCenter', label: '个人中心'},
87
+ {key: 'about', label: '关于系统'},
88
+ {key: 'logout', label: '退出登录'},
89
+
90
+ ]
91
+ }}><SettingOutlined/>
92
+
93
+ </Dropdown>
94
+
95
+ </div>
96
+
97
+ </div>
98
+ }
99
+
100
+
101
+ about = () => {
102
+ history.push("/about")
103
+ }
104
+ }
@@ -0,0 +1,158 @@
1
+ import React from "react";
2
+ import {withRouter} from "umi";
3
+ import {Tabs} from "antd";
4
+ import {PageRender} from "../PageRender";
5
+ import {PageUtils} from "../../framework";
6
+
7
+ class TabPageRender extends React.Component {
8
+
9
+ state = {
10
+ active: null,
11
+ urlLabelMap: {},
12
+ tabs: [],
13
+ }
14
+
15
+ componentDidMount() {
16
+ const url = this.getUrl(this.props)
17
+ this.onUrlChange(url);
18
+
19
+ document.addEventListener('close-page-event', (e)=>{
20
+ const url = e.detail.url
21
+ this.onRemove(url)
22
+ })
23
+ }
24
+
25
+ componentDidUpdate(prevProps, prevState, snapshot) {
26
+ const url = this.getUrl(this.props)
27
+ const pUrl = this.getUrl(prevProps)
28
+
29
+ if (url !== pUrl) {
30
+ this.onUrlChange(url);
31
+ }
32
+ }
33
+
34
+ onUrlChange = url => {
35
+ const {location} = this.props
36
+
37
+ const {pathname, search} = location
38
+ let {tabs} = this.state
39
+
40
+ const old = tabs.find(t => t.key === url)
41
+ if (old == null) {
42
+ const cmp = <PageRender pathname={pathname} search={search}/>
43
+ let label = this.getLabel(pathname);
44
+ tabs.push({
45
+ key: url,
46
+ label: label,
47
+ children: cmp
48
+ });
49
+ this.setState({tabs: [...tabs]})
50
+ }else {
51
+ const menu = this.props.pathMenuMap[pathname]
52
+ if (menu && menu.refreshOnTabClick) {
53
+ this.refresh(pathname)
54
+ }
55
+ }
56
+
57
+ this.setState({active: url})
58
+ };
59
+
60
+ getLabel(path) {
61
+ if (path === '/') {
62
+ return '首页'
63
+ }
64
+ let label = PageUtils.currentLabel();
65
+
66
+ if (!label) {
67
+ const menu = this.props.pathMenuMap[path]
68
+ if (menu) {
69
+ return menu.name
70
+ }
71
+ }
72
+
73
+ return label;
74
+ }
75
+
76
+
77
+ render() {
78
+ let {tabs} = this.state
79
+ if (tabs.length === 0) {
80
+ return null
81
+ }
82
+
83
+ return <>
84
+ <Tabs
85
+ items={tabs}
86
+ activeKey={this.state.active}
87
+ onChange={this.onChange}
88
+ onEdit={this.onRemove}
89
+
90
+ hideAdd
91
+ size='small'
92
+ type='editable-card'
93
+ style={{background: 'white'}}
94
+ rootClassName='tmgg-layout-tabs'
95
+
96
+ onTabClick={this.onTabClick}
97
+
98
+ >
99
+ </Tabs>
100
+ </>
101
+ }
102
+
103
+ lastTabClickTime = 0
104
+ onTabClick = (key, event) => {
105
+ let now = new Date().getTime();
106
+ let doubleClick = now - this.lastTabClickTime < 300;
107
+ // 双击时刷新
108
+ if (doubleClick) {
109
+ this.refresh(key);
110
+ }
111
+
112
+ this.lastTabClickTime = now
113
+ };
114
+
115
+ refresh = key => {
116
+ const tabs = this.state.tabs;
117
+ const tab = tabs.find(t => t.key === key)
118
+ if(tab != null){
119
+ const old = tab.children
120
+ if(old != null){
121
+ console.log('准备刷新:', key)
122
+ tab.children = '刷新中...'
123
+ this.setState({tabs}, () => {
124
+ console.log('刷新节点', tab)
125
+ tab.children = old
126
+ this.setState({tabs})
127
+ })
128
+ }
129
+ }
130
+ };
131
+
132
+ onChange = url => {
133
+ if (url !== this.state.active) {
134
+ this.props.history.push(url)
135
+ }
136
+ };
137
+
138
+ onRemove = url => {
139
+ let {tabs} = this.state
140
+ tabs = tabs.filter(t => t.key !== url)
141
+
142
+ this.setState({tabs})
143
+ if (tabs.length > 0) {
144
+ this.setState({active: tabs[tabs.length - 1].key})
145
+ }
146
+ };
147
+
148
+ getUrl = props => {
149
+ const {location} = props
150
+ const {pathname, search} = location
151
+ return pathname + search;
152
+ }
153
+
154
+ }
155
+
156
+
157
+ // 让组件有路由相关的参数,如 this.props.location
158
+ export default withRouter(TabPageRender)