vue2-client 1.11.4 → 1.11.6-alpha

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 (57) hide show
  1. package/.babelrc +3 -0
  2. package/babel.config.js +18 -21
  3. package/jest.config.js +22 -21
  4. package/package.json +5 -4
  5. package/src/base-client/components/common/CitySelect/CitySelect.vue +366 -342
  6. package/src/base-client/components/common/Upload/Upload.vue +322 -322
  7. package/src/base-client/components/common/XDescriptions/XDescriptionsGroup.vue +314 -304
  8. package/src/base-client/components/common/XDescriptions/demo.vue +51 -50
  9. package/src/base-client/components/common/XFormGroup/demo.vue +39 -46
  10. package/src/base-client/components/common/XFormTable/demo.vue +60 -60
  11. package/src/components/STable/index.js +426 -426
  12. package/src/expression/ExpressionRunner.js +26 -0
  13. package/src/expression/TestExpression.js +508 -0
  14. package/src/expression/core/Delegate.js +113 -0
  15. package/src/expression/core/Expression.js +1323 -0
  16. package/src/expression/core/Program.js +933 -0
  17. package/src/expression/core/Token.js +27 -0
  18. package/src/expression/enums/ExpressionType.js +81 -0
  19. package/src/expression/enums/TokenType.js +11 -0
  20. package/src/expression/exception/BreakWayException.js +2 -0
  21. package/src/expression/exception/ContinueWayException.js +2 -0
  22. package/src/expression/exception/ExpressionException.js +28 -0
  23. package/src/expression/exception/ReturnWayException.js +14 -0
  24. package/src/expression/exception/ServiceException.js +22 -0
  25. package/src/expression/instances/JSONArray.js +48 -0
  26. package/src/expression/instances/JSONObject.js +122 -0
  27. package/src/expression/instances/LogicConsole.js +45 -0
  28. package/src/expression/ts/ExpressionRunner.ts +28 -0
  29. package/src/expression/ts/TestExpression.ts +509 -0
  30. package/src/expression/ts/core/Delegate.ts +114 -0
  31. package/src/expression/ts/core/Expression.ts +1309 -0
  32. package/src/expression/ts/core/Program.ts +950 -0
  33. package/src/expression/ts/core/Token.ts +29 -0
  34. package/src/expression/ts/enums/ExpressionType.ts +81 -0
  35. package/src/expression/ts/enums/TokenType.ts +13 -0
  36. package/src/expression/ts/exception/BreakWayException.ts +2 -0
  37. package/src/expression/ts/exception/ContinueWayException.ts +2 -0
  38. package/src/expression/ts/exception/ExpressionException.ts +28 -0
  39. package/src/expression/ts/exception/ReturnWayException.ts +14 -0
  40. package/src/expression/ts/exception/ServiceException.ts +22 -0
  41. package/src/expression/ts/instances/JSONArray.ts +48 -0
  42. package/src/expression/ts/instances/JSONObject.ts +109 -0
  43. package/src/expression/ts/instances/LogicConsole.ts +32 -0
  44. package/src/logic/LogicRunner.js +67 -0
  45. package/src/logic/TestLogic.js +13 -0
  46. package/src/logic/plugins/common/DateTools.js +32 -0
  47. package/src/logic/plugins/index.js +5 -0
  48. package/src/logic/ts/LogicRunner.ts +67 -0
  49. package/src/logic/ts/TestLogic.ts +13 -0
  50. package/src/pages/LogicCallExample/index.vue +30 -0
  51. package/src/router/async/router.map.js +4 -2
  52. package/src/services/user.js +2 -0
  53. package/src/store/mutation-types.js +1 -0
  54. package/src/utils/EncryptUtil.js +23 -0
  55. package/src/utils/indexedDB.js +234 -234
  56. package/src/utils/request.js +382 -362
  57. package/test/request.test.js +17 -0
