free-fe-core-modules 0.0.2 → 0.0.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.
Files changed (104) hide show
  1. package/components/Basic/EIcon.vue +2 -4
  2. package/components/Basic/LeveledMenus.vue +0 -5
  3. package/components/Basic/SummaryHead.vue +23 -3
  4. package/components/Dialog/BasicDialog.vue +2 -3
  5. package/components/SlidingCarousel/index.vue +13 -3
  6. package/components/SlidingNews/index.vue +13 -3
  7. package/components/ThemeSwitch/index.vue +7 -5
  8. package/composible/useObjectData.js +69 -0
  9. package/free-field/Fields/AgreementCheck.js +170 -0
  10. package/free-field/Fields/ApiCall.js +123 -0
  11. package/{field-components/Fields/Boolean.vue → free-field/Fields/Boolean.js} +40 -46
  12. package/free-field/Fields/Category.js +28 -0
  13. package/free-field/Fields/Check.js +106 -0
  14. package/free-field/Fields/Customize.js +87 -0
  15. package/free-field/Fields/Date.js +133 -0
  16. package/free-field/Fields/DateRange.js +226 -0
  17. package/free-field/Fields/DynamicList.js +565 -0
  18. package/{field-components → free-field}/Fields/FixedList.vue +78 -83
  19. package/free-field/Fields/InputFieldList.vue +324 -0
  20. package/{field-components → free-field}/Fields/Labels.vue +24 -15
  21. package/{field-components → free-field}/Fields/MixedTable.vue +53 -61
  22. package/free-field/Fields/Number.js +167 -0
  23. package/free-field/Fields/Password.js +81 -0
  24. package/{field-components → free-field}/Fields/Permission.vue +17 -13
  25. package/{field-components → free-field}/Fields/PermissionEditor.vue +62 -105
  26. package/{field-components → free-field}/Fields/QueryFilters.vue +65 -48
  27. package/{field-components → free-field}/Fields/RadioList.vue +36 -12
  28. package/{field-components → free-field}/Fields/Rich.vue +104 -114
  29. package/{field-components → free-field}/Fields/Search.vue +35 -26
  30. package/{field-components → free-field}/Fields/Select.vue +116 -87
  31. package/{field-components → free-field}/Fields/SelectionChain.vue +89 -67
  32. package/{field-components/Fields/Separator.vue → free-field/Fields/Separator.js} +11 -16
  33. package/{field-components → free-field}/Fields/SingleList.vue +27 -21
  34. package/free-field/Fields/Static.js +27 -0
  35. package/free-field/Fields/String.js +105 -0
  36. package/free-field/Fields/Text.js +80 -0
  37. package/{field-components → free-field}/Fields/Time.vue +59 -43
  38. package/{field-components → free-field}/Fields/TimeRange.vue +107 -92
  39. package/free-field/Fields/Year.js +137 -0
  40. package/{field-components → free-field}/Fields/YearRange.vue +63 -73
  41. package/{field-components → free-field}/Fields/index.js +28 -30
  42. package/free-field/composible/fieldWrapper.js +221 -0
  43. package/free-field/composible/freeFieldLabel.js +22 -0
  44. package/free-field/composible/readonlyContent.js +36 -0
  45. package/free-field/composible/useFileSizeUtils.js +52 -0
  46. package/free-field/composible/useFreeField.js +143 -0
  47. package/{field-components → free-field}/index.js +3 -3
  48. package/i18n/en-us/index.js +1 -1
  49. package/i18n/zh-cn/index.js +1 -1
  50. package/index.js +1 -4
  51. package/package.json +2 -2
  52. package/router/error/data.js +4 -1
  53. package/view/dict/index.vue +13 -2
  54. package/view/error/list.vue +22 -14
  55. package/view/menu/index.vue +19 -4
  56. package/view/system/index.vue +15 -2
  57. package/field-components/Fields/AgreementCheck.vue +0 -161
  58. package/field-components/Fields/ApiCall.vue +0 -139
  59. package/field-components/Fields/Category.vue +0 -33
  60. package/field-components/Fields/Check.vue +0 -131
  61. package/field-components/Fields/Customize.vue +0 -103
  62. package/field-components/Fields/Date.vue +0 -142
  63. package/field-components/Fields/DateRange.vue +0 -199
  64. package/field-components/Fields/DynamicList.vue +0 -575
  65. package/field-components/Fields/FieldEditor.vue +0 -379
  66. package/field-components/Fields/File.vue +0 -382
  67. package/field-components/Fields/FileList.vue +0 -405
  68. package/field-components/Fields/FileListCombined.vue +0 -142
  69. package/field-components/Fields/Image.vue +0 -328
  70. package/field-components/Fields/ImageList.vue +0 -285
  71. package/field-components/Fields/ImageListCombined.vue +0 -76
  72. package/field-components/Fields/InputFieldList.vue +0 -299
  73. package/field-components/Fields/Number.vue +0 -247
  74. package/field-components/Fields/Password.vue +0 -79
  75. package/field-components/Fields/Static.vue +0 -22
  76. package/field-components/Fields/String.vue +0 -185
  77. package/field-components/Fields/Text.vue +0 -89
  78. package/field-components/Fields/UltimateFile.vue +0 -100
  79. package/field-components/Fields/Year.vue +0 -124
  80. package/field-components/Fields/components/FieldTypeOptions.vue +0 -248
  81. package/field-components/components/FieldComponents.vue +0 -246
  82. package/free-fields/AutoHide.js +0 -66
  83. package/free-fields/CenterContent.js +0 -15
  84. package/free-fields/Draggable.js +0 -30
  85. package/free-fields/Droppable.js +0 -114
  86. package/free-fields/EditableString.js +0 -63
  87. package/free-fields/FieldCategory.js +0 -83
  88. package/free-fields/FieldTypeSelect.js +0 -94
  89. package/free-fields/fieldEditors/arrayEditor.js +0 -3
  90. package/free-fields/fieldEditors/boolEditor.js +0 -22
  91. package/free-fields/fieldEditors/dateEditor.js +0 -23
  92. package/free-fields/fieldEditors/datetimeEditor.js +0 -23
  93. package/free-fields/fieldEditors/index.js +0 -21
  94. package/free-fields/fieldEditors/jsonEditor.js +0 -371
  95. package/free-fields/fieldEditors/labeledField.js +0 -74
  96. package/free-fields/fieldEditors/numberEditor.js +0 -51
  97. package/free-fields/fieldEditors/objectEditor.js +0 -3
  98. package/free-fields/fieldEditors/selectEditor.js +0 -0
  99. package/free-fields/fieldEditors/stringEditor.js +0 -49
  100. package/free-fields/fieldEditors/textEditor.js +0 -50
  101. package/free-fields/fieldEditors/timeEditor.js +0 -23
  102. package/free-fields/index.js +0 -402
  103. /package/{field-components/Display → free-field/Layout}/index.js +0 -0
  104. /package/{field-components → free-field}/style.sass +0 -0
