free-fe-core-modules 0.0.8 → 0.0.10
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/components/Basic/SummaryHead.vue +1 -6
- package/components/Dialog/BasicDialog.vue +139 -129
- package/composible/useFormValidator.js +8 -7
- package/composible/useObjectData.js +3 -3
- package/free-field/Fields/Labels.vue +1 -0
- package/free-field/Fields/Number.js +2 -2
- package/free-field/Fields/Password.js +1 -1
- package/free-field/Fields/Permission.vue +1 -0
- package/free-field/Fields/PermissionEditor.vue +0 -1
- package/free-field/Fields/Search.vue +7 -10
- package/free-field/Fields/Select.vue +1 -1
- package/free-field/Fields/Tabs.vue +1 -2
- package/free-field/composible/fieldWrapper.js +1 -1
- package/free-field/composible/useFreeField.js +51 -73
- package/i18n/en-us/index.js +5 -1
- package/i18n/zh-cn/index.js +71 -66
- package/index.js +23 -1
- package/package.json +1 -1
- package/view/dict/index.vue +29 -27
- package/view/error/list.vue +17 -20
- package/view/menu/index.vue +2 -2
|
@@ -123,12 +123,7 @@ export default defineComponent({
|
|
|
123
123
|
for (let j = 0; j < filters.length; j += 1) {
|
|
124
124
|
const f = filters[j];
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
if (filterFunc) {
|
|
128
|
-
item.number = filterFunc(
|
|
129
|
-
item.number,
|
|
130
|
-
);
|
|
131
|
-
}
|
|
126
|
+
item.number = this.$filter(f, item.number);
|
|
132
127
|
}
|
|
133
128
|
|
|
134
129
|
// remove the filter to avoid filter multiple times
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
</template>
|
|
103
103
|
|
|
104
104
|
<script>
|
|
105
|
-
import { defineComponent } from 'vue';
|
|
105
|
+
import { defineComponent, ref, computed, watch } from 'vue';
|
|
106
106
|
import { useFormValidator } from '../../composible/useFormValidator';
|
|
107
107
|
import FreeField from '../../free-field/composible/fieldWrapper';
|
|
108
108
|
import EIcon from '../Basic/EIcon.vue';
|
|
@@ -157,170 +157,180 @@ export default defineComponent({
|
|
|
157
157
|
FreeField,
|
|
158
158
|
EIcon,
|
|
159
159
|
},
|
|
160
|
-
setup(props, { expose }) {
|
|
160
|
+
setup(props, { expose, emit }) {
|
|
161
161
|
const { validate } = useFormValidator('fieldsToValid');
|
|
162
|
-
expose({
|
|
163
|
-
validate,
|
|
164
|
-
})
|
|
165
162
|
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
data() {
|
|
169
|
-
return {
|
|
170
|
-
timeLeft: 0,
|
|
171
|
-
textContent: '',
|
|
172
|
-
textValid: true,
|
|
173
|
-
timer: undefined,
|
|
174
|
-
promise: '',
|
|
175
|
-
resolve: '',
|
|
176
|
-
reject: '',
|
|
177
|
-
};
|
|
178
|
-
},
|
|
179
|
-
watch: {
|
|
180
|
-
visible() {
|
|
181
|
-
if (this.visible) {
|
|
182
|
-
this.timeout_counter();
|
|
183
|
-
this.show();
|
|
184
|
-
} else {
|
|
185
|
-
this.hide();
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
computed: {
|
|
190
|
-
disabled() {
|
|
191
|
-
if (typeof this.okDisabled === 'object') {
|
|
192
|
-
return this.okDisabled.value;
|
|
193
|
-
}
|
|
163
|
+
const dialog = ref(null);
|
|
194
164
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
165
|
+
const timeLeft = ref(0),
|
|
166
|
+
textContent = ref(''),
|
|
167
|
+
textValid = ref(true),
|
|
168
|
+
timer = ref(undefined),
|
|
169
|
+
promise = ref(null),
|
|
170
|
+
resolve = ref(null),
|
|
171
|
+
reject = ref(null);
|
|
200
172
|
|
|
201
|
-
|
|
202
|
-
|
|
173
|
+
const timeout_counter = () => {
|
|
174
|
+
if (!props.timeout) {
|
|
175
|
+
return;
|
|
203
176
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
177
|
+
|
|
178
|
+
timeLeft.value = props.timeout;
|
|
179
|
+
timer.value = setInterval(() => {
|
|
180
|
+
timeLeft.value -= 1;
|
|
181
|
+
if (timeLeft.value < 1) {
|
|
182
|
+
clearInterval(timer.value);
|
|
183
|
+
btn_ok();
|
|
184
|
+
}
|
|
185
|
+
}, 1000);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const show = () => {
|
|
189
|
+
dialog.value.show();
|
|
190
|
+
timeout_counter();
|
|
191
|
+
|
|
192
|
+
promise.value = new Promise((resv, rej) => {
|
|
193
|
+
resolve.value = resv;
|
|
194
|
+
reject.value = rej;
|
|
217
195
|
});
|
|
218
196
|
|
|
219
|
-
return
|
|
220
|
-
}
|
|
197
|
+
return promise.value;
|
|
198
|
+
};
|
|
221
199
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
onOKClick() {
|
|
233
|
-
// on OK, it is REQUIRED to
|
|
234
|
-
// emit "ok" event (with optional payload)
|
|
235
|
-
// before hiding the QDialog
|
|
236
|
-
// this.$emit('ok');
|
|
237
|
-
// or with payload: this.$emit('ok', { ... })
|
|
238
|
-
|
|
239
|
-
// // validate
|
|
240
|
-
// if (this.validateFunc && typeof this.validateFunc === 'function') {
|
|
241
|
-
// // now we only have such content, but later we might will have more
|
|
242
|
-
// this.textValid = this.validateFunc(this.textContent);
|
|
243
|
-
// if (!this.textValid) return;
|
|
244
|
-
// }
|
|
245
|
-
if (!this.canOK || !this.validate()) {
|
|
200
|
+
const hide = () => {
|
|
201
|
+
dialog.value.hide();
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const onDialogHide = () => {
|
|
205
|
+
emit('hide');
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const onOKClick = () => {
|
|
209
|
+
if (!props.canOK || !validate.value()) {
|
|
246
210
|
return;
|
|
247
211
|
}
|
|
248
212
|
|
|
249
|
-
|
|
213
|
+
emit('ok');
|
|
250
214
|
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
clearInterval(
|
|
215
|
+
if (timer.value) {
|
|
216
|
+
timeLeft.value = 0;
|
|
217
|
+
clearInterval(timer.value);
|
|
254
218
|
}
|
|
255
219
|
|
|
256
|
-
if (
|
|
257
|
-
if (
|
|
258
|
-
|
|
220
|
+
if (resolve.value) {
|
|
221
|
+
if (props.needText) {
|
|
222
|
+
resolve.value(textContent.value);
|
|
259
223
|
} else {
|
|
260
|
-
|
|
224
|
+
resolve.value('confirm');
|
|
261
225
|
}
|
|
262
226
|
|
|
263
|
-
|
|
264
|
-
|
|
227
|
+
hide();
|
|
228
|
+
|
|
229
|
+
if (typeof props.remove === 'function'){
|
|
230
|
+
props.remove();
|
|
231
|
+
}
|
|
265
232
|
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const btnCancel = () => {
|
|
236
|
+
if (!props.canCancel) return;
|
|
269
237
|
|
|
270
|
-
|
|
238
|
+
emit('cancel');
|
|
271
239
|
|
|
272
|
-
if (
|
|
273
|
-
|
|
274
|
-
clearInterval(
|
|
240
|
+
if (timer.value) {
|
|
241
|
+
timeLeft.value = 0;
|
|
242
|
+
clearInterval(timer.value);
|
|
275
243
|
}
|
|
276
244
|
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
|
|
245
|
+
if (reject.value) {
|
|
246
|
+
reject.value('cancel');
|
|
247
|
+
|
|
248
|
+
if (typeof props.remove === 'function'){
|
|
249
|
+
props.remove();
|
|
250
|
+
}
|
|
280
251
|
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const btn_ok = () => {
|
|
255
|
+
if (!validate.value()) {
|
|
284
256
|
return;
|
|
285
257
|
}
|
|
286
258
|
|
|
287
|
-
|
|
259
|
+
emit('ok');
|
|
288
260
|
|
|
289
|
-
if (
|
|
290
|
-
|
|
291
|
-
clearInterval(
|
|
261
|
+
if (timer.value) {
|
|
262
|
+
timeLeft.value = 0;
|
|
263
|
+
clearInterval(timer.value);
|
|
292
264
|
}
|
|
293
265
|
|
|
294
|
-
if (
|
|
295
|
-
if (
|
|
296
|
-
|
|
266
|
+
if (resolve.value) {
|
|
267
|
+
if (props.needText) {
|
|
268
|
+
resolve.value(textContent.value);
|
|
297
269
|
} else {
|
|
298
|
-
|
|
270
|
+
resolve.value('confirm');
|
|
299
271
|
}
|
|
300
272
|
|
|
301
|
-
|
|
302
|
-
|
|
273
|
+
hide();
|
|
274
|
+
|
|
275
|
+
if (typeof props.remove === 'function'){
|
|
276
|
+
props.remove();
|
|
277
|
+
}
|
|
303
278
|
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
expose({
|
|
282
|
+
validate,
|
|
283
|
+
show,
|
|
284
|
+
hide,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
watch(() => props.visible, (v) => {
|
|
288
|
+
if (v) {
|
|
289
|
+
timeout_counter();
|
|
290
|
+
show();
|
|
291
|
+
} else {
|
|
292
|
+
hide();
|
|
308
293
|
}
|
|
294
|
+
});
|
|
309
295
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
296
|
+
|
|
297
|
+
const disabled = computed(() => {
|
|
298
|
+
if (typeof props.okDisabled === 'object') {
|
|
299
|
+
return props.okDisabled.value;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return props.okDisabled;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const warningMsg = computed(() => {
|
|
306
|
+
// 设置默认warning
|
|
307
|
+
if (!props.showWarning) return '';
|
|
308
|
+
|
|
309
|
+
if (!props.warning) {
|
|
310
|
+
return '';
|
|
322
311
|
}
|
|
323
|
-
|
|
312
|
+
return props.warning;
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
dialog,
|
|
317
|
+
timeLeft,
|
|
318
|
+
textContent,
|
|
319
|
+
textValid,
|
|
320
|
+
|
|
321
|
+
disabled,
|
|
322
|
+
warningMsg,
|
|
323
|
+
|
|
324
|
+
validate,
|
|
325
|
+
|
|
326
|
+
show,
|
|
327
|
+
hide,
|
|
328
|
+
onDialogHide,
|
|
329
|
+
onOKClick,
|
|
330
|
+
btnCancel,
|
|
331
|
+
btn_ok,
|
|
332
|
+
timeout_counter,
|
|
333
|
+
};
|
|
324
334
|
},
|
|
325
335
|
});
|
|
326
336
|
</script>
|
|
@@ -7,12 +7,12 @@ export function useFormValidator(...list) {
|
|
|
7
7
|
validate: computed(() => {
|
|
8
8
|
return (...args) => {
|
|
9
9
|
if (vm.shouldHide) return true;
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
// could have customized validate function in component
|
|
12
12
|
if (vm.selfValidate && typeof vm.selfValidate === 'function') {
|
|
13
13
|
return vm.selfValidate();
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
const refsList = [];
|
|
17
17
|
for(let i = 0; i < list.length; i += 1) {
|
|
18
18
|
if (typeof list[i] === 'string') {
|
|
@@ -20,24 +20,25 @@ export function useFormValidator(...list) {
|
|
|
20
20
|
} else if (typeof list[i] === 'function') {
|
|
21
21
|
list[i] = list[i]();
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
if (Array.isArray(list[i])) {
|
|
25
25
|
refsList.push(...list[i])
|
|
26
26
|
} else {
|
|
27
27
|
refsList.push(list[i])
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
if (refsList.length <= 0) return true;
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
let hasErr = false;
|
|
34
34
|
for (let i = 0; i < refsList.length; i += 1) {
|
|
35
35
|
let refi = unref(refsList[i]);
|
|
36
36
|
|
|
37
|
+
if (!refi) continue;
|
|
37
38
|
|
|
38
39
|
const validFun = unref(refi.validate || refi.methods?.validate || refi.component?.exposed?.validate|| refi.component?.ctx?.validate);
|
|
39
40
|
const shouldHide = unref(refi.shouldHide || refi.component?.ctx?.shouldHide);
|
|
40
|
-
|
|
41
|
+
|
|
41
42
|
if (typeof validFun === 'function' && shouldHide !== true) {
|
|
42
43
|
hasErr = !validFun() || hasErr;
|
|
43
44
|
|
|
@@ -47,7 +48,7 @@ export function useFormValidator(...list) {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
+
|
|
51
52
|
return !hasErr;
|
|
52
53
|
};
|
|
53
54
|
}),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref, getCurrentInstance, watch, watchEffect
|
|
1
|
+
import { ref, unref, getCurrentInstance, watch, watchEffect } from "vue";
|
|
2
2
|
|
|
3
3
|
export const objectDataProps = {
|
|
4
4
|
GetData: Function,
|
|
@@ -44,12 +44,12 @@ export function useObjectData(props, ctx) {
|
|
|
44
44
|
|
|
45
45
|
if (typeof getData === 'function') {
|
|
46
46
|
Promise.resolve(getData(...args)).then((d) => {
|
|
47
|
-
Object.assign(data.value, d);
|
|
47
|
+
Object.assign(data.value, unref(d));
|
|
48
48
|
}).finally(() => {
|
|
49
49
|
callsLeft.value --;
|
|
50
50
|
});
|
|
51
51
|
} else {
|
|
52
|
-
Object.assign(data.value, getData);
|
|
52
|
+
Object.assign(data.value, unref(getData));
|
|
53
53
|
callsLeft.value --;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -112,7 +112,7 @@ export default defineComponent({
|
|
|
112
112
|
v = Number(props.Field.MaxValue);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
setFieldData(v);
|
|
115
|
+
setFieldData(Number(v));
|
|
116
116
|
})
|
|
117
117
|
|
|
118
118
|
const readonlyNode = () => h(ReadonlyContent, {
|
|
@@ -147,7 +147,7 @@ export default defineComponent({
|
|
|
147
147
|
|
|
148
148
|
modelValue: fieldData.value,
|
|
149
149
|
'onUpdate:modelValue': (v) => {
|
|
150
|
-
setFieldData(v, emit);
|
|
150
|
+
setFieldData(Number(v), emit);
|
|
151
151
|
},
|
|
152
152
|
}, {
|
|
153
153
|
before,
|
|
@@ -47,7 +47,7 @@ export default defineComponent({
|
|
|
47
47
|
},
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
const inputNode = () =>
|
|
50
|
+
const inputNode = computed(() => h(QInput, {
|
|
51
51
|
type: isPwd.value ? 'password' : 'text',
|
|
52
52
|
maxlength: props.Field.Options?.MaxLength,
|
|
53
53
|
autocomplete: props.Field.Options?.autocomplete ? '' : 'new-password',
|
|
@@ -350,9 +350,9 @@ export default defineComponent({
|
|
|
350
350
|
},
|
|
351
351
|
},
|
|
352
352
|
watch: {
|
|
353
|
-
fieldData(n, o) {
|
|
353
|
+
'fieldData.value': function(n, o) {
|
|
354
354
|
// init search data from exist id
|
|
355
|
-
if (
|
|
355
|
+
if (this.fieldData.value === void 0) {
|
|
356
356
|
this.searchSelected = [];
|
|
357
357
|
this.searchData = {};
|
|
358
358
|
this.searchDisplay = '';
|
|
@@ -406,14 +406,11 @@ export default defineComponent({
|
|
|
406
406
|
},
|
|
407
407
|
},
|
|
408
408
|
created() {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
}
|
|
409
|
+
this.searchColumns.forEach((col) => {
|
|
410
|
+
if (col.filters) {
|
|
411
|
+
col.format = (d) => this.$filter(col.filters, d);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
417
414
|
},
|
|
418
415
|
methods: {
|
|
419
416
|
search(p) {
|
|
@@ -124,7 +124,7 @@ export default defineComponent({
|
|
|
124
124
|
const tab = ref(0);
|
|
125
125
|
|
|
126
126
|
if (!Array.isArray(fieldData.value)) {
|
|
127
|
-
setFieldData([{}])
|
|
127
|
+
setFieldData([{}], emit)
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
if (props.Field.Options?.ValueField && props.Field.Default) {
|
|
@@ -140,7 +140,6 @@ export default defineComponent({
|
|
|
140
140
|
fieldData,
|
|
141
141
|
|
|
142
142
|
fieldChanged: () => {
|
|
143
|
-
console.log('field changed', fieldData.value)
|
|
144
143
|
emit('input');
|
|
145
144
|
},
|
|
146
145
|
validate,
|
|
@@ -1,85 +1,63 @@
|
|
|
1
|
-
import { reactive,
|
|
1
|
+
import { reactive, getCurrentInstance, watchEffect } from "vue";
|
|
2
2
|
|
|
3
3
|
export const freeFieldProps = {
|
|
4
4
|
values: { type: Object },
|
|
5
5
|
Field: { type: Object },
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
export function useFreeField(props) {
|
|
8
|
+
export function useFreeField(props, ctx) {
|
|
9
|
+
const { proxy:vm } = getCurrentInstance();
|
|
9
10
|
const fieldData = reactive({});
|
|
10
11
|
|
|
11
12
|
watchEffect(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// if (typeof this.Field.Options.Filters === 'string') {
|
|
61
|
-
// // only one filter
|
|
62
|
-
// filters.push(this.Field.Options.Filters);
|
|
63
|
-
// } else if (Array.isArray(this.Field.Options.Filters)) {
|
|
64
|
-
// filters = filters.concat(this.Field.Options.Filters);
|
|
65
|
-
// }
|
|
66
|
-
|
|
67
|
-
// for (let i = 0; i < filters.length; i += 1) {
|
|
68
|
-
// const f = filters[i];
|
|
69
|
-
// const filter = this.$options.filters[f];
|
|
70
|
-
// if (filter) {
|
|
71
|
-
// realData = filter(realData);
|
|
72
|
-
// }
|
|
73
|
-
// }
|
|
74
|
-
// }
|
|
75
|
-
// }
|
|
76
|
-
// }
|
|
77
|
-
|
|
78
|
-
// if ((typeof realData === 'undefined' || realData === null || !realData) && this.Field.Info && this.Field.Info.ShowNaN) {
|
|
79
|
-
// return this.ctx.config.nanPlaceholder || '';
|
|
80
|
-
// }
|
|
81
|
-
|
|
82
|
-
// return realData;
|
|
13
|
+
let realData = void 0;
|
|
14
|
+
|
|
15
|
+
if (!props.Field) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!props.Field.Name) {
|
|
20
|
+
realData = props.Field.Value || props.Field.Default || undefined;
|
|
21
|
+
} else {
|
|
22
|
+
if (props.Field.Info?.Dynamic && props.Field.Value) {
|
|
23
|
+
realData = props.Field.Value;
|
|
24
|
+
} else {
|
|
25
|
+
realData = Object.nestValue(props.values, props.Field?.Name);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// set to default if still undefined
|
|
30
|
+
if ((realData === void 0 || realData === null) && (props.Field.Value || props.Field.Default)) {
|
|
31
|
+
realData = props.Field.Value || props.Field.Default;
|
|
32
|
+
|
|
33
|
+
// for non-dynamic field, which have refer data, we should save this data into the field
|
|
34
|
+
if (props.Field.ReferTo && !props.Field.Info?.Dynamic) {
|
|
35
|
+
ctx.emit('input');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// filter data
|
|
40
|
+
if (props.Field.Options && props.Field.Options.Filters) {
|
|
41
|
+
let filters = [];
|
|
42
|
+
if (typeof props.Field.Options.Filters === 'string') {
|
|
43
|
+
// only one filter
|
|
44
|
+
filters.push(props.Field.Options.Filters);
|
|
45
|
+
} else if (Array.isArray(props.Field.Options.Filters)) {
|
|
46
|
+
filters = filters.concat(props.Field.Options.Filters);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < filters.length; i += 1) {
|
|
50
|
+
const f = filters[i];
|
|
51
|
+
realData = vm.$filter(f, realData)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// show NaN placeholder
|
|
56
|
+
if ((realData === void 0 || realData === null || realData === '') && props.Field?.Info?.ShowNaN) {
|
|
57
|
+
return vm.ctx.config.nanPlaceholder || '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fieldData.value = realData;
|
|
83
61
|
});
|
|
84
62
|
|
|
85
63
|
return {
|
package/i18n/en-us/index.js
CHANGED
|
@@ -67,4 +67,8 @@ export default {
|
|
|
67
67
|
validatorPwd3Description: "Passwords 6-16 characters in length, must contain numbers, uppercase letters, lowercase letters, special characters",
|
|
68
68
|
validatorPwd4Name: "Password (strength four)",
|
|
69
69
|
validatorPwd4Description: "A password of 6-16 digits in length must contain numbers, at least 2 uppercase letters, at least 2 lowercase letters, special characters",
|
|
70
|
-
|
|
70
|
+
|
|
71
|
+
删除确认: "Do you want to delete {type} '{name}'?",
|
|
72
|
+
菜单: 'menu',
|
|
73
|
+
字典项: 'dictionary',
|
|
74
|
+
}
|
package/i18n/zh-cn/index.js
CHANGED
|
@@ -1,73 +1,78 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
justNow: '刚刚',
|
|
3
|
+
secondsAgo: '秒之前',
|
|
4
|
+
minutesAgo: '分钟之前',
|
|
5
|
+
hoursAgo: '小时之前',
|
|
6
|
+
daysAgo: '天之前',
|
|
7
|
+
monthsAgo: '月之前',
|
|
8
|
+
yearsAgo: '年之前',
|
|
9
|
+
SwitchTheme: '切换样式',
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
validatorNotEmptyName: "非空",
|
|
12
|
+
validatorNotEmptyDescription: "不能为空",
|
|
13
|
+
validatorMobilePhoneName: "手机号",
|
|
14
|
+
validatorMobilePhoneDescription: "中国手机号码格式",
|
|
15
|
+
validatorEmailName: "邮箱",
|
|
16
|
+
validatorEmailDescription: "",
|
|
17
|
+
validatorPhoneOrEmailName: "手机号或邮箱",
|
|
18
|
+
validatorPhoneOrEmailDescription: "",
|
|
19
|
+
validatorChinaIDNumberName: "中国身份证号码",
|
|
20
|
+
validatorChinaIDNumberDescription: "",
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
22
|
+
validatorOnlyNumberName: "只能是数字",
|
|
23
|
+
validatorOnlyNumberDescription: "",
|
|
24
|
+
validatorOnlyCharName: "只能是字母",
|
|
25
|
+
validatorOnlyCharDescription: "",
|
|
26
|
+
validatorOnlyUpCharName: "只能是大写字母",
|
|
27
|
+
validatorOnlyUpCharDescription: "",
|
|
28
|
+
validatorOnlyLowerCharName: "只能是小写字母",
|
|
29
|
+
validatorOnlyLowerCharDescription: "",
|
|
30
|
+
validatorOnlyChineseName: "只能是中文",
|
|
31
|
+
validatorOnlyChineseDescription: "",
|
|
32
|
+
validatorOnlyCCName: "只能是中文或字母",
|
|
33
|
+
validatorOnlyCCDescription: "",
|
|
34
|
+
validatorOnlyCCNName: "只能是中文或字母或数字",
|
|
35
|
+
validatorOnlyCCNDescription: "",
|
|
36
|
+
validatorOnlyCNName: "只能是中文或数字",
|
|
37
|
+
validatorOnlyCNDescription: "",
|
|
38
|
+
validatorOnlyCNUName: "只能是中文或数字或下划线",
|
|
39
|
+
validatorOnlyCNUDescription: "",
|
|
40
|
+
validatorOnlyCNSName: "只能是中文或数字或特殊字符",
|
|
41
|
+
validatorOnlyCNSDescription:
|
|
42
|
+
`只能是中文或数字或("."、{'@'}、"<"、">"、"_"、"?")`,
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
validatorOnlyIntegerName: "只能是整数",
|
|
45
|
+
validatorOnlyIntegerDescription: "",
|
|
46
|
+
validatorOnlyPIName: "只能是正整数",
|
|
47
|
+
validatorOnlyPIDescription: "",
|
|
48
|
+
validatorOnlyPIZName: "只能是正整数或零",
|
|
49
|
+
validatorOnlyPIZDescription: "",
|
|
50
|
+
validatorOnlyNIName: "只能是负整数",
|
|
51
|
+
validatorOnlyNIDescription: "",
|
|
52
|
+
validatorOnlyNIZName: "只能是负整数或零",
|
|
53
|
+
validatorOnlyNIZDescription: "",
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
validatorUrlName: "URL地址",
|
|
56
|
+
validatorUrlDescription: "",
|
|
57
|
+
validatorOfficePhoneName: "固定电话号码",
|
|
58
|
+
validatorOfficePhoneDescription: "固定电话号码(区号-号码)",
|
|
59
|
+
validatorChinaZipName: "中国邮政编码",
|
|
60
|
+
validatorChinaZipDescription: "",
|
|
61
|
+
|
|
62
|
+
validatorPwd1Name: "密码(强度一)",
|
|
63
|
+
validatorPwd1Description: "长度在6-16位之间的任意密码",
|
|
64
|
+
validatorPwd2Name: "密码(强度二)",
|
|
65
|
+
validatorPwd2Description:
|
|
66
|
+
"长度在6-16位的密码,必须包含数字、大写字母、小写字母",
|
|
67
|
+
validatorPwd3Name: "密码(强度三)",
|
|
68
|
+
validatorPwd3Description:
|
|
69
|
+
"长度在6-16位的密码,必须包含数字、大写字母、小写字母、特殊字符",
|
|
70
|
+
validatorPwd4Name: "密码(强度四)",
|
|
71
|
+
validatorPwd4Description:
|
|
72
|
+
"长度在6-16位的密码,必须包含数字、至少2个大写字母、至少2个小写字母、特殊字符",
|
|
73
|
+
|
|
74
|
+
删除确认: "确认删除{type}'{name}'吗?",
|
|
75
|
+
菜单: '菜单',
|
|
76
|
+
字典项: '字典项',
|
|
61
77
|
|
|
62
|
-
validatorPwd1Name: "密码(强度一)",
|
|
63
|
-
validatorPwd1Description: "长度在6-16位之间的任意密码",
|
|
64
|
-
validatorPwd2Name: "密码(强度二)",
|
|
65
|
-
validatorPwd2Description:
|
|
66
|
-
"长度在6-16位的密码,必须包含数字、大写字母、小写字母",
|
|
67
|
-
validatorPwd3Name: "密码(强度三)",
|
|
68
|
-
validatorPwd3Description:
|
|
69
|
-
"长度在6-16位的密码,必须包含数字、大写字母、小写字母、特殊字符",
|
|
70
|
-
validatorPwd4Name: "密码(强度四)",
|
|
71
|
-
validatorPwd4Description:
|
|
72
|
-
"长度在6-16位的密码,必须包含数字、至少2个大写字母、至少2个小写字母、特殊字符",
|
|
73
78
|
}
|
package/index.js
CHANGED
|
@@ -152,6 +152,27 @@ const filters = {
|
|
|
152
152
|
diff = quasarDate.getDateDiff(date1, date2, 'years');
|
|
153
153
|
return diff + Vue.prototype.$t('yearsAgo');
|
|
154
154
|
},
|
|
155
|
+
stepCaption: (step, status, data) => {
|
|
156
|
+
if (!step) return '';
|
|
157
|
+
if (step && typeof step.Description === 'string') return step.Description;
|
|
158
|
+
|
|
159
|
+
let desc = '';
|
|
160
|
+
if (step && Array.isArray(step.Description)) {
|
|
161
|
+
let stepStatus;
|
|
162
|
+
if (data && data.Steps) {
|
|
163
|
+
const rStep = data.Steps[step.Index];
|
|
164
|
+
if (rStep) {
|
|
165
|
+
stepStatus = rStep.Status;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
desc = step.Description.find((s) => s.Status === (status || stepStatus || '').toString());
|
|
169
|
+
desc = desc ? desc.Description : '';
|
|
170
|
+
desc = desc;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
desc = desc || '未知状态';
|
|
174
|
+
return desc;
|
|
175
|
+
},
|
|
155
176
|
};
|
|
156
177
|
|
|
157
178
|
export default (app, root) => {
|
|
@@ -289,6 +310,7 @@ export default (app, root) => {
|
|
|
289
310
|
Name: "Enabled",
|
|
290
311
|
Label: "启用",
|
|
291
312
|
Type: "Boolean",
|
|
313
|
+
showLabel: true,
|
|
292
314
|
},
|
|
293
315
|
{
|
|
294
316
|
Name: "Description",
|
|
@@ -373,4 +395,4 @@ export default (app, root) => {
|
|
|
373
395
|
validatorPwd4: (d) => /^.*(?=.{6,16})(?=.*\d)(?=.*[A-Z]{2,})(?=.*[a-z]{2,})(?=.*[!@#$%^&*?\(\)]).*$/.test(d),
|
|
374
396
|
},
|
|
375
397
|
}
|
|
376
|
-
};
|
|
398
|
+
};
|
package/package.json
CHANGED
package/view/dict/index.vue
CHANGED
|
@@ -131,10 +131,6 @@ export default defineComponent({
|
|
|
131
131
|
|
|
132
132
|
const { validate } = useFormValidator('fieldsToValidate');
|
|
133
133
|
|
|
134
|
-
watch(() => data, () => {
|
|
135
|
-
console.log(data)
|
|
136
|
-
})
|
|
137
|
-
|
|
138
134
|
return {
|
|
139
135
|
data,
|
|
140
136
|
refreshData,
|
|
@@ -175,6 +171,26 @@ export default defineComponent({
|
|
|
175
171
|
}
|
|
176
172
|
},
|
|
177
173
|
methods: {
|
|
174
|
+
makeLabelsName(n) {
|
|
175
|
+
n.Labels = n.Labels || [];
|
|
176
|
+
// check labels according to the locales
|
|
177
|
+
const locales = this.ctx.config.locales || [];
|
|
178
|
+
for(let i = 0; i < locales.length; i += 1) {
|
|
179
|
+
const locale = locales[i];
|
|
180
|
+
const existsLabel = n.Labels.find((l) => l.Locale === locale.locale);
|
|
181
|
+
|
|
182
|
+
if (!existsLabel) {
|
|
183
|
+
n.Labels.push({
|
|
184
|
+
Label: '',
|
|
185
|
+
Locale: locale.locale,
|
|
186
|
+
Description: '',
|
|
187
|
+
Name: locale.name,
|
|
188
|
+
});
|
|
189
|
+
} else {
|
|
190
|
+
existsLabel.Name = locale.name;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
},
|
|
178
194
|
loadSubDicts({ key, done, node /* , fail */ }) {
|
|
179
195
|
this.GetData(key, node.level)
|
|
180
196
|
.then((d) => {
|
|
@@ -198,28 +214,13 @@ export default defineComponent({
|
|
|
198
214
|
Type: 'String',
|
|
199
215
|
};
|
|
200
216
|
}
|
|
217
|
+
|
|
218
|
+
this.makeLabelsName(this.editingDict);
|
|
201
219
|
},
|
|
202
220
|
editNode(n) {
|
|
203
221
|
if (!n) return;
|
|
204
222
|
|
|
205
|
-
|
|
206
|
-
// check labels according to the locales
|
|
207
|
-
const locales = this.ctx.config.locales || [];
|
|
208
|
-
for(let i = 0; i < locales.length; i += 1) {
|
|
209
|
-
const locale = locales[i];
|
|
210
|
-
const existsLabel = n.Labels.find((l) => l.Locale === locale.locale);
|
|
211
|
-
|
|
212
|
-
if (!existsLabel) {
|
|
213
|
-
n.Labels.push({
|
|
214
|
-
Label: '',
|
|
215
|
-
Locale: locale.locale,
|
|
216
|
-
Description: '',
|
|
217
|
-
Name: locale.name,
|
|
218
|
-
});
|
|
219
|
-
} else {
|
|
220
|
-
existsLabel.Name = locale.name;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
+
this.makeLabelsName(n);
|
|
223
224
|
|
|
224
225
|
if (this.selectedDictNode && this.selectedDictNode.id === n.id) {
|
|
225
226
|
this.selectedDictNode = {};
|
|
@@ -236,7 +237,7 @@ export default defineComponent({
|
|
|
236
237
|
|
|
237
238
|
this.$MsgDialog({
|
|
238
239
|
type: '',
|
|
239
|
-
content:
|
|
240
|
+
content: this.$t('删除确认', { type: this.$t('字典项'), name: n.Name }),
|
|
240
241
|
canCancel: true,
|
|
241
242
|
okText: this.$t('okButtonText'),
|
|
242
243
|
cancelText: this.$t('cancelButtonText'),
|
|
@@ -255,6 +256,11 @@ export default defineComponent({
|
|
|
255
256
|
|
|
256
257
|
if (!this.validate()) return;
|
|
257
258
|
|
|
259
|
+
// clear labels without label
|
|
260
|
+
this.editingDict.Labels = (this.editingDict.Labels || []).filter(
|
|
261
|
+
(l) => l.Label,
|
|
262
|
+
);
|
|
263
|
+
|
|
258
264
|
// if is adding new
|
|
259
265
|
if (this.selectedDictNode.addingNew) {
|
|
260
266
|
this.editingDict = {
|
|
@@ -264,10 +270,6 @@ export default defineComponent({
|
|
|
264
270
|
...this.editingDict,
|
|
265
271
|
};
|
|
266
272
|
|
|
267
|
-
// fix: the default content for number input will be string!!!!????
|
|
268
|
-
// convert to number
|
|
269
|
-
this.editingDict.Index = Number(this.editingDict.Index || '0');
|
|
270
|
-
|
|
271
273
|
this.addDict(this.editingDict).then((r) => {
|
|
272
274
|
if (r && r.msg === 'OK') {
|
|
273
275
|
const parent = this.$refs.dictTree.getNodeByKey(
|
package/view/error/list.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="flow-list">
|
|
3
|
-
<summary-head :values="data.summary"
|
|
3
|
+
<summary-head :values="data.summary"></summary-head>
|
|
4
4
|
<q-table
|
|
5
5
|
flat
|
|
6
6
|
bordered
|
|
@@ -23,26 +23,24 @@
|
|
|
23
23
|
<span v-else>
|
|
24
24
|
{{ valueFilters(col, col.value || Object.nestValue(props.row, col.field))}}
|
|
25
25
|
<q-popup-edit
|
|
26
|
+
v-slot="scope"
|
|
26
27
|
v-model="props.row.Message"
|
|
27
28
|
v-if="col.name === 'message'"
|
|
28
|
-
buttons
|
|
29
|
-
persistent
|
|
30
29
|
label-set="保存"
|
|
31
30
|
label-cancel="取消"
|
|
32
|
-
@save="messageChanged(props.row.id, props.row.Message)"
|
|
33
31
|
>
|
|
34
|
-
<q-input v-model="props.row.Message" hide-bottom-space autofocus
|
|
32
|
+
<q-input v-model="props.row.Message" hide-bottom-space autofocus
|
|
33
|
+
@keyup.enter="messageChanged(props.row.id, props.row.Message, scope)"/>
|
|
35
34
|
</q-popup-edit>
|
|
36
35
|
<q-popup-edit
|
|
37
|
-
v-
|
|
36
|
+
v-slot="scope"
|
|
37
|
+
:model-value="props.row.Description"
|
|
38
38
|
v-if="col.name === 'description'"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
label-set="保存"
|
|
42
|
-
label-cancel="取消"
|
|
43
|
-
@save="descriptionChanged(props.row.id, props.row.Description)"
|
|
39
|
+
:label-set="$t('保存')"
|
|
40
|
+
:label-cancel="$t('取消')"
|
|
44
41
|
>
|
|
45
|
-
<q-input v-model="props.row.Description" hide-bottom-space autofocus
|
|
42
|
+
<q-input v-model="props.row.Description" hide-bottom-space autofocus
|
|
43
|
+
@keyup.enter="descriptionChanged(props.row.id, props.row.Description, scope)"/>
|
|
46
44
|
</q-popup-edit>
|
|
47
45
|
</span>
|
|
48
46
|
</q-td>
|
|
@@ -66,7 +64,7 @@
|
|
|
66
64
|
|
|
67
65
|
<template v-slot:no-data>
|
|
68
66
|
<div class="full-width full-height row flex-center q-gutter-sm">
|
|
69
|
-
<span
|
|
67
|
+
<span>{{$t('暂无数据')}}</span>
|
|
70
68
|
</div>
|
|
71
69
|
</template>
|
|
72
70
|
|
|
@@ -106,7 +104,7 @@ export default defineComponent({
|
|
|
106
104
|
} = useObjectData(props, ctx);
|
|
107
105
|
|
|
108
106
|
return {
|
|
109
|
-
data,
|
|
107
|
+
data,
|
|
110
108
|
refreshData,
|
|
111
109
|
};
|
|
112
110
|
},
|
|
@@ -165,10 +163,7 @@ export default defineComponent({
|
|
|
165
163
|
|
|
166
164
|
for (let i = 0; i < filters.length; i += 1) {
|
|
167
165
|
const f = filters[i];
|
|
168
|
-
|
|
169
|
-
if (filter) {
|
|
170
|
-
val = filter(v || col.value);
|
|
171
|
-
}
|
|
166
|
+
val = this.$filter(f, v || col.value)
|
|
172
167
|
}
|
|
173
168
|
}
|
|
174
169
|
|
|
@@ -181,7 +176,8 @@ export default defineComponent({
|
|
|
181
176
|
paginationChanged(p) {
|
|
182
177
|
this.refreshData({ page: p });
|
|
183
178
|
},
|
|
184
|
-
messageChanged(id, msg) {
|
|
179
|
+
messageChanged(id, msg, popup) {
|
|
180
|
+
popup.set();
|
|
185
181
|
updateErrorCode(id, msg).then((d) => {
|
|
186
182
|
if (d && d.msg === 'OK') {
|
|
187
183
|
this.$q.notify(this.$t('notifySaved'));
|
|
@@ -190,7 +186,8 @@ export default defineComponent({
|
|
|
190
186
|
}
|
|
191
187
|
});
|
|
192
188
|
},
|
|
193
|
-
descriptionChanged(id, desc) {
|
|
189
|
+
descriptionChanged(id, desc, popup) {
|
|
190
|
+
popup.set();
|
|
194
191
|
updateDescription(id, desc).then((d) => {
|
|
195
192
|
if (d && d.msg === 'OK') {
|
|
196
193
|
this.$q.notify(this.$t('notifySaved'));
|
package/view/menu/index.vue
CHANGED
|
@@ -116,7 +116,7 @@ export default defineComponent({
|
|
|
116
116
|
selectedMenuNode,
|
|
117
117
|
editingMenu,
|
|
118
118
|
menuFields,
|
|
119
|
-
data,
|
|
119
|
+
data,
|
|
120
120
|
refreshData,
|
|
121
121
|
validate,
|
|
122
122
|
};
|
|
@@ -226,7 +226,7 @@ export default defineComponent({
|
|
|
226
226
|
|
|
227
227
|
this.$MsgDialog({
|
|
228
228
|
type: '',
|
|
229
|
-
content:
|
|
229
|
+
content: this.$t('删除确认', {type: this.$t('菜单'), name: n.Label}),
|
|
230
230
|
canCancel: true,
|
|
231
231
|
okText: this.$t('okButtonText'),
|
|
232
232
|
cancelText: this.$t('cancelButtonText'),
|