@jiangood/springboot-admin-starter 0.0.8 → 0.1.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 (31) hide show
  1. package/package.json +3 -2
  2. package/src/framework/components/view/ViewBooleanEnableDisable.tsx +1 -1
  3. package/src/framework/field-components/FieldDateRange.jsx +4 -2
  4. package/src/framework/field-components/FieldNumberRange.d.ts +13 -0
  5. package/src/framework/field-components/FieldNumberRange.jsx +59 -0
  6. package/src/framework/field-components/index.ts +1 -0
  7. package/src/framework/field-components/system/OrgTree.tsx +1 -1
  8. package/src/framework/utils/MessageUtils.tsx +53 -92
  9. package/src/framework/utils/StringUtils.ts +9 -7
  10. package/src/framework/utils/system/PageUtils.ts +46 -36
  11. package/src/framework/view-components/ViewApproveStatus.tsx +26 -0
  12. package/src/framework/view-components/ViewBoolean.tsx +6 -0
  13. package/src/framework/view-components/ViewFlowableInstanceProgress.d.ts +12 -0
  14. package/src/framework/view-components/ViewFlowableInstanceProgress.jsx +97 -0
  15. package/src/framework/view-components/ViewFlowableInstanceProgressButton.tsx +26 -0
  16. package/src/framework/view-components/{ViewPassword.jsx → ViewPassword.tsx} +2 -1
  17. package/src/framework/view-components/ViewProps.ts +11 -0
  18. package/src/framework/view-components/index.ts +6 -0
  19. package/src/layouts/index.jsx +3 -3
  20. package/src/pages/flowable/InstanceInfo.jsx +6 -4
  21. package/src/pages/flowable/design/index.jsx +50 -5
  22. package/src/pages/flowable/instance/view.jsx +15 -0
  23. package/src/pages/flowable/monitor/task.jsx +12 -7
  24. package/src/pages/flowable/task/index.jsx +4 -5
  25. package/src/pages/index.jsx +2 -0
  26. package/src/pages/system/role/index.jsx +7 -13
  27. package/src/pages/system/user/index.jsx +2 -1
  28. package/src/pages/userCenter/index.jsx +1 -1
  29. package/src/.npmignore +0 -6
  30. package/src/framework/view-components/ViewBoolean.jsx +0 -4
  31. package/src/framework/view-components/index.js +0 -3
package/package.json CHANGED
@@ -29,10 +29,11 @@
29
29
  "description": "springboot-admin-starter",
30
30
  "files": [
31
31
  "src/*",
32
- "config/dist/*"
32
+ "config/dist/*",
33
+ "!src/.umi"
33
34
  ],
34
35
  "main": "src/index.ts",
35
- "version": "0.0.8",
36
+ "version": "0.1.0",
36
37
  "scripts": {
37
38
  "dev": "umi dev",
38
39
  "build": "tsc --outDir config/dist --skipLibCheck --noEmitOnError false config/index.ts"
@@ -15,6 +15,6 @@ export class ViewBooleanEnableDisable extends React.Component<ViewBooleanEnableD
15
15
  return null;
16
16
  }
17
17
 
18
- return value ? <Tag color={"green"}>启动</Tag> : <Tag color={"red"}>禁用</Tag>;
18
+ return value ? <Tag color={"green"}>启用</Tag> : <Tag color={"red"}>禁用</Tag>;
19
19
  }
20
20
  }
@@ -4,7 +4,9 @@
4
4
  import React from "react";
5
5
  import dayjs from "dayjs";
6
6
  import {DatePicker, TimePicker} from "antd";
7
+ import {StringUtils} from "../utils";
7
8
 
9
+ const SP = StringUtils.ISO_SPLITTER;
8
10
 
