@jiangood/admin-spring-boot-starter 0.2.7 → 0.2.8

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.2.7",
36
+ "version": "0.2.8",
37
37
  "scripts": {
38
38
  "dev": "umi dev",
39
39
  "build": "tsc --outDir config/dist --skipLibCheck --noEmitOnError false config/index.ts"
@@ -2,7 +2,6 @@
2
2
  import React from "react";
3
3
 
4
4
  declare type ButtonListProps = {
5
- maxNum?:number
6
5
  };
7
6
 
8
7
  export class ButtonList extends React.Component<ButtonListProps, any> {
@@ -13,23 +13,30 @@ export class ButtonList extends React.Component {
13
13
 
14
14
  render() {
15
15
  let {children} = this.props;
16
- const menus = [];
17
16
 
18
- // 判断是否数组
19
- if (Array.isArray(children)) {
20
- for (let child of children) {
21
- if (child === null || child === undefined) {
22
- continue;
23
- }
24
- if (child.props == null || child.props.perm == null || PermUtils.hasPermission(child.props.perm)) {
25
- menus.push(child);
26
- }
17
+ // 单节点的情况
18
+ if (!Array.isArray(children)) {
19
+ if (this.checkPerm(children)) {
20
+ return children;
27
21
  }
28
- } else {
29
- menus.push(children)
22
+ return null
30
23
  }
31
24
 
32
-
25
+ const menus = [];
26
+ for (let child of children) {
27
+ if (child === null || child === undefined) {
28
+ continue;
29
+ }
30
+ if (this.checkPerm(child)) {
31
+ menus.push(child);
32
+ }
33
+ }
33
34
  return <Space>{menus}</Space>;
34
35
  }
36
+
37
+ checkPerm = element => {
38
+ let props = element.props;
39
+ return props == null || props.perm == null || PermUtils.hasPermission(props.perm);
40
+
41
+ };
35
42
  }
@@ -31,6 +31,15 @@ export class StringUtils {
31
31
  return str;
32
32
  }
33
33
 
34
+ static removePrefixAndSuffix(str: string , prefix: string, suffix: string): string {
35
+ if (str != null) {
36
+ str = StringUtils.removePrefix(str, prefix);
37
+ str = StringUtils.removeSuffix(str, suffix);
38
+ }
39
+ return str;
40
+ }
41
+
42
+
34
43
  /**
35
44
  * 生成指定长度的随机字符串
36
45
  * @param length 随机字符串的长度
@@ -67,6 +76,14 @@ export class StringUtils {
67
76
  return str.includes(subStr);
68
77
  }
69
78
 
79
+ static containsAll(str: string | null | undefined, subStr: string, subStr2: string): boolean {
80
+ if (!str) {
81
+ return false;
82
+ }
83
+ return str.includes(subStr) && str.includes(subStr2);
84
+ }
85
+
86
+
70
87
  /**
71
88
  * 统计子字符串在原始字符串中出现的次数
72
89
  * @param str 原始字符串
@@ -382,16 +399,23 @@ export class StringUtils {
382
399
  * @param str
383
400
  * @param sp
384
401
  */
385
- static split(str: any, sp: string):null|string[]|undefined {
402
+ static split(str: any, sp: string):string[] {
386
403
  if(str == null || str.length === 0){
387
- return undefined
404
+ return []
388
405
  }
389
406
  if(Array.isArray(str)){
390
- return str;
407
+ return str as string[];
391
408
  }
392
409
 
393
410
  return str.split(sp)
394
411
  }
412
+ static splitTrim(str: any, sp: string):string[] {
413
+ const arr = StringUtils.split(str, sp).map(item => item.trim())
414
+ for (let i = 0; i < arr.length; i++) {
415
+ arr[i] = arr[i].trim()
416
+ }
417
+ return arr;
418
+ }
395
419
 
396
420
  /**
397
421
  * 连接字符串
@@ -1,51 +1,125 @@
1
1
  import {Button, Input, InputNumber, Modal, Select} from "antd";
2
- import React, {Component} from "react";
3
- import {FieldBoolean, FieldTable, HttpUtils, StringUtils, ThemeUtils} from "../../../../../framework";
4
-
5
- const metaInfo = {
6
- STRING: {
7
- ops: {
8
- '==': '等于',
9
- '!=': '不等于',
10
- contains: '包含',
11
- '!contains': '不包含',
12
- startWith: '开头等于',
13
- endWith: '结尾等于',
14
- },
15
- render() {
16
- return <Input/>;
17
- },
2
+ import {Component} from "react";
3
+ import {FieldBoolean, FieldTable, HttpUtils, ObjectUtils, StringUtils, ThemeUtils} from "../../../../../framework";
4
+ import {ConditionExpressionUtils} from "./ConditionExpressionUtils";
5
+
6
+
7
+ // 字符串的双引号
8
+ const QUOTE = '"';
9
+
10
+
11
+ const OPERATOR_DEFINITIONS = [
12
+ {
13
+ type: 'STRING',
14
+ label: '等于',
15
+ key: '==',
16
+ component: Input,
18
17
  },
19
- NUMBER: {
20
- ops: {
21
- '==': '等于',
22
- '!=': '不等于',
23
- '>': '大于',
24
- '<': '小于',
25
- '>=': '大于等于',
26
- '<=': '小于等于',
27
- between: '介于',
28
- },
29
- render(op) {
30
- if (op !== 'between') return <InputNumber/>;
31
-
32
- return (
33
- <Input.Group>
34
- <InputNumber placeholder="最小值"></InputNumber>
35
- <InputNumber placeholder="最大值"></InputNumber>
36
- </Input.Group>
37
- );
38
- },
18
+ {
19
+ type: 'STRING',
20
+ label: '不等于',
21
+ key: '!=',
22
+ component: Input,
39
23
  },
40
- BOOLEAN: {
41
- ops: {
42
- '==': '等于',
43
- },
44
- render() {
45
- return <FieldBoolean/>;
46
- },
24
+ {
25
+ type: 'STRING',
26
+ label: '包含',
27
+ key: '.contains',
28
+ component: Input,
29
+ },
30
+ {
31
+ type: 'STRING',
32
+ label: '开头等于',
33
+ key: '.startWith',
34
+ component: Input,
35
+ },
36
+ {
37
+ type: 'STRING',
38
+ label: '结尾等于',
39
+ key: '.endWith',
40
+ component: Input,
41
+ },
42
+
43
+ // =================== 数字 ================
44
+
45
+ {
46
+ type: 'NUMBER',
47
+ label: '等于',
48
+ key: '==',
49
+ component: Input,
50
+ },
51
+ {
52
+ type: 'NUMBER',
53
+ label: '不等于',
54
+ key: '!=',
55
+ component: Input,
47
56
  },
48
- };
57
+
58
+ {
59
+ type: 'NUMBER',
60
+ label: '大于',
61
+ key: '>',
62
+ component: InputNumber,
63
+ },
64
+ {
65
+ type: 'NUMBER',
66
+ label: '小于',
67
+ key: '<',
68
+ component: InputNumber,
69
+ },
70
+ {
71
+ type: 'NUMBER',
72
+ label: '大于等于',
73
+ key: '>=',
74
+ component: InputNumber,
75
+ },
76
+ {
77
+ type: 'NUMBER',
78
+ label: '小于等于',
79
+ key: '<=',
80
+ component: InputNumber,
81
+ },
82
+
83
+
84
+ // ===================== 布尔值 =======================
85
+
86
+ {
87
+ type: 'BOOLEAN',
88
+ label: '等于',
89
+ key: '==',
90
+ component: FieldBoolean,
91
+ },
92
+
93
+ ]
94
+
95
+
96
+ function encode(data) {
97
+ let {left, op, right} = data;
98
+ if (left == null || op == null || right == null) {
99
+ return null
100
+ }
101
+
102
+ const isFun = op.startsWith('.')
103
+ if (isFun) {
104
+ return left + op + '("' + right + '")';
105
+ }
106
+ const isStr = right.startsWith('"')
107
+ if (isStr) {
108
+ right = '"' + right + '"';
109
+ }
110
+
111
+ return left + op + right;
112
+ }
113
+
114
+ function decode(expression) {
115
+ const isFun = ConditionExpressionUtils.isFunction(expression);
116
+ if (isFun) {
117
+ return ConditionExpressionUtils.parseStrFunction(expression)
118
+ }
119
+
120
+ return ConditionExpressionUtils.parse(expression)
121
+ }
122
+
49
123
 
50
124
  export class ConditionDesignButton extends Component {
51
125
 
@@ -60,7 +134,6 @@ export class ConditionDesignButton extends Component {
60
134
  console.log('流程id', processId)
61
135
 
62
136
  HttpUtils.get('admin/flowable/model/varList', {code: processId}).then(rs => {
63
-
64
137
  const options = rs.map(r => {
65
138
  return {
66
139
  label: r.label,
@@ -76,34 +149,41 @@ export class ConditionDesignButton extends Component {
76
149
  this.props.setValue(str, this.props.element, this.props.modeling, this.props.bpmnFactory)
77
150
  };
78
151
 
152
+ getOptionsByItem = (record) => {
153
+ let options = []
154
+ let {varList} = this.state;
155
+ let varItem = varList.find(t => t.name === record.left)
156
+
157
+ if (varItem) {
158
+ const {valueType} = varItem;
159
+ const os = OPERATOR_DEFINITIONS.filter(o => o.type === valueType)
160
+ for (let o of os) {
161
+ options.push({
162
+ label: o.label,
163
+ value: o.key
164
+ })
165
+ }
166
+ }
167
+
168
+ return options;
169
+ }
170
+
79
171
  columns = [
80
172
  {
81
- dataIndex: 'key', title: '变量名称',
173
+ dataIndex: 'left', title: '变量名称',
82
174
  render: () => {
83
175
  return <Select options={this.state.varOptions} style={{width: 200}}></Select>
84
176
  }
85
177
  },
86
178
  {
87
- dataIndex: 'op', title: '操作符', render: (v, record) => {
88
- let options = []
89
- let {varList} = this.state;
90
- let varItem = varList.find(t => t.name === record.key)
91
-
92
- if (varItem) {
93
- const {valueType} = varItem;
94
- const ops = metaInfo[valueType].ops;
95
- options = Object.keys(ops).map(key => {
96
- return {
97
- label: ops[key],
98
- value: key
99
- }
100
- })
101
- }
179
+ dataIndex: 'op', title: '操作符',
180
+ render: (v, record) => {
181
+ const options = this.getOptionsByItem(record)
102
182
 
103
183
  return <Select options={options} style={{width: 100}}></Select>
104
184
  }
105
185
  },
106
- {dataIndex: 'value', title: '值'},
186
+ {dataIndex: 'right', title: '值', width: 200},
107
187
  ];
108
188
 
109
189
  render() {
@@ -111,65 +191,53 @@ export class ConditionDesignButton extends Component {
111
191
  let arrValue = this.convertStrToArr(value);
112
192
 
113
193
  return <div style={{display: 'flex', justifyContent: 'right', padding: 8}}>
114
- <Button type='primary' size='small'
194
+ <Button type='primary'
195
+ size='small'
196
+
115
197
  styles={{
116
- root: {backgroundColor: ThemeUtils.getColor('primary-color')}
198
+ root: {
199
+ backgroundColor: ThemeUtils.getColor('primary-color')
200
+ }
117
201
  }}
202
+
118
203
  onClick={() => this.setState({open: true})}
204
+
119
205
  >条件编辑器</Button>
120
206
 
121
207
 
122
- <Modal title='条件编辑器 (复杂表达式暂不支持)' open={this.state.open}
208
+ <Modal title='条件编辑器 (复杂表达式暂不支持)' open={this.state.open} width={600}
123
209
  onCancel={() => this.setState({open: false})}
124
210
  footer={null}
125
211
  mask={{blur: false}}
126
212
  destroyOnHidden
127
213
  >
128
- <FieldTable columns={this.columns}
129
- value={arrValue}
130
- onChange={this.onChange}
131
- ></FieldTable>
214
+ <FieldTable
215
+ columns={this.columns}
216
+ value={arrValue}
217
+ onChange={this.onChange}
218
+ />
132
219
  </Modal>
133
220
 
134
221
  </div>
135
222
  }
136
223
 
137
224
  convertStrToArr(value) {
138
-
139
- let arrValue = []
140
225
  if (value) {
141
-
142
-
143
- value = StringUtils.removePrefix(value, "${")
144
- value = StringUtils.removeSuffix(value, "}")
226
+ value = StringUtils.removePrefixAndSuffix(value, "${", "}")
145
227
  const strArr = StringUtils.split(value, '&&');
146
-
147
- const regex = /(\w+)([<>=!]+)(\w+)/;
148
-
149
- strArr.forEach(expression => {
150
- const parts = expression.match(regex);
151
- // parts[0] 是整个匹配的字符串
152
- // parts[1] 是第一个捕获组 (左操作数)
153
- // parts[2] 是第二个捕获组 (操作符)
154
- // parts[3] 是第三个捕获组 (右操作数)
155
- arrValue.push({
156
- key: parts[1],
157
- op: parts[2],
158
- value: parts[3],
159
- })
160
- })
228
+ return strArr.map(decode).filter(t => t != null)
161
229
  }
162
- return arrValue;
230
+ return [];
163
231
  }
164
232
 
233
+
165
234
  convertArrToStr = arrValue => {
166
- const str = arrValue.map(i => {
167
- const {key, op, value} = i;
168
- return `${key}${op}${value}`
169
- }).join('&&')
235
+ const str = arrValue.map(encode).join('&&')
170
236
 
171
237
  return "${" + str + "}"
172
238
  };
239
+
240
+
173
241
  }
174
242
 
175
243
 
@@ -0,0 +1,53 @@
1
+ import {StringUtils} from "../../../../../framework";
2
+
3
+
4
+ export class ConditionExpressionUtils {
5
+
6
+ /**
7
+ * 判断表达式是否是函数
8
+ * @param expr 如 name.contains("aa")
9
+ */
10
+ static isFunction(expr) {
11
+ const regExp = /\w+\.\w+\(.*\)/;
12
+ return regExp.test(expr);
13
+ }
14
+
15
+ /**
16
+ * 解析函数, 得到变量,函数名,参数
17
+ * 注意:只支持单参数函数
18
+ * @param expr
19
+ */
20
+ static parseStrFunction(expr) {
21
+ const regExp = /^(\w+)(\.\w+)\("(.*)"\)$/;
22
+ const match = expr.match(regExp);
23
+ if (!match) {
24
+ return null;
25
+ }
26
+ const [, left, op, right] = match;
27
+ return { left, op,right };
28
+ }
29
+
30
+ /**
31
+ * 解析普通表达式, 如 a==1, b>5, c=="你好"
32
+ *
33
+ */
34
+ static parse(expr) {
35
+ // 支持的比较操作符, 注意顺序,先比较的操作符长的
36
+ const operators = ['==', '!=', '<=', '>=', '<', '>'];
37
+
38
+ const op = operators.find(op => StringUtils.contains(expr, op))
39
+ if (!op) {
40
+ return null
41
+ }
42
+
43
+ const index = expr.indexOf(op);
44
+ const left = expr.substring(0, index).trim();
45
+ let right = expr.substring(index + op.length).trim();
46
+ right = StringUtils.removePrefixAndSuffix(right, '"', '"')
47
+
48
+ return {left, op, right};
49
+ }
50
+
51
+
52
+ }
53
+
@@ -1,4 +1,4 @@
1
- import {isTextFieldEntryEdited, TextFieldEntry} from '@bpmn-io/properties-panel';
1
+ import {isTextFieldEntryEdited, TextAreaEntry, TextFieldEntry} from '@bpmn-io/properties-panel';
2
2
  import {useService} from 'bpmn-js-properties-panel';
3
3
  import {renderReact} from "./utils";
4
4
  import {ConditionDesignButton} from "./ConditionDesign";
@@ -61,10 +61,10 @@ function Component(props) {
61
61
  const moddle = useService('moddle');
62
62
 
63
63
 
64
- return TextFieldEntry({
64
+ return TextAreaEntry({
65
65
  element,
66
66
  id: id,
67
- label: '条件表达式',
67
+ label: '条件表达式(JUEL)',
68
68
  getValue,
69
69
  setValue: value=>setValue(value,element,modeling,moddle),
70
70
  debounce,
@@ -1,76 +1,76 @@
1
1
  import React from "react";
2
2
  import {HttpUtils, ProTable} from "../../../framework";
3
3
 
4
- export default class extends React.Component {
4
+ export default class extends React.Component {
5
5
 
6
6
  columns = [
7
- {
8
- title: 'ID',
9
- dataIndex: 'id',
10
- },
11
- {
12
- title: '分类',
13
- dataIndex: 'category',
14
- },
15
- {
16
- title: '名称',
17
- dataIndex: 'name',
18
- },
19
- {
20
- title: '键',
21
- dataIndex: 'key',
22
- },
23
- {
24
- title: '描述',
25
- dataIndex: 'description',
26
- },
27
- {
28
- title: '版本',
29
- dataIndex: 'version',
30
- },
31
- {
32
- title: '资源名称',
33
- dataIndex: 'resourceName',
34
- },
35
- {
36
- title: '部署ID',
37
- dataIndex: 'deploymentId',
38
- },
39
- {
40
- title: '图表资源名称',
41
- dataIndex: 'diagramResourceName',
42
- },
43
- {
44
- title: '是否有开始表单键',
45
- dataIndex: 'hasStartFormKey',
46
- render: (value) => value ? '是' : '否',
47
- },
48
- {
49
- title: '是否有图形符号',
50
- dataIndex: 'hasGraphicalNotation',
51
- render: (value) => value ? '是' : '否',
52
- },
53
- {
54
- title: '是否挂起',
55
- dataIndex: 'suspended',
56
- render: (value) => value ? '是' : '否',
57
- },
58
- {
59
- title: '租户ID',
60
- dataIndex: 'tenantId',
61
- },
62
- {
63
- title: '派生自',
64
- dataIndex: 'derivedFrom',
65
- },
66
- {
67
- title: '根派生来源',
68
- dataIndex: 'derivedFromRoot',
69
- },
70
- {
71
- title: '派生版本',
72
- dataIndex: 'derivedVersion',
73
- },
7
+ {
8
+ title: 'ID',
9
+ dataIndex: 'id',
10
+ },
11
+ {
12
+ title: '分类',
13
+ dataIndex: 'category',
14
+ },
15
+ {
16
+ title: '名称',
17
+ dataIndex: 'name',
18
+ },
19
+ {
20
+ title: '键',
21
+ dataIndex: 'key',
22
+ },
23
+ {
24
+ title: '描述',
25
+ dataIndex: 'description',
26
+ },
27
+ {
28
+ title: '版本',
29
+ dataIndex: 'version',
30
+ },
31
+ {
32
+ title: '资源名称',
33
+ dataIndex: 'resourceName',
34
+ },
35
+ {
36
+ title: '部署ID',
37
+ dataIndex: 'deploymentId',
38
+ },
39
+ {
40
+ title: '图表资源名称',
41
+ dataIndex: 'diagramResourceName',
42
+ },
43
+ {
44
+ title: '是否有开始表单键',
45
+ dataIndex: 'hasStartFormKey',
46
+ render: (value) => value ? '是' : '否',
47
+ },
48
+ {
49
+ title: '是否有图形符号',
50
+ dataIndex: 'hasGraphicalNotation',
51
+ render: (value) => value ? '是' : '否',
52
+ },
53
+ {
54
+ title: '是否挂起',
55
+ dataIndex: 'suspended',
56
+ render: (value) => value ? '是' : '否',
57
+ },
58
+ {
59
+ title: '租户ID',
60
+ dataIndex: 'tenantId',
61
+ },
62
+ {
63
+ title: '派生自',
64
+ dataIndex: 'derivedFrom',
65
+ },
66
+ {
67
+ title: '根派生来源',
68
+ dataIndex: 'derivedFromRoot',
69
+ },
70
+ {
71
+ title: '派生版本',
72
+ dataIndex: 'derivedVersion',
73
+ },
74
74
 
75
75
 
76
76
  ]
@@ -100,7 +100,7 @@ export default class extends React.Component {
100
100
  },
101
101
  {
102
102
  key: '2',
103
- label: '流程',
103
+ label: '流程图',
104
104
  icon: <ShareAltOutlined/>,
105
105
  children: this.renderProcess(img, commentList)
106
106
  }
@@ -173,7 +173,7 @@ export default class extends React.Component {
173
173
 
174
174
 
175
175
  render() {
176
- return <Page>
176
+ return <Page padding>
177
177
  <ProTable
178
178
  actionRef={this.tableRef}
179
179
  toolBarRender={() => {
@@ -1,136 +0,0 @@
1
- import {Button, Card, Form, Modal, Table} from 'antd'
2
- import React from 'react'
3
-
4
- import {ButtonList, HttpUtils, ValueType} from '../../../framework'
5
-
6
-
7
- export default class extends React.Component {
8
-
9
- state = {
10
- data: [],
11
- formValues: {},
12
- formOpen: false
13
- }
14
-
15
- formRef = React.createRef()
16
- tableRef = React.createRef()
17
-
18
- columns = [
19
- {
20
- title: '参数名称',
21
- dataIndex: 'name',
22
- width: 300,
23
-
24
- },
25
- {
26
- title: '编码',
27
- dataIndex: 'code',
28
- },
29
-
30
-
31
- {
32
- title: '值',
33
- dataIndex: 'value',
34
- render(v, record) {
35
- if (v != null) {
36
- return ValueType.renderView(record.valueType, {value: v})
37
- }
38
- }
39
- },
40
-
41
-
42
- {
43
- title: '说明',
44
- dataIndex: 'description',
45
- },
46
- {
47
- title: '更新时间',
48
- dataIndex: 'updateTime',
49
- },
50
-
51
- {
52
- title: '操作',
53
- dataIndex: 'option',
54
- fixed: 'right',
55
- render: (_, record) => (
56
- <ButtonList>
57
- <Button size='small' perm='sysConfig:save' onClick={() => this.handleEdit(record)}> 修改 </Button>
58
- </ButtonList>
59
- ),
60
- },
61
- ]
62
-
63
- componentDidMount() {
64
- this.loadData();
65
- }
66
-
67
- loadData() {
68
- HttpUtils.get('admin/sysConfig/page').then(rs => {
69
- this.setState({data: rs})
70
- })
71
- }
72
-
73
- handleEdit = record => {
74
- this.setState({formOpen: true, formValues: record})
75
- }
76
-
77
-
78
- onFinish = values => {
79
- HttpUtils.post('admin/sysConfig/save', values).then(rs => {
80
- this.setState({formOpen: false})
81
- this.loadData()
82
- })
83
- }
84
-
85
-
86
- render() {
87
- return <>
88
- <Card loading={this.state.data.length === 0}>
89
- <Table
90
- dataSource={this.state.data}
91
- actionRef={this.tableRef}
92
- pagination={false}
93
- expandable={
94
- {
95
- defaultExpandAllRows: true
96
- }
97
- }
98
- columns={this.columns}
99
- rowKey='id'
100
- bordered
101
- size='small'
102
- />
103
- </Card>
104
-
105
-
106
- <Modal title={'编辑系统参数'}
107
- open={this.state.formOpen}
108
- onOk={() => this.formRef.current.submit()}
109
- onCancel={() => this.setState({formOpen: false})}
110
- destroyOnHidden
111
- maskClosable={false}
112
- width={400}
113
- >
114
-
115
- <Form ref={this.formRef}
116
- initialValues={this.state.formValues}
117
- onFinish={this.onFinish}
118
- layout='vertical'
119
- >
120
-
121
- <Form.Item name='id' noStyle/>
122
-
123
- <Form.Item name='value' label={this.state.formValues.label}>
124
- {ValueType.renderField(this.state.formValues.valueType)}
125
- </Form.Item>
126
-
127
- </Form>
128
- </Modal>
129
- </>
130
-
131
-
132
- }
133
- }
134
-
135
-
136
-