@jiangood/springboot-admin-starter 0.1.2 → 0.1.4

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.
package/package.json CHANGED
@@ -33,7 +33,7 @@
33
33
  "!src/.umi"
34
34
  ],
35
35
  "main": "src/index.ts",
36
- "version": "0.1.2",
36
+ "version": "0.1.4",
37
37
  "scripts": {
38
38
  "dev": "umi dev",
39
39
  "build": "tsc --outDir config/dist --skipLibCheck --noEmitOnError false config/index.ts"
@@ -2,14 +2,14 @@ import React from 'react';
2
2
 
3
3
  export interface FieldDateProps {
4
4
 
5
- type: 'YYYY-MM-DD' |
5
+ type: 'YYYY-MM-DD' | 'DAY'|
6
6
  'YYYY-MM-DD HH:mm:ss' |
7
7
  // 年
8
- 'YYYY' |
8
+ 'YYYY' | 'YEAR' |
9
9
  // 年月
10
- 'YYYY-MM' |
10
+ 'YYYY-MM' | 'YEAR_MONTH'|
11
11
  // 季度
12
- 'YYYY-QQ' |
12
+ 'YYYY-QQ' | 'YEAR_QUARTER'|
13
13
 
14
14
  'YYYY-MM-DD HH:mm' |
15
15
 
@@ -21,5 +21,7 @@ export interface FieldDateProps {
21
21
  }
22
22
 
23
23
  export class FieldDate extends React.Component<FieldDateProps, any> {
24
+
25
+
24
26
  }
25
27
 
@@ -4,6 +4,7 @@
4
4
  import React from "react";
5
5
  import dayjs from "dayjs";
6
6
  import {DatePicker, TimePicker} from "antd";
7
+ import {DateUtils} from "../utils";
7
8
 
8
9
 
9
10
  export class FieldDate extends React.Component {
@@ -11,8 +12,12 @@ export class FieldDate extends React.Component {
11
12
  type: 'YYYY-MM-DD'
12
13
  }
13
14
 
15
+
16
+
14
17
  render() {
15
18
  let {type, value, onChange, ...rest} = this.props;
19
+ type = DateUtils.convertTypeToFormat(type)
20
+
16
21
  switch (type) {
17
22
  case 'YYYY':
18
23
  return <DatePicker
@@ -4,7 +4,7 @@
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
+ import {DateUtils, StringUtils} from "../utils";
8
8
 
9
9
  const SP = StringUtils.ISO_SPLITTER;
10
10
 
@@ -15,6 +15,7 @@ export class FieldDateRange extends React.Component {
15
15
 
16
16
  render() {
17
17
  let {type, value, onChange, ...rest} = this.props;
18
+ type = DateUtils.convertTypeToFormat(type)
18
19
  switch (type) {
19
20
  case 'YYYY':
20
21
  return <DatePicker.RangePicker
@@ -1,7 +1,11 @@
1
- import React from "react";
1
+ import React, {ReactNode} from "react";
2
2
 
3
3
  export interface LoginPageProps {
4
4
 
5
+ /**
6
+ * 覆盖表单
7
+ */
8
+ form?: ReactNode
5
9
 
6
10
 
7
11
  }
@@ -3,7 +3,7 @@ import {Button, Form, Input, message, Space} from 'antd';
3
3
  import {LockOutlined, SafetyCertificateOutlined, UserOutlined, WarningOutlined} from '@ant-design/icons';
4
4
  import "./LoginPage.less"
5
5
  import {history} from 'umi';
6
- import {HttpUtils, MessageUtils, PageUtils, SysUtils} from "../utils";
6
+ import {EventBusUtils, HttpUtils, MessageUtils, PageUtils, SysUtils} from "../utils";
7
7
  import {JSEncrypt} from "jsencrypt";
8
8
 
9
9
 
@@ -53,6 +53,7 @@ export class LoginPage extends React.Component {
53
53
 
54
54
  HttpUtils.postForm('/admin/auth/login', values).then(rs => {
55
55
  console.log('登录结果', rs)
56
+ EventBusUtils.emit('loginSuccess')
56
57
  history.push(this.redirect)
57
58
  }).catch(e => {
58
59
  console.log('登录错误', e)
@@ -76,45 +77,7 @@ export class LoginPage extends React.Component {
76
77
  <section className='login-page' style={pageStyle}>
77
78
  <div className="login-content">
78
79
  <h1>{siteInfo.title}</h1>
79
- <Form
80
- name="normal_login"
81
- className="login-form"
82
- initialValues={{remember: true}}
83
- onFinish={this.submit}
84
- requiredMark={false}
85
- colon={false}
86
- >
87
-
88
- <Form.Item name="username" rules={[{required: true, message: '请输入用户名!'}]}>
89
- <Input size='large' prefix={<UserOutlined/>} placeholder="用户名" autoComplete="off"/>
90
- </Form.Item>
91
- <Form.Item name="password" rules={[{required: true, message: '请输入密码!'}]}>
92
- <Input autoComplete="off" prefix={<LockOutlined/>} type="password" placeholder="密码"
93
- size='large'
94
- />
95
- </Form.Item>
96
-
97
-
98
- {siteInfo.captcha && <Form.Item name='captchaCode' rules={[{required: true}]}>
99
- <Space style={{alignItems: 'center'}}>
100
- <Input size='large' placeholder='验证码' prefix={<SafetyCertificateOutlined/>}/>
101
- <img height={36}
102
- width={100}
103
- src={"/admin/auth/captchaImage?_random=" + this.state.random}
104
- onClick={() => {
105
- this.setState({random: Math.random()})
106
- }}></img>
107
- </Space>
108
- </Form.Item>}
109
-
110
-
111
- <Form.Item style={{marginTop: 10}}>
112
- <Button loading={this.state.logging} type="primary" htmlType="submit"
113
- block size='large'>
114
- 登录
115
- </Button>
116
- </Form.Item>
117
- </Form>
80
+ {this.getForm(siteInfo)}
118
81
 
119
82
  {this.renderFormBottom()}
120
83
 
@@ -124,6 +87,52 @@ export class LoginPage extends React.Component {
124
87
  }
125
88
 
126
89
 
90
+ getForm(siteInfo) {
91
+ if(this.props.form){
92
+ return this.props.form;
93
+ }
94
+
95
+ return <Form
96
+ name="normal_login"
97
+ className="login-form"
98
+ initialValues={{remember: true}}
99
+ onFinish={this.submit}
100
+ requiredMark={false}
101
+ colon={false}
102
+ >
103
+
104
+ <Form.Item name="username" rules={[{required: true, message: '请输入用户名!'}]}>
105
+ <Input size='large' prefix={<UserOutlined/>} placeholder="用户名" autoComplete="off"/>
106
+ </Form.Item>
107
+ <Form.Item name="password" rules={[{required: true, message: '请输入密码!'}]}>
108
+ <Input autoComplete="off" prefix={<LockOutlined/>} type="password" placeholder="密码"
109
+ size='large'
110
+ />
111
+ </Form.Item>
112
+
113
+
114
+ {siteInfo.captcha && <Form.Item name='captchaCode' rules={[{required: true}]}>
115
+ <Space style={{alignItems: 'center'}}>
116
+ <Input size='large' placeholder='验证码' prefix={<SafetyCertificateOutlined/>}/>
117
+ <img height={36}
118
+ width={100}
119
+ src={"/admin/auth/captchaImage?_random=" + this.state.random}
120
+ onClick={() => {
121
+ this.setState({random: Math.random()})
122
+ }}></img>
123
+ </Space>
124
+ </Form.Item>}
125
+
126
+
127
+ <Form.Item style={{marginTop: 10}}>
128
+ <Button loading={this.state.logging} type="primary" htmlType="submit"
129
+ block size='large'>
130
+ 登录
131
+ </Button>
132
+ </Form.Item>
133
+ </Form>;
134
+ }
135
+
127
136
  renderFormBottom() {
128
137
  let siteInfo = this.state.siteInfo;
129
138
  if (siteInfo.loginBoxBottomTip) {
@@ -1,7 +1,21 @@
1
- import { StringUtils } from './StringUtils';
1
+ import {StringUtils} from './StringUtils';
2
+
3
+ export class DateUtils {
4
+
5
+ public static convertTypeToFormat(type) {
6
+ if (type === 'YEAR') {
7
+ type = 'YYYY'
8
+ } else if (type === 'YEAR_MONTH') {
9
+ type = 'YYYY-MM'
10
+ } else if (type === 'YEAR_QUARTER') {
11
+ type = 'YYYY-QQ'
12
+ } else if (type === 'DAY') {
13
+ type = 'YYYY-MM-DD'
14
+ }
15
+ return type;
16
+ }
2
17
 
3
- export class DateUtils {
4
- public static year(date: Date): number {
18
+ public static year(date: Date): number {
5
19
  return date.getFullYear();
6
20
  }
7
21
 
@@ -28,19 +42,19 @@ export class DateUtils {
28
42
  * @param date
29
43
  * @returns {string}
30
44
  */
31
- public static hour(date: Date): string {
45
+ public static hour(date: Date): string {
32
46
  return StringUtils.pad(date.getHours(), 2);
33
47
  }
34
48
 
35
- public static minute(date: Date): string {
49
+ public static minute(date: Date): string {
36
50
  return StringUtils.pad(date.getMinutes(), 2);
37
51
  }
38
52
 
39
- public static second(date: Date): string {
53
+ public static second(date: Date): string {
40
54
  return StringUtils.pad(date.getSeconds(), 2);
41
55
  }
42
56
 
43
- public static formatDate(d: Date): string {
57
+ public static formatDate(d: Date): string {
44
58
  return this.year(d) + '-' + this.month(d) + '-' + this.date(d);
45
59
  }
46
60
 
@@ -57,7 +71,7 @@ export class DateUtils {
57
71
  * @param d
58
72
  * @returns {string} 2020年1月30日
59
73
  */
60
- public static formatDateCn(d: Date): string {
74
+ public static formatDateCn(d: Date): string {
61
75
  return this.year(d) + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日';
62
76
  }
63
77
 
@@ -76,11 +90,11 @@ export class DateUtils {
76
90
  return this.formatDate(new Date());
77
91
  }
78
92
 
79
- public static thisYear(): number {
93
+ public static thisYear(): number {
80
94
  return this.year(new Date());
81
95
  }
82
96
 
83
- public static thisMonth(): string {
97
+ public static thisMonth(): string {
84
98
  return this.month(new Date());
85
99
  }
86
100
 
@@ -88,7 +102,7 @@ export class DateUtils {
88
102
  * 显示友好时间,如 2小时前,1周前
89
103
  * @param pastDate 日期, 支持Date,String,Number
90
104
  */
91
- public static friendlyTime(pastDate: Date | string | number): string | undefined {
105
+ public static friendlyTime(pastDate: Date | string | number): string | undefined {
92
106
  if (pastDate == null) {
93
107
  return undefined;
94
108
  }
@@ -165,7 +179,7 @@ export class DateUtils {
165
179
  return min + '分' + seconds + '秒';
166
180
  }
167
181
 
168
- public static beginOfMonth(): string {
182
+ public static beginOfMonth(): string {
169
183
  const d = new Date();
170
184
  d.setDate(1);
171
185
  return this.formatDate(d);
@@ -89,6 +89,7 @@ export class EventBusUtils {
89
89
  name: string,
90
90
  ...args: T
91
91
  ): void {
92
+ console.log('触发事件:',name, args)
92
93
  const list = EventBusUtils.__stack[name] as StaticEventEntry<T>[];
93
94
 
94
95
  if (list !== undefined) {
@@ -88,21 +88,21 @@ export class MessageUtils {
88
88
  /**
89
89
  * 成功消息
90
90
  */
91
- static success(content: React.ReactNode, duration: number = 3) {
91
+ static success(content: String, duration: number = 3) {
92
92
  this.messageApi.success(content, duration);
93
93
  }
94
94
 
95
95
  /**
96
96
  * 错误消息
97
97
  */
98
- static error(content: React.ReactNode, duration: number = 3) {
98
+ static error(content: String, duration: number = 3) {
99
99
  this.messageApi.error(content, duration);
100
100
  }
101
101
 
102
102
  /**
103
103
  * 警告消息
104
104
  */
105
- static warning(content: React.ReactNode, duration: number = 3) {
105
+ static warning(content: String, duration: number = 3) {
106
106
  this.messageApi.warning(content, duration);
107
107
  }
108
108
 
@@ -116,13 +116,15 @@ export class MessageUtils {
116
116
  /**
117
117
  * 弹出 Loading 提示
118
118
  */
119
- static loading(content: React.ReactNode = '正在加载...', duration?: number) {
120
- return this.messageApi.loading({content, duration: duration === undefined ? 0 : duration});
119
+ static loading(content: string = '正在加载...', duration?: number) {
120
+ duration = duration === undefined ? 0 : duration;
121
+ return this.messageApi.loading(content, duration);
121
122
  }
122
123
 
123
124
  static config(messageApi: MessageInstance, modalApi: HookAPI) {
124
125
  this.messageApi = messageApi;
125
126
  this.modalApi = modalApi;
127
+ console.log('MessageUtils.config', messageApi, modalApi)
126
128
  }
127
129
 
128
130
  private static modalApi:HookAPI = null;
@@ -3,6 +3,11 @@
3
3
  */
4
4
  export class ObjectUtils {
5
5
 
6
+ static clone(obj:any){
7
+ return JSON.parse(JSON.stringify(obj));
8
+ }
9
+
10
+
6
11
  /**
7
12
  * 🎯 安全地获取深度嵌套的对象属性的值。
8
13
  * 如果属性链中的任何一级为 undefined 或 null,getDefinition 函数会返回一个默认值,而不是抛出错误。
@@ -21,93 +26,93 @@ export class ObjectUtils {
21
26
  */
22
27
  static get<TObj extends object, TDefault = unknown>(
23
28
  obj: TObj | null | undefined,
24
- path: string | (keyof TObj)[],
25
- defaultValue: TDefault | undefined = undefined
26
- ): unknown | TDefault {
27
-
28
- // 路径处理:将 'a[0].b.c' 转换为 ['a', '0', 'b', 'c'] 以支持数组索引
29
- // 注意:这里简化处理,只处理点分隔符,如果需要完整的 lodash getDefinition 行为,需要更复杂的正则解析。
30
- const pathArray: string[] = Array.isArray(path)
31
- ? path.map(String) // 确保路径段都是字符串
32
- : path.split('.');
33
-
34
- let result: any = obj;
35
-
36
- // 遍历路径
37
- for (const segment of pathArray) {
38
- // 如果当前结果是 null 或 undefined,则后续路径无法访问,返回默认值
39
- if (result == null) {
40
- return defaultValue;
41
- }
29
+ path: string | (keyof TObj)[],
30
+ defaultValue: TDefault | undefined = undefined
31
+ ): unknown | TDefault {
32
+
33
+ // 路径处理:将 'a[0].b.c' 转换为 ['a', '0', 'b', 'c'] 以支持数组索引
34
+ // 注意:这里简化处理,只处理点分隔符,如果需要完整的 lodash getDefinition 行为,需要更复杂的正则解析。
35
+ const pathArray: string[] = Array.isArray(path)
36
+ ? path.map(String) // 确保路径段都是字符串
37
+ : path.split('.');
38
+
39
+ let result: any = obj;
40
+
41
+ // 遍历路径
42
+ for (const segment of pathArray) {
43
+ // 如果当前结果是 null 或 undefined,则后续路径无法访问,返回默认值
44
+ if (result == null) {
45
+ return defaultValue;
46
+ }
42
47
 
43
48
  // 尝试访问属性
44
49
  // 使用 segment 作为索引,TypeScript 默认这里是合法的
45
- result = result[segment];
46
- }
50
+ result = result[segment];
51
+ }
47
52
 
48
53
  // 如果最终结果是 null 或 undefined,则返回默认值;否则返回结果
49
- return result !== null && result !== undefined ? result : defaultValue;
50
- }
54
+ return result !== null && result !== undefined ? result : defaultValue;
55
+ }
51
56
 
52
57
 
53
- /**
54
- * 📋 复制对象属性,仅复制源对象 (source) 中 **存在** 且目标对象 (target) 中 **也有** 对应属性的那些值。
55
- * 主要用于根据目标对象的结构来过滤和填充数据。
56
- *
57
- * @param source 源对象。
58
- * @param target 目标对象。
59
- * @returns void
60
- */
61
- static copyPropertyIfPresent<TSource extends object, TTarget extends object>(
62
- source: TSource | null | undefined,
63
- target: TTarget | null | undefined
64
- ): void {
65
- if (!source || !target || typeof source !== 'object' || typeof target !== 'object') {
66
- return;
67
- }
58
+ /**
59
+ * 📋 复制对象属性,仅复制源对象 (source) 中 **存在** 且目标对象 (target) 中 **也有** 对应属性的那些值。
60
+ * 主要用于根据目标对象的结构来过滤和填充数据。
61
+ *
62
+ * @param source 源对象。
63
+ * @param target 目标对象。
64
+ * @returns void
65
+ */
66
+ static copyPropertyIfPresent<TSource extends object, TTarget extends object>(
67
+ source: TSource | null | undefined,
68
+ target: TTarget | null | undefined
69
+ ): void {
70
+ if (!source || !target || typeof source !== 'object' || typeof target !== 'object') {
71
+ return;
72
+ }
68
73
 
69
74
  // 遍历目标对象的键,确保我们只复制目标对象上已有的属性
70
- const keys = Object.keys(target) as (keyof TTarget)[];
71
-
72
- for (const key of keys) {
73
- // 检查源对象是否有这个属性
74
- if (Object.hasOwn(source, key)) {
75
- // 因为目标对象和源对象都被约束为 object,所以这里的类型转换是相对安全的
76
- const value = (source as any)[key];
77
- (target as any)[key] = value;
75
+ const keys = Object.keys(target) as (keyof TTarget)[];
76
+
77
+ for (const key of keys) {
78
+ // 检查源对象是否有这个属性
79
+ if (Object.hasOwn(source, key)) {
80
+ // 因为目标对象和源对象都被约束为 object,所以这里的类型转换是相对安全的
81
+ const value = (source as any)[key];
82
+ (target as any)[key] = value;
83
+ }
84
+ }
78
85
  }
79
- }
80
- }
81
86
 
82
87
 
83
- /**
84
- * 📝 复制对象属性,将源对象 (source) 中 **非 undefined** 的属性值复制到目标对象 (target) 对应的属性上。
85
- * 仅复制目标对象 (target) 中 **已有** 的属性,如果源对象中的值是 undefined 则不复制。
86
- *
87
- * @param source 源对象。
88
- * @param target 目标对象。
89
- * @returns void
90
- */
91
- static copyProperty<TSource extends object, TTarget extends object>(
92
- source: TSource | null | undefined,
93
- target: TTarget | null | undefined
94
- ): void {
95
- if (!source || !target || typeof source !== 'object' || typeof target !== 'object') {
96
- return;
97
- }
88
+ /**
89
+ * 📝 复制对象属性,将源对象 (source) 中 **非 undefined** 的属性值复制到目标对象 (target) 对应的属性上。
90
+ * 仅复制目标对象 (target) 中 **已有** 的属性,如果源对象中的值是 undefined 则不复制。
91
+ *
92
+ * @param source 源对象。
93
+ * @param target 目标对象。
94
+ * @returns void
95
+ */
96
+ static copyProperty<TSource extends object, TTarget extends object>(
97
+ source: TSource | null | undefined,
98
+ target: TTarget | null | undefined
99
+ ): void {
100
+ if (!source || !target || typeof source !== 'object' || typeof target !== 'object') {
101
+ return;
102
+ }
98
103
 
99
104
  // 遍历目标对象的键
100
- const keys = Object.keys(target) as (keyof TTarget)[];
105
+ const keys = Object.keys(target) as (keyof TTarget)[];
101
106
 
102
- for (const key of keys) {
103
- // 尝试从源对象获取值
104
- const value = (source as any)[key];
107
+ for (const key of keys) {
108
+ // 尝试从源对象获取值
109
+ const value = (source as any)[key];
105
110
 
106
- // 只有当值明确不是 undefined 时才复制(即允许复制 null 或其他 falsy 值)
107
- if (value !== undefined) {
108
- (target as any)[key] = value;
111
+ // 只有当值明确不是 undefined 时才复制(即允许复制 null 或其他 falsy 值)
112
+ if (value !== undefined) {
113
+ (target as any)[key] = value;
114
+ }
115
+ }
109
116
  }
110
- }
111
- }
112
117
 
113
118
  }
@@ -113,11 +113,14 @@ export class TreeUtils {
113
113
  }
114
114
 
115
115
  /**
116
- * 🚶 深度优先遍历树节点。
116
+ * 深度优先遍历树节点。
117
117
  * @param tree 树节点数组
118
118
  * @param callback 对每个节点执行的回调函数
119
119
  */
120
120
  public static walk<T extends TreeNode>(tree: T[], callback: (node: T) => void): void {
121
+ if(tree == null){
122
+ return
123
+ }
121
124
  for (const node of tree) {
122
125
  callback(node); // 执行回调函数
123
126
 
@@ -129,7 +132,7 @@ export class TreeUtils {
129
132
  }
130
133
 
131
134
  /**
132
- * 🔑 根据键值深度查找单个节点。
135
+ * 根据键值深度查找单个节点。
133
136
  * @param key 要查找的键值 (例如: 节点的 id)
134
137
  * @param list 树节点数组
135
138
  * @param keyName 要匹配的字段名,默认为 'id'
@@ -10,7 +10,7 @@ import {Gap, HttpUtils, NamedIcon, PageUtils, SysUtils, ThemeUtils, TreeUtils} f
10
10
  import HeaderRight from "./HeaderRight";
11
11
  import TabPageRender from "./TabPageRender";
12
12
 
13
- const {Header, Footer, Sider, Content} = Layout;
13
+ const {Header, Sider, Content} = Layout;
14
14
  /**
15
15
  * 带菜单的布局,主要处理布局宇框架结构
16
16
  */
@@ -99,7 +99,7 @@ export default class extends React.Component {
99
99
  <Header className='header'>
100
100
  <div className='header-left'>
101
101
  {siteInfo.logoUrl &&
102
- <img className='logo-img' src='/admin/public/logo.jpg' onClick={() => history.push('/')} alt='logo'/>}
102
+ <img className='logo-img' src={siteInfo.logoUrl} onClick={() => history.push('/')} alt='logo'/>}
103
103
  <h3 className='hide-on-mobile'>
104
104
  <Link to="/" style={{color: ThemeUtils.getColor("primary-color")}}>{siteInfo.title} </Link>
105
105
  </h3>
@@ -57,6 +57,8 @@ export default class extends React.Component {
57
57
  }
58
58
  });
59
59
 
60
+ console.log('导入的xml内容如下')
61
+ console.log(xml)
60
62
  this.bpmnModeler.importXML(xml)
61
63
  this.bpmnModeler.on('element.contextmenu', e => e.preventDefault()) // 关闭右键,影响操作
62
64
  };
@@ -10,11 +10,11 @@ export default class extends React.Component {
10
10
 
11
11
  columns = [
12
12
  {
13
- title: '模型名称',
13
+ title: '名称',
14
14
  dataIndex: 'name',
15
15
  },
16
16
  {
17
- title: '唯一编码',
17
+ title: '代码',
18
18
  dataIndex: 'key'
19
19
  },
20
20
 
@@ -1,18 +1,27 @@
1
1
  import React from "react";
2
- import {Button, Card, Form, Input, message, Radio, Spin, Splitter,} from "antd";
2
+ import {Button, Card, Empty, Form, Input, message, Modal, Radio, Spin, Splitter, Table, Tabs, Typography,} from "antd";
3
3
  import {history} from "umi";
4
- import {HttpUtils, Page, PageUtils} from "../../../framework";
5
- import InstanceInfo from "../InstanceInfo";
4
+ import {FormRegistryUtils, Gap, HttpUtils, Page, PageUtils} from "../../../framework";
5
+ import {FormOutlined, ShareAltOutlined} from "@ant-design/icons";
6
6
 
7
7
  export default class extends React.Component {
8
8
 
9
9
  state = {
10
10
  submitLoading: false,
11
- taskId: null,
12
- instanceId: null,
13
- formKey: null,
14
11
 
15
- taskInfo: null
12
+
13
+ instanceCommentList: [],
14
+ vars: {},
15
+
16
+
17
+ data: {
18
+ taskId: null,
19
+ commentList: [],
20
+ img: null
21
+ },
22
+ loading: true,
23
+
24
+ errorMsg: null
16
25
  }
17
26
 
18
27
 
@@ -20,16 +29,31 @@ export default class extends React.Component {
20
29
  externalFormRef = React.createRef()
21
30
 
22
31
  componentDidMount() {
23
- const {taskId, instanceId, formKey} = PageUtils.currentParams()
24
- this.setState({taskId, instanceId, formKey})
32
+ const {taskId} = PageUtils.currentParams()
25
33
 
26
- HttpUtils.get('admin/flowable/my/taskInfo', {id: taskId}).then(rs=>{
27
- console.log('任务信息',rs)
28
- this.setState({taskInfo:rs})
34
+
35
+ HttpUtils.get("admin/flowable/my/getInstanceInfoByTaskId", {taskId}).then(rs => {
36
+ this.setState({data: rs})
37
+ }).catch(e => {
38
+ this.setState({errorMsg: e})
39
+ }).finally(() => {
40
+ this.setState({loading: false})
29
41
  })
30
42
 
43
+
31
44
  }
32
45
 
46
+ onImgClick = () => {
47
+ Modal.info({
48
+ title: '流程图',
49
+ width: '70vw',
50
+ content: <div style={{width: '100%', overflow: 'auto', maxHeight: '80vh'}}>
51
+ <img src={this.state.data.img}/>
52
+ </div>
53
+ })
54
+ };
55
+
56
+
33
57
  handleTask = async value => {
34
58
  this.setState({submitLoading: true});
35
59
  try {
@@ -40,8 +64,8 @@ export default class extends React.Component {
40
64
  }
41
65
  }
42
66
 
43
- value.taskId = this.state.taskId
44
- await HttpUtils.post("admin//flowable/my/handleTask", value)
67
+ value.taskId = this.state.data.taskId
68
+ await HttpUtils.post("admin/flowable/my/handleTask", value)
45
69
  history.replace('/flowable/task')
46
70
  } catch (error) {
47
71
  message.error(error)
@@ -52,16 +76,37 @@ export default class extends React.Component {
52
76
  }
53
77
 
54
78
  render() {
55
- const {submitLoading,taskInfo} = this.state
56
- const instanceId = this.state.instanceId
57
- if (!instanceId || !taskInfo) {
79
+ const {submitLoading} = this.state
80
+
81
+ const {data, loading} = this.state
82
+ const {commentList, img} = data
83
+ if(loading){
58
84
  return <Spin/>
59
85
  }
60
86
  return <Page padding>
61
87
 
62
88
  <Splitter>
63
89
  <Splitter.Panel>
64
- <InstanceInfo id={instanceId} formKey={this.state.formKey} externalFormRef={this.externalFormRef} taskInfo={taskInfo}/>
90
+ <Typography.Title level={4}>{data.name}</Typography.Title>
91
+ <Typography.Text type="secondary">{data.starter} &nbsp;&nbsp; {data.startTime}</Typography.Text>
92
+ <Gap></Gap>
93
+ <Tabs
94
+ items={[
95
+ {
96
+ key: '1',
97
+ label: '表单',
98
+ icon: <FormOutlined/>,
99
+ children: this.renderForm()
100
+ },
101
+ {
102
+ key: '2',
103
+ label: '流程',
104
+ icon: <ShareAltOutlined/>,
105
+ children: this.renderProcess(img, commentList)
106
+ }
107
+ ]}>
108
+
109
+ </Tabs>
65
110
  </Splitter.Panel>
66
111
  <Splitter.Panel defaultSize={400}>
67
112
  <Card title='审批意见'>
@@ -70,6 +115,7 @@ export default class extends React.Component {
70
115
  onFinish={this.handleTask}
71
116
  disabled={submitLoading}
72
117
  >
118
+
73
119
  <Form.Item label='审批结果' name='result' rules={[{required: true, message: '请选择'}]}
74
120
  initialValue={'APPROVE'}>
75
121
  <Radio.Group>
@@ -96,4 +142,45 @@ export default class extends React.Component {
96
142
 
97
143
 
98
144
  }
145
+
146
+ renderProcess = (img, commentList) => <Card title='处理记录'>
147
+ <img src={img} style={{maxWidth: '100%'}}
148
+ onClick={this.onImgClick}/>
149
+ <Gap></Gap>
150
+ <Table dataSource={commentList}
151
+
152
+ size='small'
153
+ pagination={false}
154
+ rowKey='id'
155
+ columns={[
156
+ {
157
+ dataIndex: 'content',
158
+ title: '操作'
159
+ },
160
+ {
161
+ dataIndex: 'user',
162
+ title: '处理人'
163
+ },
164
+ {
165
+ dataIndex: 'time',
166
+ title: '处理时间'
167
+ },
168
+ ]}
169
+ />
170
+ </Card>;
171
+
172
+ renderForm = () => {
173
+ const {data} = this.state
174
+ const {businessKey} = data
175
+ const formKey = data.formKey;
176
+ const formName = data.formKey + 'Form'
177
+
178
+ let ExForm = FormRegistryUtils.get(formName);
179
+ if (!ExForm) {
180
+ console.error(" 表单不存在: "+formName+"。 请检查表单源代码:src/forms/"+formName+".jsx")
181
+ return <Empty description={"表单不存在: " + formName}></Empty>
182
+ }
183
+
184
+ return <ExForm id={businessKey} formKey={formKey} ref={this.externalFormRef} ></ExForm>
185
+ }
99
186
  }
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
- import {Button, Modal, Tabs} from "antd";
3
- import {HttpUtils, LinkButton, MessageUtils, Page, PageLoading, ProTable} from "../../../framework";
4
- import InstanceInfo from "../InstanceInfo";
2
+ import {Button, Tabs} from "antd";
3
+ import {HttpUtils, LinkButton, Page, PageLoading, PageUtils, ProTable} from "../../../framework";
5
4
 
6
5
 
7
6
  export default class extends React.Component {
@@ -66,10 +65,7 @@ export default class extends React.Component {
66
65
  title: '操作',
67
66
  dataIndex: 'option',
68
67
  render: (_, record) => {
69
- let path = '/flowable/task/form?taskId=' + record.id + '&instanceId=' + record.instanceId;
70
- if (record.formKey) {
71
- path += "&formKey=" + record.formKey
72
- }
68
+ let path = '/flowable/task/form?taskId=' + record.id;
73
69
  return (
74
70
  <LinkButton
75
71
  type='primary'
@@ -124,13 +120,7 @@ export default class extends React.Component {
124
120
  title: '操作',
125
121
  dataIndex: 'option',
126
122
  render: (_, record) => (
127
- <Button size='small' onClick={() => {
128
- Modal.info({
129
- title: '流程信息',
130
- width: '800vw',
131
- content: <InstanceInfo id={record.instanceId}/>
132
- })
133
- }}> 查看 </Button>
123
+ <Button size='small' onClick={() => PageUtils.open('/flowable/task/instance/view?id='+record.id, '流程信息') }> 查看 </Button>
134
124
  ),
135
125
  },
136
126
  ]}
@@ -185,14 +175,9 @@ export default class extends React.Component {
185
175
  title: '操作',
186
176
  dataIndex: 'option',
187
177
  render: (_, record) => (
188
- <Button size='small' onClick={() => {
189
- MessageUtils.alert(<InstanceInfo id={record.id}/>, {
190
- width: '80vw',
191
- title: '流程信息'
192
- })
178
+ <Button size='small' onClick={() => PageUtils.open('/flowable/task/instance/view?id='+record.id, '流程信息') }> 查看 </Button>
193
179
 
194
- }}> 查看 </Button>
195
- ),
180
+ ),
196
181
  },
197
182
  ]}
198
183
  />;
@@ -0,0 +1,85 @@
1
+ import React from "react";
2
+ import {Gap, HttpUtils, Page, PageUtils, ProTable} from "../../../../framework";
3
+ import {Card, Empty, Skeleton, Table} from "antd";
4
+
5
+ export default class extends React.Component {
6
+ state = {
7
+ instanceCommentList: [],
8
+ vars: {},
9
+
10
+ id: null,
11
+ starter: null,
12
+ startTime: null,
13
+ name: null,
14
+
15
+ data: {
16
+ commentList: [],
17
+ img: null
18
+ },
19
+ loading: true,
20
+
21
+ errorMsg: null
22
+ }
23
+
24
+
25
+ componentDidMount() {
26
+ const { id} = PageUtils.currentParams()
27
+
28
+ HttpUtils.get("admin/flowable/my/getInstanceInfo", {id}).then(rs => {
29
+ this.setState(rs)
30
+ this.setState({data: rs})
31
+ }).catch(e => {
32
+ this.setState({errorMsg: e})
33
+ }).finally(() => {
34
+ this.setState({loading: false})
35
+ })
36
+
37
+ }
38
+
39
+
40
+ render() {
41
+
42
+ if (this.state.errorMsg) {
43
+ return <Empty description={this.state.errorMsg}></Empty>
44
+ }
45
+
46
+ const {data, loading} = this.state
47
+ const {commentList, img} = data
48
+ if (loading) {
49
+ return <Skeleton/>
50
+ }
51
+
52
+
53
+ return <Page padding>
54
+ <Card title='流程图'>
55
+ <img src={img} style={{maxWidth: '100%'}}/>
56
+ </Card>
57
+ <Gap/>
58
+ <Card title='审批记录'>
59
+ <Table dataSource={commentList}
60
+ size='small'
61
+ pagination={false}
62
+ rowKey='id'
63
+ columns={[
64
+ {
65
+ dataIndex: 'content',
66
+ title: '操作'
67
+ },
68
+ {
69
+ dataIndex: 'user',
70
+ title: '处理人'
71
+ },
72
+ {
73
+ dataIndex: 'time',
74
+ title: '处理时间'
75
+ },
76
+ ]}
77
+ />
78
+ </Card>
79
+
80
+
81
+ </Page>
82
+ }
83
+
84
+
85
+ }
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import {LoginPage} from "../framework/pages/LoginPage";
4
+ import {Button} from "antd";
4
5
 
5
6
 
6
7
  export default class extends React.Component {
@@ -9,8 +10,9 @@ export default class extends React.Component {
9
10
 
10
11
 
11
12
  render() {
12
-
13
- return <LoginPage />
13
+ return <LoginPage />
14
+ // 支持自定义
15
+ // return <LoginPage form={<Button type={"primary"} size='large'>xx登录</Button>} />
14
16
  }
15
17
 
16
18
 
@@ -1,138 +0,0 @@
1
- import React from "react";
2
- import {Card, Empty, Modal, Skeleton, Table, Tabs, Typography} from "antd";
3
-
4
- import {FormOutlined, ShareAltOutlined} from "@ant-design/icons";
5
- import {FormRegistryUtils, Gap, HttpUtils} from "../../framework";
6
-
7
- export default class InstanceInfo extends React.Component {
8
-
9
- state = {
10
- instanceCommentList: [],
11
- vars: {},
12
-
13
- id: null,
14
- starter: null,
15
- startTime: null,
16
- name: null,
17
-
18
- data: {
19
- commentList: [],
20
- img: null
21
- },
22
- loading: true,
23
-
24
- errorMsg: null
25
- }
26
-
27
-
28
- componentDidMount() {
29
- const {id, businessKey} = this.props;
30
- HttpUtils.get("admin/flowable/my/getInstanceInfo", {id, businessKey}).then(rs => {
31
- this.setState(rs)
32
- this.setState({data: rs})
33
- }).catch(e => {
34
- this.setState({errorMsg: e})
35
- }).finally(() => {
36
- this.setState({loading: false})
37
- })
38
-
39
- }
40
-
41
- onImgClick = () => {
42
- const {data} = this.state
43
-
44
- const {img} = data
45
- Modal.info({
46
- title: '流程图',
47
- width: '70vw',
48
- content: <div style={{width: '100%', overflow: 'auto', maxHeight: '80vh'}}><img src={img}/></div>
49
- })
50
- };
51
-
52
- render() {
53
- if (this.state.errorMsg) {
54
- return <Empty description={this.state.errorMsg}></Empty>
55
- }
56
-
57
- const {data, loading} = this.state
58
- const {commentList, img} = data
59
- if (loading) {
60
- return <Skeleton/>
61
- }
62
-
63
-
64
- return <>
65
- <Typography.Title level={4}>{data.name}</Typography.Title>
66
- <Typography.Text type="secondary">{data.starter} &nbsp;&nbsp; {data.startTime}</Typography.Text>
67
- <Gap></Gap>
68
- <Tabs
69
- items={[
70
- {
71
- key: '1',
72
- label: '表单',
73
- icon: <FormOutlined/>,
74
- children: this.renderForm()
75
- },
76
- {
77
- key: '2',
78
- label: '流程',
79
- icon: <ShareAltOutlined/>,
80
- children: this.renderProcess(img, commentList)
81
- }
82
- ]}>
83
-
84
- </Tabs>
85
-
86
-
87
- </>
88
-
89
- }
90
-
91
- renderProcess = (img, commentList) => <Card title='处理记录'>
92
- {img && <img src={img} style={{maxWidth: '100%'}}
93
- onClick={this.onImgClick}/>}
94
- <Gap></Gap>
95
- <Table dataSource={commentList}
96
-
97
- size='small'
98
- pagination={false}
99
- rowKey='id'
100
- columns={[
101
- {
102
- dataIndex: 'content',
103
- title: '操作'
104
- },
105
- {
106
- dataIndex: 'user',
107
- title: '处理人'
108
- },
109
- {
110
- dataIndex: 'time',
111
- title: '处理时间'
112
- },
113
- ]}
114
- />
115
- </Card>;
116
-
117
- renderForm = () => {
118
- const {data} = this.state
119
- const {processDefinitionKey, businessKey} = data
120
- const formKey = this.props.formKey || processDefinitionKey;
121
- const formName = formKey + 'Form'
122
-
123
- // let formKey = this.props.formKey || processDefinitionKey + 'Form';
124
- let ExForm = FormRegistryUtils.get(formName);
125
- if (!ExForm) {
126
- return <div>
127
- <p>
128
- 未创建表单 {formName}。
129
- </p>
130
- <Typography.Text>
131
- 表单路径:src/forms/{formName}.jsx
132
- </Typography.Text>
133
- </div>
134
- }
135
-
136
- return <ExForm id={businessKey} formKey={formKey} ref={this.props.externalFormRef} taskInfo={this.props.taskInfo}></ExForm>
137
- }
138
- }
@@ -1,15 +0,0 @@
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
- }