@@ -4,14 +4,12 @@
4
4
  v-if="isIcon"
5
5
  class="full-width full-height"
6
6
  :name="name"
7
- v-bind="$attrs"
8
7
  ></q-icon>
9
8
  <q-img
10
9
  v-else
11
10
  class="full-width full-height"
12
11
  style="display: block;"
13
12
  :src="imgPath"
14
- v-bind="$attrs"
15
13
  round
16
14
  >
17
15
  <slot></slot>
@@ -54,8 +52,8 @@ export default defineComponent({
54
52
  // TODO:默认使用二倍图?
55
53
  if (this.relative) return `images/${this.name}${this.defaultSize}.png`;
56
54
  return this.thumb
57
- ? this.$options.filters.serverThumb(this.name)
58
- : this.$options.filters.serverImage(this.name);
55
+ ? this.$filter('serverThumb', this.name)
56
+ : this.$filter('serverImage', this.name);
59
57
  },
60
58
  },
61
59
  });
@@ -85,8 +85,3 @@ export default defineComponent({
85
85
  });
86
86
  </script>
87
87
 
88
- <style lang="sass">
89
- .leveled-menu
90
- .simple-expand-icon
91
- display: none
92
- </style>
@@ -46,7 +46,7 @@
46
46
  <span class="text">{{ item.text }}</span>