@@ -1,304 +1,314 @@
1
- <template>
2
- <a-row id="XDescriptionGroup" :gutter="24">
3
- <a-col :span="4" v-if="showLeftTab && realData.length">
4
- <a-tabs tab-position="left" v-model="activeTab" @change="scrollToGroup">
5
- <template v-for="(item,index) in realData">
6
- <a-tab-pane
7
- :tab="item.title"
8
- :key="index"
9
- v-if="item.title">
10
- </a-tab-pane>
11
- </template>
12
- </a-tabs>
13
- </a-col>
14
- <a-col :span="showLeftTab ? 20 : 24" ref="descriptionsGroupContext" class="descriptionsGroupContext">
15
- <div
16
- class="descriptions-item"
17
- :ref="`descriptions-item-${realDataIndex}`"
18
- :key="realDataIndex"
19
- v-for="(realDataItem, realDataIndex) in realData">
20
- <template v-if="!loadError">
21
- <!-- 带有子的详情 -->
22
- <template
23
- v-if="realDataItem.title && groups[realDataItem.title]?.type ==='array'"
24
- >
25
- <div class="ant-descriptions-title">{{ realDataItem.title }}</div>
26
- <div class="descriptions-array-item">
27
- <a-descriptions
28
- v-for="(arrayItem,arrayIndex) in realDataItem.column"
29
- :column="isMobile ? 1 : column"
30
- size="small"
31
- :key="arrayIndex"
32
- :title="arrayItem.title">
33
- {{ arrayItem }}
34
- <template v-for="(item, index) in arrayItem.column">
35
- <!-- 大多数情况 循环下 空值省略不展示,todo 后期可能加配置处理 -->
36
- <a-descriptions-item
37
- :key="index"
38
- v-if="item.value"
39
- :label="item.key">
40
- {{ formatText(item.value) }}
41
- </a-descriptions-item>
42
- </template>
43
- </a-descriptions>
44
- </div>
45
- </template>
46
- <a-descriptions
47
- v-else-if="realDataItem.title"
48
- :column="isMobile ? 1 : column"
49
- :title="realDataItem.title">
50
- <a-descriptions-item
51
- v-for="(item, index) in realDataItem.column"
52
- :key="index"
53
- :span="item.span || 1"
54
- :label="item.key">
55
- <nobr>{{ item.value || '--' }}</nobr>
56
- </a-descriptions-item>
57
- </a-descriptions>
58
- </template>
59
- </div>
60
- </a-col>
61
- </a-row>
62
- </template>
63
- <script>
64
-
65
- import { mapState } from 'vuex'
66
- import { getRealKeyData } from '@vue2-client/utils/formatter'
67
- import { getConfigByName } from '@vue2-client/services/api/common'
68
- import XAddNativeForm from '@vue2-client/base-client/components/common/XAddNativeForm/XAddNativeForm.vue'
69
-
70
- export default {
71
- name: 'XDescriptionsGroup',
72
- components: {
73
- XAddNativeForm
74
- },
75
- props: {
76
- // 内容
77
- data: {
78
- type: Object,
79
- required: true,
80
- default: undefined
81
- },
82
- // 展示列配置 格式 {title:[{key,name}]} {描述列表标题:[{字段名,字段中文名}]}
83
- // {
84
- // "groups": {
85
- // "表具信息": {
86
- // "f_gasbrand": "气表品牌"
87
- // },
88
- // "客户信息": {
89
- // "f_userinfo_code": "用户编号"
90
- // },
91
- // "设备信息":{
92
- // "type": "array",
93
- // "value": {
94
- // "f_devices_num": "设备数量",
95
- // "f_devices_type": "设备类型",
96
- // },
97
- // "key": "devices"
98
- // }
99
- // }
100
- // }
101
- configName: {
102
- type: String,
103
- required: true,
104
- default: ''
105
- },
106
- // 配置所属命名空间
107
- serviceName: {
108
- type: String,
109
- default: process.env.VUE_APP_SYSTEM_NAME
110
- },
111
- // 每列显示数量
112
- column: {
113
- type: Number,
114
- default: 3
115
- },
116
- // 处理 key tuf_f_userinfo_id -> f_userinfo_id
117
- getRealData: {
118
- type: Boolean,
119
- default: false
120
- },
121
- // 是否展示左侧tab
122
- showLeftTab: {
123
- type: Boolean,
124
- default: false
125
- }
126
- },
127
- mounted () {
128
- },
129
- beforeDestroy () {
130
- const formGroupContext = this.$refs.formGroupContext?.$el
131
- if (formGroupContext && formGroupContext.removeEventListener) {
132
- formGroupContext.removeEventListener('scroll', this.onScroll)
133
- }
134
- },
135
- created () {
136
- this.initConfig()
137
- },
138
- data () {
139
- return {
140
- // 加载状态
141
- loading: false,
142
- loadError: false,
143
- realData: [],
144
- // 获取到的配置组
145
- groups: {},
146
- activeTab: 0
147
- }
148
- },
149
- computed: {
150
- ...mapState('setting', { isMobile: 'isMobile' })
151
- },
152
- methods: {
153
- initConfig () {
154
- this.loading = true
155
- if (this.configName) {
156
- this.getConfig()
157
- this.$nextTick(() => {
158
- const formGroupContext = this.$refs.descriptionsGroupContext?.$el
159
- if (formGroupContext && formGroupContext.addEventListener) {
160
- formGroupContext.addEventListener('scroll', this.onScroll)
161
- }
162
- })
163
- } else {
164
- this.loading = false
165
- this.loadError = true
166
- }
167
- },
168
- scrollToGroup (index) {
169
- const groupElement = this.$refs[`descriptions-item-${index}`][0]
170
- if (groupElement) {
171
- groupElement.scrollIntoView({ behavior: 'smooth' })
172
- }
173
- },
174
- getConfig () {
175
- getConfigByName(this.configName, this.serviceName, (res) => {
176
- if (res.groups) {
177
- this.groups = res.groups
178
- this.realData = Object.keys(res.groups).map((h) => {
179
- const hObj = res.groups[h]
180
- const dataItem = {}
181
- dataItem.title = h
182
- dataItem.column = []
183
- if (hObj.type && hObj.type === 'array') {
184
- // 从data 取出数组
185
- const arrayData = this.data[hObj.key]
186
- const arrayDataItem = arrayData.map((item, index) => {
187
- const arrayItem = {
188
- title: `${h} ${index + 1}`,
189
- column: Object.keys(hObj.value).map((key) => {
190
- return {
191
- key: hObj.value[key],
192
- value: item[key]
193
- }
194
- })
195
- }
196
- // 如果所有 value 都是空的 return null todo 后期可能做成配置
197
- const isAllNull = arrayItem.column.every((item) => {
198
- return item.value === null || item.value === ''
199
- })
200
- return isAllNull ? null : arrayItem
201
- }).filter((item) => item)
202
- if (arrayDataItem.length) {
203
- dataItem.column = arrayDataItem
204
- return dataItem
205
- } else {
206
- return null
207
- }
208
- } else {
209
- const tempData = Object.keys(hObj).map((key) => {
210
- // 如果 hObj[key] jsonobject
211
- if (typeof hObj[key] === 'object') {
212
- return { key: hObj[key].name, value: this.getRealKeyData(this.data, key), span: hObj[key].span || 1 }
213
- }
214
- // 如果是数组形态
215
- return { key: hObj[key], value: this.getRealKeyData(this.data, key) }
216
- })
217
- // 如果所有 value 都是空的 return null todo 后期可能做成配置
218
- const isAllNull = tempData.every((item) => {
219
- return item.value === null || item.value === ''
220
- })
221
- if (isAllNull) {
222
- return null
223
- } else {
224
- dataItem.column = tempData
225
- return dataItem
226
- }
227
- }
228
- }).filter((item) => item)
229
- } else {
230
- this.loading = false
231
- this.loadError = true
232
- }
233
- })
234
- },
235
- // 文字格式化
236
- formatText (value) {
237
- return value || '--'
238
- },
239
- getRealKeyData (data, key) {
240
- if (this.getRealData) {
241
- return getRealKeyData(data)[key] || ''
242
- } else {
243
- return this.data[key] || ''
244
- }
245
- },
246
- onScroll () {
247
- const formGroupContext = this.$refs.descriptionsGroupContext.$el
248
- let groupItems = []
249
- if (formGroupContext && formGroupContext.querySelectorAll) {
250
- groupItems = formGroupContext.querySelectorAll('.descriptions-item')
251
- }
252
- let activeIndex = this.activeTab
253
-
254
- groupItems.forEach((item, index) => {
255
- const rect = item.getBoundingClientRect()
256
- if (rect.top <= 205 && rect.bottom > 200) {
257
- activeIndex = index
258
- }
259
- })
260
- this.activeTab = activeIndex
261
- }
262
- },
263
- watch: {
264
- content: {
265
- handler () {
266
- this.initConfig()
267
- }
268
- },
269
- configName: {
270
- handler () {
271
- this.initConfig()
272
- }
273
- },
274
- serviceName: {
275
- handler () {
276
- this.initConfig()
277
- }
278
- }
279
- }
280
- }
281
- </script>
282
-
283
- <style lang="less" scoped>
284
- #XDescriptionGroup {
285
- height: 100%;
286
-
287
- :deep(.ant-descriptions-title) {
288
- color: @primary-color;
289
- }
290
-
291
- .descriptions-item {
292
- margin-bottom: 8px;
293
- }
294
-
295
- .descriptions-array-item {
296
- padding-left: 1rem;
297
- }
298
-
299
- .descriptionsGroupContext {
300
- height: 100%;
301
- overflow-y: scroll;
302
- }
303
- }
304
- </style>
1
+ <template>
2
+ <a-row id="XDescriptionGroup" :gutter="24">
3
+ <a-col :span="4" v-if="showLeftTab && realData.length">
4
+ <a-tabs tab-position="left" v-model="activeTab" @change="scrollToGroup">
5
+ <template v-for="(item,index) in realData">
6
+ <a-tab-pane
7
+ :tab="item.title"
8
+ :key="index"
9
+ v-if="item.title">
10
+ </a-tab-pane>
11
+ </template>
12
+ </a-tabs>
13
+ </a-col>
14
+ <a-col :span="showLeftTab ? 20 : 24" ref="descriptionsGroupContext" class="descriptionsGroupContext">
15
+ <div
16
+ class="descriptions-item"
17
+ :ref="`descriptions-item-${realDataIndex}`"
18
+ :key="realDataIndex"
19
+ v-for="(realDataItem, realDataIndex) in realData">
20
+ <template v-if="!loadError">
21
+ <!-- 带有子的详情 -->
22
+ <template
23
+ v-if="realDataItem.title && groups[realDataItem.title]?.type ==='array'"
24
+ >
25
+ <div class="ant-descriptions-title">{{ realDataItem.title }}</div>
26
+ <div class="descriptions-array-item">
27
+ <a-descriptions
28
+ v-for="(arrayItem,arrayIndex) in realDataItem.column"
29
+ :column="isMobile ? 1 : column"
30
+ size="small"
31
+ :key="arrayIndex"
32
+ :title="arrayItem.title">
33
+ {{ arrayItem }}
34
+ <template v-for="(item, index) in arrayItem.column">
35
+ <!-- 大多数情况 循环下 空值省略不展示,todo 后期可能加配置处理 -->
36
+ <a-descriptions-item
37
+ :key="index"
38
+ v-if="item.value"
39
+ :label="item.key">
40
+ {{ formatText(item.value) }}
41
+ </a-descriptions-item>
42
+ </template>
43
+ </a-descriptions>
44
+ </div>
45
+ </template>
46
+ <a-descriptions
47
+ v-else-if="realDataItem.title"
48
+ :column="isMobile ? 1 : column"
49
+ :title="realDataItem.title">
50
+ <a-descriptions-item
51
+ v-for="(item, index) in realDataItem.column"
52
+ :key="index"
53
+ :span="item.span || 1"
54
+ :label="item.key">
55
+ <nobr>{{ item.value || '--' }}</nobr>
56
+ </a-descriptions-item>
57
+ </a-descriptions>
58
+ </template>
59
+ </div>
60
+ </a-col>
61
+ </a-row>
62
+ </template>
63
+ <script>
64
+
65
+ import { mapState } from 'vuex'
66
+ import { getRealKeyData } from '@vue2-client/utils/formatter'
67
+ import { getConfigByName } from '@vue2-client/services/api/common'
68
+ import XAddNativeForm from '@vue2-client/base-client/components/common/XAddNativeForm/XAddNativeForm.vue'
69
+
70
+ export default {
71
+ name: 'XDescriptionsGroup',
72
+ components: {
73
+ XAddNativeForm
74
+ },
75
+ props: {
76
+ // 内容
77
+ data: {
78
+ type: Object,
79
+ required: true,
80
+ default: undefined
81
+ },
82
+ // 展示列配置 格式 {title:[{key,name}]} {描述列表标题:[{字段名,字段中文名}]}
83
+ // {
84
+ // "groups": {
85
+ // "表具信息": {
86
+ // "f_gasbrand": "气表品牌"
87
+ // },
88
+ // "客户信息": {
89
+ // "f_userinfo_code": "用户编号"
90
+ // },
91
+ // "设备信息":{
92
+ // "type": "array",
93
+ // "value": {
94
+ // "f_devices_num": "设备数量",
95
+ // "f_devices_type": "设备类型",
96
+ // },
97
+ // "key": "devices"
98
+ // }
99
+ // }
100
+ // }
101
+ // 数据模式结构
102
+ // "groups": [{
103
+ // "name": "客户信息",
104
+ // "fields": [
105
+ // {
106
+ // "name": "备注",
107
+ // "key": "f_comments",
108
+ // "span": 3
109
+ // },
110
+ // {
111
+ // "name": "地址",
112
+ // "key": "f_address",
113
+ // "span": 3
114
+ // }]
115
+ // }]
116
+ configName: {
117
+ type: String,
118
+ required: true,
119
+ default: ''
120
+ },
121
+ // 配置所属命名空间
122
+ serviceName: {
123
+ type: String,
124
+ default: process.env.VUE_APP_SYSTEM_NAME
125
+ },
126
+ // 每列显示数量
127
+ column: {
128
+ type: Number,
129
+ default: 3
130
+ },
131
+ // 处理 key tuf_f_userinfo_id -> f_userinfo_id
132
+ getRealData: {
133
+ type: Boolean,
134
+ default: false
135
+ },
136
+ // 是否展示左侧tab
137
+ showLeftTab: {
138
+ type: Boolean,
139
+ default: false
140
+ }
141
+ },
142
+ mounted () {
143
+ },
144
+ beforeDestroy () {
145
+ const formGroupContext = this.$refs.formGroupContext?.$el
146
+ if (formGroupContext && formGroupContext.removeEventListener) {
147
+ formGroupContext.removeEventListener('scroll', this.onScroll)
148
+ }
149
+ },
150
+ created () {
151
+ this.initConfig()
152
+ },
153
+ data () {
154
+ return {
155
+ // 加载状态
156
+ loading: false,
157
+ loadError: false,
158
+ realData: [],
159
+ // 获取到的配置组
160
+ groups: {},
161
+ activeTab: 0
162
+ }
163
+ },
164
+ computed: {
165
+ ...mapState('setting', { isMobile: 'isMobile' })
166
+ },
167
+ methods: {
168
+ initConfig () {
169
+ this.loading = true
170
+ if (this.configName) {
171
+ this.getConfig()
172
+ this.$nextTick(() => {
173
+ const formGroupContext = this.$refs.descriptionsGroupContext?.$el
174
+ if (formGroupContext && formGroupContext.addEventListener) {
175
+ formGroupContext.addEventListener('scroll', this.onScroll)
176
+ }
177
+ })
178
+ } else {
179
+ this.loading = false
180
+ this.loadError = true
181
+ }
182
+ },
183
+ scrollToGroup (index) {
184
+ const groupElement = this.$refs[`descriptions-item-${index}`][0]
185
+ if (groupElement) {
186
+ groupElement.scrollIntoView({ behavior: 'smooth' })
187
+ }
188
+ },
189
+ getConfig () {
190
+ getConfigByName(this.configName, this.serviceName, (res) => {
191
+ if (res.groups) {
192
+ const groups = Array.isArray(res.groups)
193
+ ? res.groups
194
+ : Object.entries(res.groups).map(([groupName, groupConfig]) => {
195
+ if (groupConfig.type === 'array') {
196
+ return {
197
+ name: groupName,
198
+ type: 'array',
199
+ key: groupConfig.key,
200
+ fields: Object.entries(groupConfig.value || {}).map(([k, v]) => ({
201
+ key: k,
202
+ name: v
203
+ }))
204
+ }
205
+ }
206
+
207
+ // 处理普通旧格式配置
208
+ return {
209
+ name: groupName,
210
+ fields: Object.entries(groupConfig).map(([fieldKey, fieldValue]) => ({
211
+ key: fieldKey,
212
+ name: typeof fieldValue === 'string' ? fieldValue : fieldValue.name,
213
+ ...(typeof fieldValue === 'object' ? fieldValue : {})
214
+ }))
215
+ }
216
+ })
217
+
218
+ this.groups = groups
219
+ this.realData = groups.map(group => {
220
+ const dataItem = { title: group.name }
221
+
222
+ if (group.type === 'array') {
223
+ // 处理数组类型数据
224
+ const arrayData = this.data[group.key] || []
225
+ dataItem.column = arrayData.map((item, index) => ({
226
+ title: `${group.name} ${index + 1}`,
227
+ column: group.fields.map(field => ({
228
+ key: field.name,
229
+ value: item[field.key]
230
+ }))
231
+ })).filter(Boolean)
232
+ } else {
233
+ dataItem.column = group.fields.map(field => ({
234
+ key: field.name,
235
+ value: this.getRealKeyData(this.data, field.key),
236
+ span: field.span
237
+ }))
238
+ }
239
+
240
+ return dataItem.column.length > 0 ? dataItem : null
241
+ }).filter(Boolean)
242
+ }
243
+ })
244
+ },
245
+ // 文字格式化
246
+ formatText (value) {
247
+ return value || '--'
248
+ },
249
+ getRealKeyData (data, key) {
250
+ if (this.getRealData) {
251
+ return getRealKeyData(data)[key] || ''
252
+ } else {
253
+ return this.data[key] || ''
254
+ }
255
+ },
256
+ onScroll () {
257
+ const formGroupContext = this.$refs.descriptionsGroupContext.$el
258
+ let groupItems = []
259
+ if (formGroupContext && formGroupContext.querySelectorAll) {
260
+ groupItems = formGroupContext.querySelectorAll('.descriptions-item')
261
+ }
262
+ let activeIndex = this.activeTab
263
+
264
+ groupItems.forEach((item, index) => {
265
+ const rect = item.getBoundingClientRect()
266
+ if (rect.top <= 205 && rect.bottom > 200) {
267
+ activeIndex = index
268
+ }
269
+ })
270
+ this.activeTab = activeIndex
271
+ }
272
+ },
273
+ watch: {
274
+ content: {
275
+ handler () {
276
+ this.initConfig()
277
+ }
278
+ },
279
+ configName: {
280
+ handler () {
281
+ this.initConfig()
282
+ }
283
+ },
284
+ serviceName: {
285
+ handler () {
286
+ this.initConfig()
287
+ }
288
+ }
289
+ }
290
+ }
291
+ </script>
292
+
293
+ <style lang="less" scoped>
294
+ #XDescriptionGroup {
295
+ height: 100%;
296
+
297
+ :deep(.ant-descriptions-title) {
298
+ color: @primary-color;
299
+ }
300
+
301
+ .descriptions-item {
302
+ margin-bottom: 8px;
303
+ }
304
+
305
+ .descriptions-array-item {
306
+ padding-left: 1rem;
307
+ }
308
+
309
+ .descriptionsGroupContext {
310
+ height: 100%;
311
+ overflow-y: scroll;
312
+ }
313
+ }
314
+ </style>