free-fe-core-modules 0.0.44 → 0.0.46

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.
@@ -3,7 +3,7 @@
3
3
  <div
4
4
  v-for="(item, i) in data"
5
5
  :key="i"
6
- :class="
6
+ :class="(item.classes ? (item.classes + ' ') : '') +
7
7
  (item.is_count ? 'summary-head-count ' : '') +
8
8
  (item.is_title
9
9
  ? 'summary-head-title summary-head-item'
@@ -192,13 +192,12 @@
192
192
  >
193
193
  </q-img>
194
194
 
195
- <q-pdfviewer
195
+ <pdf-viewer
196
196
  v-if="previewType === 'pdf'"
197
197
  v-model="showPreview"
198
198
  @click="showPreview=false"
199
- @error="pdfError"
200
- @load="pdfLoad"
201
199
  :src="previewFile"
200
+ :version="Field?.Options?.PdfViewerVersion"
202
201
  type="pdfjs"
203
202
  style="height: 100%; max-width: 100%;"
204
203
  />
@@ -212,6 +211,7 @@ import { computed, defineComponent, getCurrentInstance, ref } from 'vue';
212
211
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
213
212
  import { useFormValidator} from '../../composible/useFormValidator';
214
213
  import { useUploader } from '../composible/useUploader';
214
+ import PdfViewer from './pdfviewer';
215
215
 
216
216
  export default defineComponent({
217
217
  name: 'InputFieldFile',
@@ -247,9 +247,18 @@ export default defineComponent({
247
247
  Name: 'Options.AsLink',
248
248
  Default: false,
249
249
  },
250
+ {
251
+ Type: 'String',
252
+ Label: 'PDF查看器版本',
253
+ Name: 'Options.PdfViewerVersion',
254
+ Default: '',
255
+ },
250
256
  ],
251
257
  Description: '',
252
258
  },
259
+ components: {
260
+ PdfViewer,
261
+ },
253
262
  emits: ['input'],
254
263
  setup(props, { expose, emit }) {
255
264
  const { proxy:vm } = getCurrentInstance();
@@ -215,11 +215,12 @@
215
215
  >
216
216
  </q-img>
217
217
 
218
- <q-pdfviewer
218
+ <pdf-viewer
219
219
  v-if="previewType === 'pdf'"
220
220
  v-model="showPreview"
221
221
  @click="showPreview=false"
222
222
  :src="previewFile"
223
+ :version="Field?.Options?.PdfViewerVersion"
223
224
  type="pdfjs"
224
225
  style="height: 100%; max-width: 100%;"
225
226
  />
@@ -233,6 +234,7 @@ import { computed, defineComponent, getCurrentInstance, ref } from 'vue';
233
234
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
234
235
  import { useFormValidator} from '../../composible/useFormValidator';
235
236
  import { useUploader } from '../composible/useUploader';
237
+ import PdfViewer from './pdfviewer';
236
238
 
237
239
  export default defineComponent({
238
240
  name: 'InputFieldFileList',
@@ -286,9 +288,18 @@ export default defineComponent({
286
288
  Name: 'Options.AsLink',
287
289
  Default: false,
288
290
  },
291
+ {
292
+ Type: 'String',
293
+ Label: 'PDF查看器版本',
294
+ Name: 'Options.PdfViewerVersion',
295
+ Default: '',
296
+ },
289
297
  ],
290
298
  Description: '',
291
299
  },
300
+ components: {
301
+ PdfViewer,
302
+ },
292
303
  props: {
293
304
  ...freeFieldProps,
294
305
  },
@@ -33,6 +33,7 @@
33
33
  api-key="wh7g3etkwrso25e0wcpqrx8uvoa51toag3j92mllkajtg1xb"
34
34
  tinymce-script-src="tiny/tiny7.js"
35
35
  :init="{
36
+ placeholder: Field.Placeholder || '',
36
37
  language_url: 'tiny/langs/zh_cn.js',
37
38
  language: 'zh_cn',
38
39
  plugins: Field.ReadOnly ? [] : this.plugins,
@@ -49,7 +50,7 @@
49
50
  setup: tinySetup,
50
51
  default_link_target: (Field && Field.Options && Field.Options.LinkTarget) || '_blank',
51
52
 
52
- automatic_uploads: true,
53
+ automatic_uploads: (Field && Field.Options && Field.Options.NoUpload) ? false : true,
53
54
  images_upload_url: '/api/upload',
54
55
  images_reuse_filename: true,
55
56
  images_upload_handler,
@@ -114,6 +115,12 @@ export default defineComponent({
114
115
  },
115
116
  ],
116
117
  },
118
+ {
119
+ Type: 'Boolean',
120
+ Name: 'Options.NoUpload',
121
+ Label: '禁止上传',
122
+ Default: false,
123
+ },
117
124
  ],
118
125
  },
119
126
  components: {
@@ -298,43 +305,25 @@ export default defineComponent({
298
305
  }
299
306
 
300
307
  if (props.Field.Options?.MaxLength) {
301
- editor.on('keydown', (e) => {
302
- const allowedKeys = [8, 37, 38, 39, 40, 46];
303
- if (allowedKeys.indexOf(e.keyCode) >= 0) return true;
308
+ editor.on('input', () => {
309
+ const ctLen = editor.plugins.wordcount.body.getWordCount();
304
310
 
305
- const selectedText = editor.selection.getContent({
306
- format: 'text',
307
- });
308
-
309
- if (selectedText.length <= 0
310
- && editor.getContent({ format: 'text' }).length >= props.Field.Options.MaxLength) {
311
- e.preventDefault();
312
- e.stopPropagation();
313
- return false;
311
+ if (ctLen > props.Field.Options.MaxLength) {
312
+ // 如果超过了限制,则撤销最后的更改
313
+ // TODO: 撤销不是最好的处理方式,应该是从最后输入的内容开始删除
314
+ editor.undoManager.undo();
314
315
  }
315
-
316
- return true;
317
316
  });
318
317
  }
319
318
  if (props.Field.Options?.MaxSize) {
320
319
  const maxSize = fileSizeStrToNumber(props.Field.Options.MaxSize);
321
320
 
322
- editor.on('keydown', (e) => {
323
- const allowedKeys = [8, 37, 38, 39, 40, 46];
324
- if (allowedKeys.indexOf(e.keyCode) >= 0) return true;
325
-
326
- const selectedText = editor.selection.getContent({
327
- format: 'text',
328
- });
329
-
330
- if (selectedText.length <= 0
331
- && editor.getContent({ format: 'html' }).length >= maxSize) {
332
- e.preventDefault();
333
- e.stopPropagation();
334
- return false;
321
+ editor.on('input', () => {
322
+ if (editor.getContent({ format: 'html' }).length > maxSize) {
323
+ // 如果超过了限制,则撤销最后的更改
324
+ // TODO: 撤销不是最好的处理方式,应该是从最后输入的内容开始删除
325
+ editor.undoManager.undo();
335
326
  }
336
-
337
- return true;
338
327
  });
339
328
  }
340
329
  };
@@ -17,8 +17,8 @@
17
17
  <q-tooltip
18
18
  v-if="Field.Description"
19
19
  anchor="top right"
20
- >{{Field.Description}}</q-tooltip>
21
- {{Field.Label || ''}}
20
+ >{{$t(Field.Description)}}</q-tooltip>
21
+ {{$t(Field.Label) || ''}}
22
22
  <span
23
23
  v-if="Field.Required"
24
24
  class="required-mark"
@@ -27,17 +27,22 @@
27
27
  <span class="readonly-content">
28
28
  <span
29
29
  class="prefix"
30
- v-if="Field.Options && Field.Options.Prefix"
30
+ v-if="Field.Info && Field.Info.Prefix"
31
31
  >
32
- {{Field.Options.Prefix}}
32
+ {{Field.Info.Prefix}}
33
33
  </span>
34
- <span :style="(Field.Info && Field.Info.Style) ? Field.Info.Style : ''">
34
+ <div v-if="Field.Info && Field.Info.Chip">
35
+ <q-chip v-bind="Field.Info.ChipOptions || {}" v-for="(opt, idx) in readonlyContent || []" :key="idx">
36
+ {{opt}}
37
+ </q-chip>
38
+ </div>
39
+ <span v-else :style="(Field.Info && Field.Info.Style) ? Field.Info.Style : ''">
35
40
  {{readonlyContent}}
36
41
  </span>
37
42
  <span
38
43
  class="postfix"
39
- v-if="Field.Options && Field.Options.Postfix"
40
- >{{Field.Options.Postfix}}</span>
44
+ v-if="Field.Info && Field.Info.Postfix"
45
+ >{{Field.OptiInfons.Postfix}}</span>
41
46
  </span>
42
47
  </span>
43
48
 
@@ -51,8 +56,8 @@
51
56
  option-value="Value"
52
57
  option-label="Label"
53
58
  map-options
54
- :label="Field.Placeholder"
55
59
  emit-value
60
+ :label="Field.Placeholder || $t(getModule('core-modules').config['defaultSelectFieldPlaceholder'])"
56
61
  :multiple="Field.Multiple"
57
62
  :readonly="Field.ReadOnly"
58
63
  ref="fieldToValid"
@@ -61,7 +66,6 @@
61
66
  :use-chips="Field && (Field.UseChip || (Field.Info && Field.Info.Chip))"
62
67
  v-bind="inputControlSettings"
63
68
  :rules="Field.Rules"
64
-
65
69
  :new-value-mode="Field?.NewValueMode ? 'add' : undefined"
66
70
  >
67
71
  <template v-slot:before>
@@ -73,8 +77,8 @@
73
77
  <q-tooltip
74
78
  v-if="Field.Description"
75
79
  anchor="top right"
76
- >{{Field.Description}}</q-tooltip>
77
- {{Field.Label || ''}}
80
+ >{{$t(Field.Description)}}</q-tooltip>
81
+ {{$t(Field.Label) || ''}}
78
82
  <span
79
83
  v-if="Field.Required"
80
84
  class="required-mark"
@@ -85,6 +89,7 @@
85
89
  <template v-slot:option="scope">
86
90
  <q-item
87
91
  v-bind="scope.itemProps"
92
+ v-on="scope.itemEvents"
88
93
  >
89
94
  <q-item-section
90
95
  avatar
@@ -94,7 +99,7 @@
94
99
  </q-item-section>
95
100
 
96
101
  <q-item-section>
97
- <q-item-label>{{ scope.opt.Label }}</q-item-label>
102
+ <q-item-label v-html="scope.opt.Label" />
98
103
  <q-tooltip v-if="scope.opt.Tooltip">
99
104
  {{scope.opt.Tooltip}}
100
105
  </q-tooltip>
@@ -119,8 +124,8 @@
119
124
  <q-tooltip
120
125
  v-if="Field.Description"
121
126
  anchor="top right"
122
- >{{Field.Description}}</q-tooltip>
123
- {{Field.Label || ''}}
127
+ >{{$t(Field.Description)}}</q-tooltip>
128
+ {{$t(Field.Label) || ''}}
124
129
  <span
125
130
  v-if="Field.Required"
126
131
  class="required-mark"
@@ -144,14 +149,30 @@
144
149
 
145
150
  <q-checkbox
146
151
  v-for="(option, index) in Field.Options"
152
+ :class="{
153
+ checked: checked.includes(option.Value),
154
+ 'with-inner-extra': option.InnerExtra?.length,
155
+ }"
147
156
  :key="index"
148
157
  hide-bottom-space
149
158
  :label="option.Label || ''"
150
159
  v-model="checked"
151
160
  :val="option.Value"
152
161
  :disable="Field.ReadOnly"
153
- @update:modelValue="checkChanged(option.Value)"
154
- ></q-checkbox>
162
+ @input="checkChanged(option.Value)"
163
+ :checked-icon="checkedIcon(option)"
164
+ >
165
+ <q-tooltip v-if="option.opt?.Tooltip"
166
+ anchor="bottom middle">
167
+ {{$t(option.opt.Tooltip) || ''}}
168
+ </q-tooltip>
169
+ <div class="option-inner-extra" v-if="option.InnerExtra?.length">
170
+ <input-field
171
+ v-for="(fld, idx) in option.InnerExtra || []" :key="idx"
172
+ :Field="fld"
173
+ :values="data"></input-field>
174
+ </div>
175
+ </q-checkbox>
155
176
  </div>
156
177
  </span>
157
178
  </span>
@@ -163,6 +184,13 @@ import { ref, computed, defineComponent, getCurrentInstance, watchEffect } from
163
184
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
164
185
  import { useFormValidator} from '../../composible/useFormValidator';
165
186
 
187
+ const NUM_ICONS = [
188
+ '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩',
189
+ '⑪', '⑫', '⑬', '⑭', '⑮','⑯','⑰','⑱','⑲','⑳',
190
+ '㉑','㉒','㉓','㉔','㉕','㉖','㉗','㉘','㉙','㉚',
191
+ '㉛','㉜','㉝','㉞','㉟','㊱','㊲','㊳','㊴','㊵',
192
+ '㊶','㊷','㊸','㊹','㊺','㊻','㊼','㊽','㊾','㊿'];
193
+
166
194
  export default defineComponent({
167
195
  name: 'InputFieldSelect',
168
196
  props: {
@@ -175,6 +203,16 @@ export default defineComponent({
175
203
  Value: 'Select',
176
204
  Description: '',
177
205
  Extra: [
206
+ {
207
+ Type: 'String',
208
+ Label: '前缀',
209
+ Name: 'Info.Prefix',
210
+ },
211
+ {
212
+ Type: 'String',
213
+ Label: '后缀',
214
+ Name: 'Info.Postfix',
215
+ },
178
216
  {
179
217
  Type: 'Check',
180
218
  Label: '展开单选',
@@ -190,6 +228,11 @@ export default defineComponent({
190
228
  Label: '可多选',
191
229
  Name: 'Multiple',
192
230
  },
231
+ {
232
+ Type: 'Check',
233
+ Label: '显示为顺序号',
234
+ Name: 'Info.AsOrderNumber',
235
+ },
193
236
  {
194
237
  Type: 'Check',
195
238
  Label: '显示为碎屑',
@@ -211,6 +254,12 @@ export default defineComponent({
211
254
  Label: '获取选项的参数字段',
212
255
  Placeholder: '逗号分割多个参数字段名',
213
256
  },
257
+ {
258
+ Type: 'String',
259
+ Name: 'Info.TriggerTo',
260
+ Label: '选择后激活字段',
261
+ Placeholder: '逗号分割多个参数字段名',
262
+ },
214
263
  {
215
264
  Type: 'DynamicList',
216
265
  Label: '选项',
@@ -225,6 +274,10 @@ export default defineComponent({
225
274
  Label: 'Value',
226
275
  Name: 'Value',
227
276
  },
277
+ {
278
+ Label: 'Tooltip',
279
+ Name: 'opt.Tooltip',
280
+ },
228
281
  {
229
282
  Label: 'Extra',
230
283
  Name: 'Extra',
@@ -251,6 +304,32 @@ export default defineComponent({
251
304
  ],
252
305
  },
253
306
  },
307
+ {
308
+ Label: 'InnerExtra',
309
+ Name: 'InnerExtra',
310
+ Type: 'FieldList',
311
+ Options: {
312
+ Columns: [
313
+ {
314
+ Label: '#',
315
+ Name: 'Index',
316
+ sortable: true,
317
+ },
318
+ {
319
+ Label: '名称',
320
+ Name: 'Name',
321
+ style: 'max-width: 200px;',
322
+ sortable: true,
323
+ },
324
+ {
325
+ Label: '标题',
326
+ Name: 'Label',
327
+ style: 'max-width: 200px;',
328
+ sortable: true,
329
+ },
330
+ ],
331
+ },
332
+ },
254
333
  ],
255
334
  },
256
335
  },
@@ -299,6 +378,25 @@ export default defineComponent({
299
378
  return fieldData.value;
300
379
  });
301
380
 
381
+ const checkedIcon = computed(() => {
382
+ // only when ascheck and multiple and as order number
383
+ if (props.Field?.AsCheck && props.Field?.Multiple && props.Field?.Info?.AsOrderNumber) {
384
+ return (opt) => {
385
+ if (!opt?.Value) return undefined;
386
+
387
+ const idx = (checked.value || []).findIndex((v) => v === opt.Value);
388
+
389
+ if (idx >= 0 && idx < NUM_ICONS.length) {
390
+ return NUM_ICONS[idx];
391
+ }
392
+
393
+ return undefined;
394
+ };
395
+ }
396
+
397
+ return () => undefined;
398
+ });
399
+
302
400
 
303
401
  watchEffect(() => {
304
402
  if (props.Field.AsCheck) {
@@ -407,6 +505,7 @@ export default defineComponent({
407
505
  selectOptions,
408
506
 
409
507
  readonlyContent,
508
+ checkedIcon,
410
509
 
411
510
  selectChanged,
412
511
  checkChanged,
@@ -0,0 +1,120 @@
1
+ import ModelToggleMixin from 'quasar/src/mixins/model-toggle.js';
2
+
3
+ export default {
4
+ name: 'QPdfviewer',
5
+
6
+ mixins: [ModelToggleMixin],
7
+
8
+ props: {
9
+ version: { type: String, default: '' },
10
+ src: String,
11
+ type: {
12
+ type: String,
13
+ default: 'html5',
14
+ validator: (v) => ['html5', 'pdfjs'].indexOf(v) !== -1,
15
+ },
16
+ errorString: {
17
+ type: String,
18
+ default:
19
+ 'This browser does not support PDFs. Download the PDF to view it:',
20
+ },
21
+ contentStyle: [String, Object, Array],
22
+ contentClass: [String, Object, Array],
23
+ innerContentStyle: [String, Object, Array],
24
+ innerContentClass: [String, Object, Array],
25
+ },
26
+
27
+ data() {
28
+ return {
29
+ hashId: `q-pdfviewer-${Math.random()
30
+ .toString(36)
31
+ .substring(2, 9)}`,
32
+ height: '1200',
33
+ };
34
+ },
35
+ mounted() {
36
+ window.addEventListener('message', (event) => {
37
+ this.height = event.data;
38
+ });
39
+ },
40
+ methods: {
41
+ // eslint-disable-next-line no-underscore-dangle
42
+ __renderObject(h) {
43
+ return h(
44
+ 'object',
45
+ {
46
+ class: this.innerContentClass,
47
+ style: this.innerContentStyle,
48
+ attrs: {
49
+ id: this.hashId,
50
+ data: this.src,
51
+ type: 'application/pdf',
52
+ width: '100%',
53
+ height: '100%',
54
+ },
55
+ on: {
56
+ ...this.$listeners,
57
+ },
58
+ },
59
+ [
60
+ // browser object not supported, try iframe
61
+ // eslint-disable-next-line no-underscore-dangle
62
+ this.__renderIFrame(h),
63
+ ],
64
+ );
65
+ },
66
+
67
+ // eslint-disable-next-line no-underscore-dangle
68
+ __renderIFrame(h) {
69
+ return h(
70
+ 'iframe',
71
+ {
72
+ staticClass: 'q-pdfviewer__iframe',
73
+ attrs: {
74
+ src: this.src,
75
+ width: '100%',
76
+ height: '100%',
77
+ },
78
+ },
79
+ );
80
+ },
81
+
82
+ // eslint-disable-next-line no-underscore-dangle
83
+ __renderIFramePDFJS(h) {
84
+ return h(
85
+ 'iframe',
86
+ {
87
+ staticClass: 'q-pdfviewer__iframe',
88
+ attrs: {
89
+ src: `pdfjs${this.version ? `_${this.version}` : ''}/web/viewer.html?file=${encodeURIComponent(this.src)}`,
90
+ width: '100%',
91
+ height: '100%',
92
+ },
93
+ },
94
+ );
95
+ },
96
+ },
97
+
98
+ render(h) {
99
+ if (this.value === true && this.src !== undefined && this.src.length > 0) {
100
+ return h(
101
+ 'div',
102
+ {
103
+ staticClass: 'q-pdfviewer',
104
+ class: this.contentClass,
105
+ style: this.contentStyle,
106
+ attrs: {
107
+ },
108
+ },
109
+ [
110
+ this.$q.platform.is.electron || this.type === 'pdfjs'
111
+ // eslint-disable-next-line no-underscore-dangle
112
+ ? this.__renderIFramePDFJS(h)
113
+ // eslint-disable-next-line no-underscore-dangle
114
+ : this.__renderObject(h),
115
+ ],
116
+ );
117
+ }
118
+ return '';
119
+ },
120
+ };
@@ -30,7 +30,8 @@ export default defineComponent({
30
30
  const { proxy: vm } = getCurrentInstance();
31
31
 
32
32
  const localField = computed(() => {
33
- const lField = { ...props.Field };
33
+ const lField = Object.clone(props.Field);
34
+
34
35
  lField.Rules = lField.Rules || [];
35
36
  for (let i = 0; i < lField.Rules.length; i += 1) {
36
37
  const rule = lField.Rules[i];
@@ -205,6 +206,7 @@ export default defineComponent({
205
206
  emit("input", fld || props.Field);
206
207
  },
207
208
  ...compEmits.value,
209
+ ...localField.value.attrs,
208
210
  },
209
211
  {
210
212
  ...slots,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-fe-core-modules",
3
- "version": "0.0.44",
3
+ "version": "0.0.46",
4
4
  "main": "index.js",
5
5
  "repository": "https://github.com/freeeis/free-fe-core-modules.git",
6
6
  "author": "zhiquan",