47
47
  </q-btn>
48
48
  <span
49
- v-if="typeof item.number !== 'undefined'"
49
+ v-if="item.number !== void 0"
50
50
  :class="
51
51
  item.number && Number(item.number).toString() !== 'NaN'
52
52
  ? 'summary-head-number is-number highlight'
@@ -76,15 +76,35 @@
76
76
 
77
77
  <script>
78
78
  import { defineComponent } from 'vue';
79
- import mixins from 'free-fe-mixins';
79
+ import { useObjectData, objectDataProps } from '../../composible/useObjectData';
80
80
 
81
81
  export default defineComponent({
82
82
  name: 'SummaryHead',
83
- mixins: [mixins.ArrayDataMixin],
84
83
  props: {
84
+ ...objectDataProps,
85
85
  has_multiple_head: { type: Boolean, default: false },
86
+ values: {type: Object, default: () => ({})},
87
+ },
88
+ setup(props, ctx) {
89
+ const {
90
+ data,
91
+ refreshData,
92
+ } = useObjectData(props, ctx);
93
+
94
+ return {
95
+ data,
96
+ refreshData,
97
+ };
86
98
  },
87
99
  created() {
100
+ if (this.values) {
101
+ this.data = this.values;
102
+ }
103
+ },
104
+ watch: {
105
+ values(v) {
106
+ this.data = v || [];
107
+ },
88
108
  },
89
109
  methods: {
90
110
  filteredValue(item) {
@@ -100,14 +100,13 @@
100
100
  </template>
101
101
 
102
102
  <script>
103
- import mixins from 'free-fe-mixins';
104
103
  import { defineComponent } from 'vue';
105
- import FreeField from '../../field-components/components/FieldComponents.vue';
104
+ import FreeField from '../../free-field/composible/fieldWrapper';
106
105
  import EIcon from '../Basic/EIcon.vue';
107
106
 
108
107
  export default defineComponent({
109
108
  name: 'BasicDialog',
110
- mixins: [mixins.InputFieldValidator],
109
+ // mixins: [mixins.InputFieldValidator],
111
110
  emits: ['hide', 'ok', 'cancel'],
112
111
  props: {
113
112
  persistent: { type: Boolean, default: true },
@@ -6,7 +6,6 @@
6
6
  infinite
7
7
  :transition-prev="transitionPrev"
8
8
  :transition-next="transitionNext"
9
- v-bind="$attrs"
10
9
  :height="heightString"
11
10
  :autoplay="interval"
12
11
  :arrows="data && data.length > 0"
@@ -27,13 +26,13 @@
27
26
  </template>
28
27
 
29
28
  <script>
30
- import mixins from 'free-fe-mixins';
31
29
  import { defineComponent } from 'vue';
30
+ import { useObjectData, objectDataProps } from '../../composible/useObjectData';
32
31
 
33
32
  export default defineComponent({
34
33
  name: 'SlidingCarousel',
35
- mixins: [mixins.ArrayDataMixin],
36
34
  props: {
35
+ ...objectDataProps,
37
36
  interval: { type: Number, default: 3000 },
38
37
  height: { type: String, default: '220px' },
39
38
  width: { type: String, default: '100%' },
@@ -43,6 +42,17 @@ export default defineComponent({
43
42
  swipeable: { type: Boolean, default: true },
44
43
  thumbnails: { type: Boolean, default: true },
45
44
  },
45
+ setup(props, ctx) {
46
+ const {
47
+ data,
48
+ refreshData,
49
+ } = useObjectData(props, ctx);
50
+
51
+ return {
52
+ data,
53
+ refreshData,
54
+ };
55
+ },
46
56
  data() {
47
57
  return {
48
58
  slide: 0,
@@ -20,7 +20,6 @@
20
20
  :height="heightString"
21
21
  :autoplay="interval"
22
22
  :navigation="false"
23
- v-bind="$attrs"
24
23
  animated
25
24
  infinite
26
25
  padding
@@ -66,13 +65,13 @@
66
65
  </template>
67
66
 
68
67
  <script>
69
- import mixins from 'free-fe-mixins';
70
68
  import { defineComponent } from 'vue';
69
+ import { useObjectData, objectDataProps } from '../../composible/useObjectData';
71
70
 
72
71
  export default defineComponent({
73
72
  name: 'SlidingNews',
74
- mixins: [mixins.ArrayDataMixin],
75
73
  props: {
74
+ ...objectDataProps,
76
75
  interval: { type: Number, default: 3000 },
77
76
  height: { type: String, default: '40px' },
78
77
  width: { type: String, default: '100%' },
@@ -84,6 +83,17 @@ export default defineComponent({
84
83
  transitionPrev: { type: String, default: 'slide-up' },
85
84
  transitionNext: { type: String, default: 'slide-down' },
86
85
  },
86
+ setup(props, ctx) {
87
+ const {
88
+ data,
89
+ refreshData,
90
+ } = useObjectData(props, ctx);
91
+
92
+ return {
93
+ data,
94
+ refreshData,
95
+ };
96
+ },
87
97
  data() {
88
98
  return {
89
99
  visible: true,
@@ -58,15 +58,17 @@ export default defineComponent({
58
58
  watch: {
59
59
  theme(v) {
60
60
  if (v) {
61
- const appEle = document.getElementById('q-app');
61
+ const appEle = document.getElementById('free-app');
62
62
 
63
- let arr = appEle.className.split(' ');
63
+ let arr = appEle?.className.split(' ');
64
64
 
65
- arr = arr.filter(cl => !cl.startsWith('theme-'));
65
+ if (arr) {
66
+ arr = arr.filter(cl => !cl.startsWith('theme-'));
66
67
 
67
- arr.push(`theme-${v}`);
68
+ arr?.push(`theme-${v}`);
68
69
 
69
- appEle.className = arr.join(' ');
70
+ appEle.className = arr.join(' ');
71
+ }
70
72
 
71
73
  const appStore = useAppStore();
72
74
  appStore.SET_THEME(v);
@@ -0,0 +1,69 @@
1
+ import { ref, getCurrentInstance, watch, watchEffect, defineEmits } from "vue";
2
+
3
+ export const objectDataProps = {
4
+ GetData: Function,
5
+ Bus: Object,
6
+ modelValue: {},
7
+ autoGet: { type: Boolean, default: true },
8
+ };
9
+
10
+ export function useObjectData(props, ctx) {
11
+ const { proxy:vm } = getCurrentInstance();
12
+
13
+ const data = ref({});
14
+ const callsLeft = ref(100);
15
+
16
+ watch(data, (v) => {
17
+ ctx.emit('update:modelValue', v);
18
+ });
19
+
20
+ watch(() => props.modelValue, () => {
21
+ data.value = props.modelValue;
22
+ })
23
+
24
+ // call after refresh when all function got called
25
+ watchEffect(() => {
26
+ if (vm.afterRefresh && callsLeft.value <= 0) {
27
+ vm.afterRefresh(...args);
28
+ }
29
+ })
30
+
31
+ const refreshData = (...args) => {
32
+ // support multiple get data functions
33
+ const getDataList = [];
34
+ if (Array.isArray(props.GetData)) {
35
+ getDataList.push(...props.GetData);
36
+ } else {
37
+ getDataList.push(props.GetData);
38
+ }
39
+
40
+ callsLeft.value = getDataList.length;
41
+
42
+ for (let i = 0; i < getDataList.length; i += 1) {
43
+ const getData = getDataList[i];
44
+
45
+ if (typeof getData === 'function') {
46
+ Promise.resolve(getData(...args)).then((d) => {
47
+ Object.assign(data.value, d);
48
+ }).finally(() => {
49
+ callsLeft.value --;
50
+ });
51
+ } else {
52
+ Object.assign(data.value, getData);
53
+ callsLeft.value --;
54
+ }
55
+ }
56
+ };
57
+
58
+ if(props.modelValue) {
59
+ data.value = props.modelValue;
60
+ } else if (props.autoGet) {
61
+ refreshData();
62
+ }
63
+
64
+ return {
65
+ data,
66
+ refreshData,
67
+ }
68
+ };
69
+
@@ -0,0 +1,170 @@
1
+ import { defineComponent, h, ref, getCurrentInstance } from 'vue';
2
+ import { useFreeField, freeFieldProps } from '../composible/useFreeField';
3
+ import { QCheckbox } from 'quasar';
4
+
5
+ export default defineComponent({
6
+ name: 'InputFieldAgreementCheck',
7
+ fieldInfo: {
8
+ Category: 'Simple',
9
+ Label: '协议同意勾选框',
10
+ Value: 'AgreementCheck',
11
+ Extra: [
12
+ {
13
+ Type: 'Check',
14
+ Label: '居中显示',
15
+ Name: 'Options.Center',
16
+ },
17
+ ],
18
+ Description: '',
19
+ },
20
+ props: {
21
+ ...freeFieldProps,
22
+ },
23
+ emits: ['input'],
24
+ setup(props, { emit }){
25
+ if (!props.Field) return {};
26
+
27
+ const { proxy:vm } = getCurrentInstance();
28
+ const { fieldData, setFieldData } = useFreeField(props);
29
+ const hasError = ref(false);
30
+
31
+ const fieldTip = (tip) => {
32
+ if (!tip || !tip.Text) return '';
33
+ if (!tip.Links || !Array.isArray(tip.Links) || tip.Links.length <= 0) {
34
+ return [{ Text: tip.Text }];
35
+ }
36
+
37
+ // process tip with links
38
+ let linkPos = [];
39
+ tip.Links.forEach((tl) => {
40
+ if (!tl || !tl.Text || !tl.Link) return;
41
+
42
+ const start = tip.Text.indexOf(tl.Text);
43
+ if (start >= 0) {
44
+ linkPos.push({
45
+ start,
46
+ end: start + tl.Text.length,
47
+ Link: tl.Link,
48
+ File: tl.File,
49
+ });
50
+ }
51
+ });
52
+
53
+ const textSplit = [];
54
+ let start = 0;
55
+ linkPos = linkPos.sort((a, b) => a.start - b.start);
56
+ for (let i = 0; i < linkPos.length; i += 1) {
57
+ const lp = linkPos[i];
58
+
59
+ const beforeText = tip.Text.substr(start, lp.start - start);
60
+ if (beforeText) {
61
+ textSplit.push({ Text: beforeText });
62
+ }
63
+
64
+ textSplit.push({
65
+ Text: tip.Text.substr(lp.start, lp.end - lp.start),
66
+ Link: lp.File
67
+ ? vm.$filter('serverDocument', lp.File)
68
+ : lp.Link,
69
+ });
70
+
71
+ start += lp.end;
72
+ }
73
+
74
+ const afterText = tip.Text.substr(start);
75
+ if (afterText) {
76
+ textSplit.push({
77
+ Text: afterText,
78
+ });
79
+ }
80
+
81
+ if (textSplit.length > 0) return textSplit;
82
+
83
+ return [{ Text: tip.Text }];
84
+ };
85
+
86
+ const validate = () => {
87
+ if (props.Field.Required) {
88
+ hasError.value = typeof fieldData.value === 'undefined' || !fieldData.value;
89
+ return !hasError.value;
90
+ }
91
+
92
+ const rules = Array.isArray(typeof props.Field.Rules)
93
+ ? props.Field.Rules
94
+ : [props.Field.Rules];
95
+
96
+ let isValid = true;
97
+ for (let i = 0; i < rules.length; i += 1) {
98
+ const r = rules[i];
99
+
100
+ if (typeof r === 'function') {
101
+ isValid = isValid && r(fieldData.value);
102
+ }
103
+ }
104
+
105
+ hasError.value = !isValid;
106
+ return isValid;
107
+ };
108
+
109
+ const checkboxNode = () => h(QCheckbox, {
110
+ disable: props.Field?.ReadOnly,
111
+ label: props.Field?.showLabel ? '' : props.Field?.Label,
112
+
113
+ class: 'check',
114
+ style: props.Field.Info?.Style,
115
+
116
+ modelValue: fieldData.value,
117
+ 'onUpdate:modelValue': (v) => {
118
+ setFieldData(v, emit);
119
+ },
120
+ });
121
+
122
+ const tipsNode = () => h('div', {},[
123
+ h('span', {
124
+ class: 'input-field-tips-prefix'
125
+ }),
126
+ h('span',{
127
+ class: 'tips-list'
128
+ }, (props.Field.Tips || []).map((tip) => h('span', {
129
+ class:'input-field-tips-tip',
130
+ }, [
131
+ h('span', {
132
+ class: 'input-field-tips-tip-prefix'
133
+ }),
134
+ fieldTip(tip).map((t) => h('span', {}, [
135
+ t.Link ? h('span', {
136
+ class: 'tip-link'
137
+ },[
138
+ h('span', {class: 'tip-link-prefix'}),
139
+ h('a',{
140
+ href: t.Link,
141
+ },t.Text),
142
+ h('span', {class: 'tip-link-postfix'}),
143
+ ]) : h('span',{class: 'tip-text'}, t.Text),
144
+ ])),
145
+ h('span', {
146
+ class: 'input-field-tips-tip-postfix'
147
+ })
148
+ ]))),
149
+ h('span',{
150
+ class: 'input-field-tips-postfix'
151
+ })
152
+ ]);
153
+
154
+ return () => h('div', {
155
+ class: `input-field-agreement-check row items-center no-wrap\
156
+ ${props.Field.Options?.Center ? 'center full-width justify-center' : ''}`,
157
+ }, h('div',{
158
+ class: `row no-wrap items-center relative-position ${hasError.value ? 'input-field--error' : ''}`,
159
+ },[
160
+ props.Field.Options?.Center || h('span', { class: 'field-label-empty', }),
161
+ checkboxNode(),
162
+ tipsNode(),
163
+ hasError.value && h('div', {
164
+ class: 'input-field--error-tag',
165
+ }, h(QIcon,{
166
+ name: 'error',
167
+ }))
168
+ ]));
169
+ },
170
+ });
@@ -0,0 +1,123 @@
1
+ import { defineComponent, getCurrentInstance, h, ref, watchEffect } from 'vue';
2
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
+ import ReadonlyContent from '../composible/readonlyContent';
4
+
5
+ export default defineComponent({
6
+ name: 'InputFieldApiCall',
7
+ fieldInfo: {
8
+ Category: 'Advanced',
9
+ Label: '特定接口处理',
10
+ Value: 'ApiCall',
11
+ Extra: [
12
+ {
13
+ Type: 'String',
14
+ Label: '数据获取地址',
15
+ Name: 'Options.Url',
16
+ },
17
+ {
18
+ Type: 'Select',
19
+ Label: '调用方法',
20
+ Name: 'Options.Method',
21
+ Options: [
22
+ 'get',
23
+ 'post',
24
+ 'put',
25
+ 'delete',
26
+ 'patch',
27
+ ],
28
+ },
29
+ {
30
+ Type: 'String',
31
+ Label: '传送字段名',
32
+ Name: 'Options.Fields',
33
+ Placeholder: '逗号分割',
34
+ Tips: [
35
+ {
36
+ Text: '默认将传送当前字段数据,但可以指定相同数据层级下的其他字段。',
37
+ },
38
+ ],
39
+ },
40
+ {
41
+ Type: 'String',
42
+ Label: '附加字段名',
43
+ Name: 'Options.ExtraFieldNames',
44
+ Placeholder: '逗号分割',
45
+ Tips: [
46
+ {
47
+ Text: '如果接口返回值中有这些字段,他们将会被赋予当前父数据中。',
48
+ },
49
+ ],
50
+ },
51
+ ],
52
+ Description: '',
53
+ },
54
+ props: {
55
+ ...freeFieldProps,
56
+ },
57
+ methods: {
58
+ ...useFreeFieldMethods,
59
+ },
60
+ setup(props, { slots }){
61
+ if (!props.Field) return {};
62
+
63
+ const { proxy:vm } = getCurrentInstance();
64
+ const { fieldData } = useFreeField(props);
65
+
66
+ const callResult = ref('');
67
+
68
+ const apiCall = () => {
69
+ let Fields = props.Field.Options.Fields || props.Field.Name;
70
+
71
+ if (!props.Field.Options || !props.Field.Options.Fields) {
72
+ return;
73
+ }
74
+
75
+ const paramObj = {};
76
+ if (Fields.length > 0) {
77
+ if (typeof Fields === 'string') {
78
+ Fields = Fields.split(',');
79
+ }
80
+ for (let i = 0; i < Fields.length; i += 1) {
81
+ const fld = Fields[i];
82
+
83
+ if (fld) {
84
+ Object.setValue(paramObj, fld, Object.nestValue(fieldData.value, fld));
85
+ }
86
+ }
87
+ } else {
88
+ Object.setValue(paramObj, props.Field.Name, fieldData.value);
89
+ }
90
+
91
+ vm[`${props.Field.Options.Method || 'post'}Request`](props.Field.Options.Url, paramObj).then((d) => {
92
+ if (d && d.msg === 'OK') {
93
+ if (d.data && d.data.value) {
94
+ callResult.value = JSON.stringify(d.data.value);
95
+ } else {
96
+ callResult.value = JSON.stringify(d.data);
97
+ }
98
+
99
+ // other extra new fields
100
+ (props.Field.Options.ExtraFieldNames || '').split(',').forEach((fname) => {
101
+ Object.setValue(props.values, fname, d.data[fname]);
102
+ });
103
+ }
104
+ });
105
+ };
106
+
107
+ watchEffect(() => {
108
+ fieldData.value && apiCall();
109
+ })
110
+
111
+ const readonlyNode = () => h(ReadonlyContent, {
112
+ Field: props.Field,
113
+ Content: callResult.value,
114
+ });
115
+
116
+ return () => h('div', {
117
+ class: 'simple-field input-field-apicall row items-center no-wrap',
118
+ }, [
119
+ readonlyNode(),
120
+ slots.warning && slots.warning(),
121
+ ]);
122
+ },
123
+ });
@@ -1,41 +1,10 @@
1
- <template>
2
- <span class="simple-field input-field-boolean row items-center no-wrap">
3
- <span
4
- :class="`field-label ${(Field.Label && Field.Label.trim().length)
5
- ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
6
- v-if="Field.showLabel && !Field.dense && typeof Field.Label !== 'undefined'"
7
- >
8
- <q-tooltip
9
- v-if="Field.Description"
10
- anchor="top right"
11
- >{{Field.Description}}</q-tooltip>
12
- {{Field.Label || ''}}
13
- <span
14
- v-if="Field.Required"
15
- class="required-mark"
16
- >*</span>
17
- </span>
18
- <span v-else-if="!Field.showLabel && !Field.dense" class="field-label-empty"></span>
19
-
20
- <q-toggle
21
- v-model="fieldData"
22
- :label="!Field.showLabel ? Field.Label : ''"
23
- @input="$emit('input')"
24
- :disable="Field.ReadOnly"
25
- v-bind="$attrs">
26
- <q-tooltip v-if="Field.Description">{{Field.Description}}</q-tooltip>
27
- </q-toggle>
28
- <slot name="warning"></slot>
29
- </span>
30
- </template>
31
-
32
- <script>
33
- import { defineComponent } from 'vue';
34
- import mixins from 'free-fe-mixins';
1
+ import { defineComponent, h, ref } from 'vue';
2
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
+ import { QToggle } from 'quasar';
4
+ import freeFieldLabel from '../composible/freeFieldLabel';
35
5
 
36
6
  export default defineComponent({
37
7
  name: 'InputFieldBoolean',
38
- mixins: [mixins.InputFieldMixin],
39
8
  fieldInfo: {
40
9
  Category: 'Simple',
41
10
  Label: '开关',
@@ -96,17 +65,42 @@ export default defineComponent({
96
65
  ],
97
66
  Description: '',
98
67
  },
99
- watch: {
100
- fieldData() {
101
- if (!this.fieldData) {
102
- this.fieldData = false;
103
- }
104
- },
68
+ props: {
69
+ ...freeFieldProps,
70
+ },
71
+ emits: ['input'],
72
+ methods: {
73
+ ...useFreeFieldMethods,
105
74
  },
106
- created() {
107
- if (!this.fieldData) {
108
- this.fieldData = false;
109
- }
75
+ setup(props, { emit, slots }){
76
+ if (!props.Field) return {};
77
+
78
+ const { fieldData, setFieldData } = useFreeField(props);
79
+
80
+ const before = (props.Field.showLabel && !props.Field.dense && props.Field.Label !== void 0) ? () => h(freeFieldLabel, {
81
+ Field: props.Field,
82
+ }) : () => h('div', {
83
+ class: 'field-label-empty'
84
+ });
85
+
86
+ const toggleNode = () => h(QToggle, {
87
+ disable: props.Field?.ReadOnly,
88
+ label: props.Field?.showLabel ? props.Field?.Lable : '',
89
+
90
+ style: props.Field.Info?.Style,
91
+
92
+ modelValue: fieldData.value,
93
+ 'onUpdate:modelValue': (v) => {
94
+ setFieldData(v, emit);
95
+ },
96
+ })
97
+
98
+ return () => h('div', {
99
+ class: 'simple-field input-field-boolean row items-center no-wrap',
100
+ }, [
101
+ before(),
102
+ toggleNode(),
103
+ slots.warning && slots.warning(),
104
+ ]);
110
105
  },
111
106
  });
112
- </script>
@@ -0,0 +1,28 @@
1
+ import { defineComponent, h } from 'vue';
2
+
3
+ export default defineComponent({
4
+ name: 'InputFieldCategory',
5
+ fieldInfo: {
6
+ Category: 'Static',
7
+ Label: '字段分类',
8
+ Value: 'Category',
9
+ Description: '',
10
+ },
11
+ props: {
12
+ Field: { type: Object },
13
+ },
14
+ methods: {
15
+ },
16
+ setup(props, { slots }){
17
+ if (!props.Field || (typeof props.Field.Label === 'undefined')) return;
18
+
19
+ return () => h('div', {
20
+ class: 'simple-field input-field-category row items-center no-wrap',
21
+ }, [
22
+ h('span', {
23
+ class: 'label'
24
+ }, props.Field.Label),
25
+ slots.warning && slots.warning(),
26
+ ]);
27
+ },
28
+ });