9
11
  export class FieldDateRange extends React.Component {
10
12
  static defaultProps = {
@@ -82,7 +84,7 @@ export class FieldDateRange extends React.Component {
82
84
  return null;
83
85
  }
84
86
 
85
- const arr = v.split("/")
87
+ const arr = v.split(SP)
86
88
  let s1 = arr[0];
87
89
  let s2 = arr[1];
88
90
  return [dayjs(s1), dayjs(s2)]
@@ -95,7 +97,7 @@ export class FieldDateRange extends React.Component {
95
97
  const s1 = d1 ? d1.format(fmt) : ""
96
98
  const s2 = d2 ? d2.format(fmt) : "";
97
99
 
98
- return s1 + '/' + s2
100
+ return s1 + SP + s2
99
101
  }
100
102
 
101
103
  }
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ export interface FieldNumberRangeProps {
4
+ value?: string;
5
+ onChange?: (value: string) => void;
6
+ }
7
+
8
+ /**
9
+ * 数字的百分数输入框
10
+ */
11
+ export class FieldNumberRange extends React.Component<FieldNumberRangeProps, any> {
12
+ }
13
+
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ import {InputNumber} from "antd";
3
+ import {StringUtils} from "../utils";
4
+
5
+
6
+ const SP = StringUtils.ISO_SPLITTER;
7
+
8
+ export class FieldNumberRange extends React.Component {
9
+
10
+
11
+ onChangeA = (a) => {
12
+ const {b} = this.parse(this.props.value)
13
+ this.props.onChange && this.props.onChange(this.merge(a, b))
14
+ }
15
+ onChangeB = (b) => {
16
+ const {a} = this.parse(this.props.value)
17
+ this.props.onChange && this.props.onChange(this.merge(a, b))
18
+ }
19
+
20
+ merge(a, b) {
21
+ if (a == null) {
22
+ a = ''
23
+ }
24
+ if (b == null) {
25
+ b = ''
26
+ }
27
+ return a + SP + b;
28
+ }
29
+
30
+ parse(v) {
31
+ if (v == null) {
32
+ return {a: null, b: null}
33
+ }
34
+ const arr = v.split(SP);
35
+ return {a: arr[0], b: arr[1]}
36
+ }
37
+
38
+ componentDidMount() {
39
+ let {value, defaultValue} = this.props
40
+ if (value == null) {
41
+ this.props.onChange && this.props.onChange(defaultValue)
42
+ }
43
+
44
+ }
45
+
46
+
47
+ render() {
48
+ let {value, defaultValue} = this.props
49
+ if (value == null) {
50
+ value = defaultValue
51
+ }
52
+ const {a, b} = this.parse(value)
53
+
54
+ return <div style={{display: 'flex', alignItems: 'center'}}>
55
+ <InputNumber value={a} onChange={this.onChangeA}/> - <InputNumber value={b} onChange={this.onChangeB}/>
56
+ </div>
57
+ }
58
+
59
+ }
@@ -11,6 +11,7 @@ export * from './FieldRemoteTreeSelectMultiple'
11
11
  export * from './FieldBoolean';
12
12
  export * from './FieldDate';
13
13
  export * from './FieldDateRange';
14
+ export * from './FieldNumberRange';
14
15
  export * from './FieldTable'
15
16
  export * from './FieldTableSelect'
16
17
  export * from './FieldSysOrgTreeSelect'
@@ -15,7 +15,7 @@ export class OrgTree extends React.Component<any, any> {
15
15
 
16
16
 
17
17
  componentDidMount() {
18
- HttpUtils.get('admin/sysOrg/unitTree').then(tree => {
18
+ HttpUtils.get('admin/sysOrg/deptTree').then(tree => {
19
19
  this.setState({treeData: tree,treeDataLoading: false})
20
20
  })
21
21
  }
@@ -1,38 +1,35 @@
1
- import {Input, message, Modal, notification} from 'antd';
1
+ import {Form, Input, InputNumber, message, Modal} from 'antd';
2
2
  import type {ModalFuncProps} from 'antd/es/modal/interface';
3
- import type {ArgsProps, NotificationPlacement} from 'antd/es/notification/interface';
4
3
  import React from 'react';
5
- import {ThemeUtils} from './system/ThemeUtils';
4
+ import {MessageInstance} from "antd/lib/message/interface";
5
+ import {HookAPI} from "antd/lib/modal/useModal";
6
6
 
7
7
 
8
- let color = ThemeUtils.getColor('primary-color');
9
- const buttonStyles = {
10
- root: {
11
- backgroundColor: color
12
- }
13
- }
14
8
 
15
9
  /**
16
10
  * 消息工具类 (MsgUtils)
17
11
  * 封装了 Ant Design 的 Modal, message, 和 notification 静态方法
18
12
  */
19
13
  export class MessageUtils {
20
- // --- Antd Modal 封装 (Alert/Confirm/Prompt) ---
21
14
 
22
15
  /**
23
16
  * 弹出 Alert 提示框
24
17
  */
25
- static alert(content: React.ReactNode, config?: Omit<ModalFuncProps, 'content' | 'icon' | 'onOk' | 'onCancel'>) {
26
- Modal.info({
27
- title: '提示',
28
- content,
29
- okText: '确定',
30
- icon: null,
31
- okButtonProps: {
32
- styles: buttonStyles
33
- },
34
- ...config,
35
- });
18
+ static alert(content: any, config?: Omit<ModalFuncProps, 'content' | 'icon' | 'onOk' | 'onCancel'>) {
19
+ return new Promise(resolve => {
20
+ this.modalApi.info({
21
+ title: '提示',
22
+ content,
23
+ okText: '确定',
24
+ onOk: (close)=>{
25
+ close()
26
+ resolve()
27
+ },
28
+ icon: null,
29
+ ...config,
30
+ });
31
+ })
32
+
36
33
  }
37
34
 
38
35
  /**
@@ -40,16 +37,13 @@ export class MessageUtils {
40
37
  */
41
38
  static confirm(content: React.ReactNode, config?: Omit<ModalFuncProps, 'content' | 'icon' | 'onOk' | 'onCancel'>) {
42
39
  return new Promise((resolve) => {
43
- Modal.confirm({
40
+ this.modalApi.confirm({
44
41
  title: '确认操作',
45
42
  content,
46
43
  okText: '确定',
47
44
  cancelText: '取消',
48
45
  onOk: () => resolve(true),
49
46
  onCancel: () => resolve(false),
50
- okButtonProps: {
51
- styles: buttonStyles
52
- },
53
47
  ...config,
54
48
  });
55
49
  })
@@ -57,32 +51,33 @@ export class MessageUtils {
57
51
  }
58
52
 
59
53
  /**
60
- * 弹出 Prompt 输入框对话框
54
+ * 弹出 Prompt 输入框对话框, 如果默认值是数字, 则使用 InputNumber 输入框
61
55
  */
62
- static prompt(message: React.ReactNode, initialValue?: string, placeholder?: string, config?: Omit<ModalFuncProps, 'content' | 'title' | 'icon' | 'onOk'>) {
56
+ static prompt(message: React.ReactNode, initialValue?: string|number, placeholder?: string, config?: Omit<ModalFuncProps, 'content' | 'title' | 'icon' | 'onOk'>) {
57
+ const isNumber = typeof initialValue === 'number';
63
58
  return new Promise((resolve) => {
64
59
  const ref = React.createRef()
65
- Modal.confirm({
60
+ this.modalApi.confirm({
66
61
  icon: null,
67
62
  title: '提示',
68
63
  content: <div>
69
64
  <div style={{marginBottom: 4}}>{message}</div>
70
- <Input ref={ref} placeholder={placeholder}/>
65
+ <Form ref={ref}>
66
+ <Form.Item name='inputValue' initialValue={initialValue}>
67
+ {isNumber ? <InputNumber placeholder={placeholder}/> : <Input placeholder={placeholder}/>}
68
+ </Form.Item>
69
+ </Form>
71
70
  </div>,
72
71
  okText: '确定',
73
72
  cancelText: '取消',
74
73
  onOk: () => {
75
- const inputInstance = ref.current;
76
- const inputElement = inputInstance.input;
77
- const inputValue = inputElement.value;
78
- resolve(inputValue)
74
+ const form = ref.current;
75
+ const values= form.getFieldsValue()
76
+ resolve(values.inputValue)
79
77
  },
80
78
  onCancel: () => {
81
79
  resolve()
82
80
  },
83
- okButtonProps: {
84
- styles: buttonStyles
85
- },
86
81
  ...config,
87
82
  });
88
83
  })
@@ -94,89 +89,55 @@ export class MessageUtils {
94
89
  * 成功消息
95
90
  */
96
91
  static success(content: React.ReactNode, duration: number = 3) {
97
- message.success(content, duration);
92
+ this.messageApi.success(content, duration);
98
93
  }
99
94
 
100
95
  /**
101
96
  * 错误消息
102
97
  */
103
98
  static error(content: React.ReactNode, duration: number = 3) {
104
- message.error(content, duration);
99
+ this.messageApi.error(content, duration);
105
100
  }
106
101
 
107
102
  /**
108
103
  * 警告消息
109
104
  */
110
105
  static warning(content: React.ReactNode, duration: number = 3) {
111
- message.warning(content, duration);
106
+ this.messageApi.warning(content, duration);
112
107
  }
113
108
 
114
109
  /**
115
110
  * 通用消息
116
111
  */
117
112
  static info(content: React.ReactNode, duration: number = 3) {
118
- message.info(content, duration);
113
+ this.messageApi.info(content, duration);
119
114
  }
120
115
 
121
116
  /**
122
117
  * 弹出 Loading 提示
123
118
  */
124
119
  static loading(content: React.ReactNode = '正在加载...', duration?: number) {
125
- return message.loading({content, duration: duration === undefined ? 0 : duration});
120
+ return this.messageApi.loading({content, duration: duration === undefined ? 0 : duration});
126
121
  }
127
122
 
128
- /**
129
- * 立即关闭所有 message 提示
130
- */
131
- static hideAll() {
132
- message.destroy();
123
+ static config(messageApi: MessageInstance, modalApi: HookAPI) {
124
+ this.messageApi = messageApi;
125
+ this.modalApi = modalApi;
133
126
  }
134
127
 
135
- // --- Antd Notification 封装 (通知提醒框) ---
136
-
137
- /**
138
- * 弹出右上角通知提醒框
139
- */
140
- static notify(
141
- message: React.ReactNode,
142
- description: React.ReactNode,
143
- type: 'success' | 'error' | 'info' | 'warning' | 'open' | 'config' = 'open',
144
- placement: NotificationPlacement = 'topRight',
145
- config?: Omit<ArgsProps, 'message' | 'description' | 'placement'>,
146
- ) {
147
- const notifyFunc = notification[type];
148
- notifyFunc({
149
- message,
150
- description,
151
- placement,
152
- ...config,
153
- });
154
- }
155
-
156
- /**
157
- * 弹出成功通知
158
- */
159
- static notifySuccess(message: React.ReactNode, description: React.ReactNode, placement?: NotificationPlacement, config?: Omit<ArgsProps, 'message' | 'description' | 'placement'>) {
160
- MessageUtils.notify(message, description, 'success', placement, config);
161
- }
162
-
163
- /**
164
- * 弹出失败通知
165
- */
166
- static notifyError(message: React.ReactNode, description: React.ReactNode, placement?: NotificationPlacement, config?: Omit<ArgsProps, 'message' | 'description' | 'placement'>) {
167
- MessageUtils.notify(message, description, 'error', placement, config);
168
- }
169
-
170
- /**
171
- * 弹出警告通知
172
- */
173
- static notifyWarning(
174
- message: React.ReactNode,
175
- description: React.ReactNode,
176
- placement?: NotificationPlacement,
177
- config?: Omit<ArgsProps, 'message' | 'description' | 'placement'>,
178
- ) {
179
- MessageUtils.notify(message, description, 'warning', placement, config);
180
- }
128
+ private static modalApi:HookAPI = null;
129
+ private static messageApi:MessageInstance = null;
181
130
  }
182
131
 
132
+ /**
133
+ * antd6 推荐使用这个hooks,这里统一设置, 供公共layout使用
134
+ * @constructor
135
+ */
136
+ export function MessageHolder(){
137
+ const [modalApi, modalContextHolder] = Modal.useModal();
138
+ const [messageApi, messageContextHolder] = message.useMessage();
139
+ MessageUtils.config(messageApi,modalApi);
140
+ return <>
141
+ {modalContextHolder} {messageContextHolder}
142
+ </>
143
+ }
@@ -3,6 +3,8 @@
3
3
  */
4
4
  export class StringUtils {
5
5
 
6
+ static readonly ISO_SPLITTER = "/";
7
+
6
8
  /**
7
9
  * 移除字符串前缀
8
10
  * @param str 原始字符串
@@ -144,16 +146,16 @@ export class StringUtils {
144
146
 
145
147
  /**
146
148
  * 截取字符串,返回子字符串前面的部分。如果不包含,则原样返回
147
- * @param s 原始字符串
149
+ * @param str 原始字符串
148
150
  * @param sub 分隔符
149
151
  * @returns 分隔符前面的字符串,或原字符串
150
152
  */
151
- static subBefore(s: string | null | undefined, sub: string): string | null | undefined {
152
- if (s == null) {
153
- return s;
153
+ static subBefore(str: string | null | undefined, sub: string): string {
154
+ if (str == null) {
155
+ return "";
154
156
  }
155
- const index = s.indexOf(sub);
156
- return index === -1 ? s : s.substring(0, index);
157
+ const index = str.indexOf(sub);
158
+ return index === -1 ? str : str.substring(0, index);
157
159
  }
158
160
 
159
161
  /**
@@ -380,7 +382,7 @@ export class StringUtils {
380
382
  * @param str
381
383
  * @param sp
382
384
  */
383
- static split(str: any, sp: string):null|string[] {
385
+ static split(str: any, sp: string):null|string[]|undefined {
384
386
  if(str == null || str.length === 0){
385
387
  return undefined
386
388
  }
@@ -1,6 +1,7 @@
1
- import { history } from "umi";
1
+ import {history} from "umi";
2
2
  import {StringUtils} from "../StringUtils";
3
3
  import {UrlUtils} from "../UrlUtils";
4
+ import {MessageUtils} from "../MessageUtils";
4
5
 
5
6
  /**
6
7
  * 页面相关的工具类,主要用于路由、URL参数和页面跳转操作。
@@ -111,43 +112,52 @@ export class PageUtils {
111
112
  * @param path 要跳转的路径。
112
113
  * @param label 可选,用于在 URL 中添加一个 '_label' 参数。
113
114
  */
114
- static open(path: string, label: string ='临时'): void {
115
- let targetPath = path;
116
- if(label) {
117
- // 假设 UrlUtil.setParam(url, key, value) 存在并返回设置参数后的 URL
118
- targetPath = UrlUtils.setParam(targetPath, '_label', label);
115
+ static open(path: string, label: string = '临时'): void {
116
+ let targetPath = path;
117
+ if (label) {
118
+ // 假设 UrlUtil.setParam(url, key, value) 存在并返回设置参数后的 URL
119
+ targetPath = UrlUtils.setParam(targetPath, '_label', label);
120
+ }
121
+ history.push(targetPath);
119
122
  }
120
- history.push(targetPath);
121
- }
122
123
 
123
- /**
124
- * 打开一个不带菜单、Header 等布局元素的页面。
125
- * 通过在 URL 中添加 '_noLayout=true' 参数实现。
126
- * @param path 要跳转的路径。
127
- */
128
- static openNoLayout(path: string): void {
129
- // 假设 UrlUtil.setParam(url, key, value) 存在
130
- const targetPath = UrlUtils.setParam(path, '_noLayout', true);
131
- history.push(targetPath);
132
- }
133
124
 
134
- /**
135
- * 获取当前 URL 参数中名为 '_label' 的值。
136
- * @returns {string | undefined} '_label' 参数的值。
137
- */
138
- static currentLabel(): string | undefined {
139
- // currentParams 返回 Record<string, string | undefined>
140
- return this.currentParams()['_label'];
141
- }
125
+ /**
126
+ * 打开一个不带菜单、Header 等布局元素的页面。
127
+ * 通过在 URL 中添加 '_noLayout=true' 参数实现。
128
+ * @param path 要跳转的路径。
129
+ */
130
+ static openNoLayout(path: string): void {
131
+ // 假设 UrlUtil.setParam(url, key, value) 存在
132
+ const targetPath = UrlUtils.setParam(path, '_noLayout', true);
133
+ history.push(targetPath);
134
+ }
135
+
136
+ /**
137
+ * 获取当前 URL 参数中名为 '_label' 的值。
138
+ * @returns {string | undefined} '_label' 参数的值。
139
+ */
140
+ static currentLabel(): string | undefined {
141
+ // currentParams 返回 Record<string, string | undefined>
142
+ return this.currentParams()['_label'];
143
+ }
144
+
145
+ /**
146
+ * 发送一个自定义事件来关闭当前页面。
147
+ * 依赖外部监听 'close-page-event' 事件的处理机制。
148
+ */
149
+ static closeCurrent() {
150
+ const event = new CustomEvent<{ url: string }>('close-page-event', {
151
+ detail: {url: PageUtils.currentUrl()}
152
+ });
153
+ document.dispatchEvent(event);
154
+ }
155
+
156
+ static closeCurrentAndOpenPage(alertMessage:string,path:string,label:string){
157
+ MessageUtils.alert(alertMessage).then(()=>{
158
+ this.closeCurrent()
159
+ this.open(path,label)
160
+ })
161
+ }
142
162
 
143
- /**
144
- * 发送一个自定义事件来关闭当前页面。
145
- * 依赖外部监听 'close-page-event' 事件的处理机制。
146
- */
147
- static closeCurrent(): void {
148
- const event = new CustomEvent<{ url: string }>('close-page-event', {
149
- detail: { url: PageUtils.currentUrl() }
150
- });
151
- document.dispatchEvent(event);
152
- }
153
163
  }
@@ -0,0 +1,26 @@
1
+ import {DictUtils} from "../utils";
2
+ import {Tag} from "antd";
3
+ import {ViewStringProps} from "./ViewProps";
4
+
5
+ interface ViewProps {
6
+ value: String;
7
+ }
8
+
9
+ /**
10
+ * 查看审批状态组件
11
+ * @param props
12
+ * @constructor
13
+ */
14
+ export function ViewApproveStatus(props:ViewStringProps) {
15
+ let {value} = props;
16
+ let txt= DictUtils.dictLabel('approveStatus', value)
17
+
18
+ const colorMap = {
19
+ 'DRAFT': 'orange',
20
+ 'PENDING': 'blue',
21
+ 'APPROVED': 'green',
22
+ 'REJECTED': 'red'
23
+ };
24
+ let color = colorMap[value]
25
+ return <Tag color={color}>{txt}</Tag> ;
26
+ }
@@ -0,0 +1,6 @@
1
+ import {ViewBooleanProps} from "./ViewProps";
2
+
3
+ export function ViewBoolean(props: ViewBooleanProps) {
4
+ let {value} = props;
5
+ return value == null ? null : (value ? '是' : '否')
6
+ }
@@ -0,0 +1,12 @@
1
+ // @ts-ignore
2
+ import React from "react";
3
+ import {ViewProps, ViewStringProps} from "./ViewProps";
4
+
5
+
6
+
7
+ /**
8
+ * 业务标识businessKey
9
+ */
10
+ export class ViewFlowableInstanceProgress extends React.Component<ViewStringProps, any> {
11
+ }
12
+
@@ -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
+ }
@@ -1,8 +1,9 @@
1
1
  import React from "react";
2
2
  import {Space} from "antd";
3
3
  import {EyeInvisibleOutlined, EyeOutlined} from "@ant-design/icons";
4
+ import {ViewProps, ViewStringProps} from "./ViewProps";
4
5
 
5
- export class ViewPassword extends React.Component {
6
+ export class ViewPassword extends React.Component<ViewStringProps,any> {
6
7
 
7
8
  state = {
8
9
  visible: false
@@ -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'
@@ -5,7 +5,7 @@ import {ConfigProvider} from "antd";
5
5
 
6
6
  import {Outlet, withRouter} from "umi";
7
7
  import zhCN from 'antd/locale/zh_CN';
8
- import {ArrUtils, HttpUtils, PageLoading, PageUtils, SysUtils, ThemeUtils,} from "../framework";
8
+ import {ArrUtils, HttpUtils, MessageHolder, PageLoading, PageUtils, SysUtils, ThemeUtils,} from "../framework";
9
9
  import dayjs from 'dayjs';
10
10
  import 'dayjs/locale/zh-cn';
11
11
 
@@ -120,6 +120,8 @@ class _Layouts extends React.Component {
120
120
 
121
121
  {this.renderContent()}
122
122
 
123
+ <MessageHolder />
124
+
123
125
  </ConfigProvider>
124
126
  }
125
127
 
@@ -142,9 +144,7 @@ class _Layouts extends React.Component {
142
144
  return <AdminLayout path={this.state.path} logo={this.props.logo}/>
143
145
  };
144
146
 
145
- renderMessages = () => {
146
147
 
147
- };
148
148
 
149
149
  }
150
150
 
@@ -117,16 +117,18 @@ export default class InstanceInfo extends React.Component {
117
117
  renderForm = () => {
118
118
  const {data} = this.state
119
119
  const {processDefinitionKey, businessKey} = data
120
+ const formKey = this.props.formKey || processDefinitionKey;
121
+ const formName = formKey + 'Form'
120
122
 
121
- let formKey = this.props.formKey || processDefinitionKey + 'Form';
122
- let ExForm = FormRegistryUtils.get(formKey);
123
+ // let formKey = this.props.formKey || processDefinitionKey + 'Form';
124
+ let ExForm = FormRegistryUtils.get(formName);
123
125
  if (!ExForm) {
124
126
  return <div>
125
127
  <p>
126
- 未注册表单,请注册表单 {formKey}。
128
+ 未创建表单 {formName}。
127
129
  </p>
128
130
  <Typography.Text>
129
- 表单路径:src/forms/{formKey}.jsx
131
+ 表单路径:src/forms/{formName}.jsx
130
132
  </Typography.Text>
131
133
  </div>
132
134
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import {Button, Card, message, Space, Splitter} from "antd";
2
+ import {Button, Card, message, Modal, Space, Splitter} from "antd";
3
3
 
4
4
  import 'bpmn-js/dist/assets/diagram-js.css'
5
5
  import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
@@ -9,7 +9,7 @@ import './index.css'
9
9
  import customTranslate from "./customTranslate/customTranslate";
10
10
  import contextPad from "./contextPad";
11
11
  import {CloudUploadOutlined, SaveOutlined} from "@ant-design/icons";
12
- import {HttpUtils, MessageUtils, PageUtils} from "../../../framework";
12
+ import {HttpUtils, MessageUtils, PageUtils, ProTable} from "../../../framework";
13
13
  import 'bpmn-js/dist/assets/bpmn-js.css';
14
14
  import '@bpmn-io/properties-panel/assets/properties-panel.css';
15
15
  import {BpmnPropertiesPanelModule, BpmnPropertiesProviderModule} from 'bpmn-js-properties-panel';
@@ -24,17 +24,18 @@ export default class extends React.Component {
24
24
  state = {
25
25
  id: null,
26
26
  model: null,
27
+
28
+ deployedModal: false
27
29
  }
28
30
 
29
31
  bpmRef = React.createRef()
30
32
 
31
- preXmlRef = React.createRef()
32
33
 
33
34
  async componentDidMount() {
34
35
  let params = PageUtils.currentParams()
35
36
  this.state.id = params.id
36
37
  const rs = await HttpUtils.get('admin/flowable/model/detail', {id: this.state.id})
37
- this.setState({model:rs}, this.initBpmn)
38
+ this.setState({model: rs}, this.initBpmn)
38
39
  }
39
40
 
40
41
  initBpmn = () => {
@@ -52,7 +53,7 @@ export default class extends React.Component {
52
53
  flowablePropertiesProviderModule
53
54
  ],
54
55
  moddleExtensions: {
55
- flowable: flowableJson
56
+ flowable: flowableJson
56
57
  }
57
58
  });
58
59
 
@@ -103,6 +104,10 @@ export default class extends React.Component {
103
104
  <Button onClick={this.showXML}>XML</Button>
104
105
  <Button
105
106
  onClick={() => PageUtils.open('/flowable/test?id=' + this.state.id, "流程测试")}> 测试 </Button>
107
+
108
+ <Button title='查看已部署的历史版本' onClick={() => {
109
+ this.setState({deployedModal: true})
110
+ }}>历史版本</Button>
106
111
  </Space>}>
107
112
 
108
113
 
@@ -117,6 +122,46 @@ export default class extends React.Component {
117
122
  </Splitter>
118
123
 
119
124
 
125
+ <Modal title='已部署版本' width={800} footer={null}
126
+ open={this.state.deployedModal}
127
+ destroyOnHidden
128
+ onCancel={() => this.setState({deployedModal: false})}>
129
+
130
+ <ProTable
131
+ columns={[
132
+ {
133
+ dataIndex: 'key',
134
+ title: '编码'
135
+ },
136
+ {
137
+ dataIndex: 'name',
138
+ title: '名称'
139
+ },
140
+ {
141
+ dataIndex: 'version',
142
+ title: '版本号'
143
+ }, {
144
+ title: '操作',
145
+ dataIndex:'id',
146
+ render:(id)=> {
147
+ return <Button type='primary' onClick={()=>{
148
+ HttpUtils.get('admin/flowable/model/getDefinitionContent',{id}).then(xml=>{
149
+ this.bpmnModeler.importXML(xml)
150
+ this.setState({deployedModal:false})
151
+ })
152
+ }}>加载</Button>
153
+ }
154
+ }
155
+ ]}
156
+ request={params => {
157
+ params.key = this.state.model.key
158
+ return HttpUtils.get('admin/flowable/model/definitionPage', params)
159
+ }}>
160
+
161
+ </ProTable>
162
+
163
+ </Modal>
164
+
120
165
  </Card>
121
166
  }
122
167
 
@@ -0,0 +1,15 @@
1
+ import InstanceInfo from "../InstanceInfo";
2
+ import {Page, PageUtils} from "../../../framework";
3
+ import React from "react";
4
+
5
+ export default class extends React.Component{
6
+
7
+ render() {
8
+ let params = PageUtils.currentParams();
9
+ const {businessKey} = params
10
+ return <Page padding>
11
+ <InstanceInfo businessKey={businessKey} />
12
+ </Page>
13
+ }
14
+
15
+ }
@@ -29,12 +29,20 @@ export default class extends React.Component {
29
29
  actionRef={this.taskTableRef}
30
30
  columns={[
31
31
  {
32
- dataIndex: 'id',
33
- title: '任务标识',
32
+ dataIndex: 'processInstanceName',
33
+ title: '实例名称'
34
34
  },
35
35
  {
36
36
  dataIndex: 'name',
37
- title: '名称',
37
+ title: '任务名称',
38
+ },
39
+ {
40
+ dataIndex: 'assigneeLabel',
41
+ title: '处理人'
42
+ },
43
+ {
44
+ dataIndex: 'id',
45
+ title: '任务标识',
38
46
  },
39
47
 
40
48
  {
@@ -47,10 +55,7 @@ export default class extends React.Component {
47
55
  },
48
56
 
49
57
 
50
- {
51
- dataIndex: 'assigneeLabel',
52
- title: '处理人'
53
- },
58
+
54
59
  {
55
60
  dataIndex: 'startTime',
56
61
  title: '开始时间'
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import {Button, Modal, Tabs} from "antd";
3
- import {HttpUtils, LinkButton, Page, PageLoading, ProTable} from "../../../framework";
3
+ import {HttpUtils, LinkButton, MessageUtils, Page, PageLoading, ProTable} from "../../../framework";
4
4
  import InstanceInfo from "../InstanceInfo";
5
5
 
6
6
 
@@ -186,12 +186,11 @@ export default class extends React.Component {
186
186
  dataIndex: 'option',
187
187
  render: (_, record) => (
188
188
  <Button size='small' onClick={() => {
189
-
190
- Modal.info({
191
- title: '流程信息',
189
+ MessageUtils.alert(<InstanceInfo id={record.id}/>, {
192
190
  width: '80vw',
193
- content: <InstanceInfo id={record.id}/>
191
+ title: '流程信息'
194
192
  })
193
+
195
194
  }}> 查看 </Button>
196
195
  ),
197
196
  },
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import {Card} from "antd";
3
+ import {MessageUtils} from "../framework";
3
4
 
4
5
 
5
6
  export default class extends React.Component {
@@ -7,6 +8,7 @@ export default class extends React.Component {
7
8
  state = {}
8
9
 
9
10
  componentDidMount() {
11
+
10
12
  }
11
13
 
12
14
  render() {
@@ -100,15 +100,15 @@ export default class extends React.Component {
100
100
 
101
101
  return (
102
102
  <ButtonList>
103
- <Button size='small' perm='sysRole:save'
103
+ <Button size='small' perm='sysRole:manage'
104
104
  onClick={() => this.handleEditUser(record)}>用户设置</Button>
105
105
 
106
- <Button size='small' perm='sysRole:save' disabled={record.builtin}
106
+ <Button size='small' perm='sysRole:manage' disabled={record.builtin}
107
107
  onClick={() => PageUtils.open('/system/role/perm?id='+record.id, '角色权限设置')}>权限设置</Button>
108
108
 
109
- <Button size='small' perm='sysRole:save' disabled={record.builtin}
109
+ <Button size='small' perm='sysRole:manage' disabled={record.builtin}
110
110
  onClick={() => this.handleEdit(record)}>编辑</Button>
111
- <Popconfirm perm='sysRole:delete' disabled={record.builtin} title='是否确定删除系统角色'
111
+ <Popconfirm perm='sysRole:manage' disabled={record.builtin} title='是否确定删除系统角色'
112
112
  onConfirm={() => this.handleDelete(record)}>
113
113
  <Button size='small'>删除</Button>
114
114
  </Popconfirm>
@@ -183,12 +183,12 @@ export default class extends React.Component {
183
183
  }
184
184
 
185
185
  render() {
186
- return <Page>
186
+ return <Page padding>
187
187
  <ProTable
188
188
  actionRef={this.tableRef}
189
189
  toolBarRender={() => {
190
190
  return <ButtonList>
191
- <Button perm='sysRole:save' type='primary' onClick={this.handleAdd}>
191
+ <Button perm='sysRole:manage' type='primary' onClick={this.handleAdd}>
192
192
  <PlusOutlined/> 新增
193
193
  </Button>
194
194
  </ButtonList>
@@ -285,8 +285,6 @@ export default class extends React.Component {
285
285
  onOk={this.handleGrantMenu}
286
286
  loading={this.state.menuTreeLoading}
287
287
  >
288
-
289
-
290
288
  <Tree
291
289
  height={600}
292
290
  treeData={this.state.menuTree}
@@ -300,11 +298,7 @@ export default class extends React.Component {
300
298
  titleRender={node=>{
301
299
  return <span title={node.perm} >{node.title}</span>
302
300
  }}
303
- >
304
- </Tree>
305
-
306
-
307
-
301
+ />
308
302
  </Modal>
309
303
  </Page>
310
304
 
@@ -157,7 +157,7 @@ export default class extends React.Component {
157
157
 
158
158
  render() {
159
159
 
160
- return <Page>
160
+ return <Page >
161
161
  <Splitter >
162
162
  <Splitter.Panel defaultSize={400} >
163
163
  <Tabs
@@ -192,6 +192,7 @@ export default class extends React.Component {
192
192
 
193
193
  </ButtonList>
194
194
  }}
195
+ showToolbarSearch
195
196
  request={(params) => {
196
197
  params.orgId = this.state.currentOrgId
197
198
  params.roleId = this.state.currentRoleId
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import {Avatar, Card, Col, Row, Tabs} from "antd";
3
3
  import ChangePassword from "./ChangePassword";
4
- import {Page} from "../../framework";
4
+ import {HttpUtils, Page} from "../../framework";
5
5
 
6
6
  export default class extends React.Component {
7
7
 
package/src/.npmignore DELETED
@@ -1,6 +0,0 @@
1
- node_modules/
2
-
3
- .umi/
4
-
5
- .umi-production/
6
- .umi/
@@ -1,4 +0,0 @@
1
- export function ViewBoolean(props) {
2
- let {value} = props;
3
- return value == null ? null : (value ? '是' : '否')
4
- }
@@ -1,3 +0,0 @@
1
- // 查看组件,主要是value 属性
2
- export * from './ViewPassword';
3
- export * from './ViewBoolean';