Browse Source

1、w-form-group支持自定义布局

2、w-textarea等基础组件支持插槽
3、w-grid的按钮响应式问题修复
4、w-grid的td-content支持任意类型
main
likunming 4 weeks ago
parent
commit
7b97258b3f
  1. 2
      io.sc.platform.core.frontend/package.json
  2. 17
      io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckbox.vue
  3. 10
      io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckboxGroup.vue
  4. 23
      io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue
  5. 10
      io.sc.platform.core.frontend/src/platform/components/color/WColorInput.vue
  6. 10
      io.sc.platform.core.frontend/src/platform/components/color/WColorInputPalette.vue
  7. 10
      io.sc.platform.core.frontend/src/platform/components/cron/WCron.vue
  8. 10
      io.sc.platform.core.frontend/src/platform/components/date/WDate.vue
  9. 10
      io.sc.platform.core.frontend/src/platform/components/date/WDateRange.vue
  10. 10
      io.sc.platform.core.frontend/src/platform/components/file/WFile.vue
  11. 2
      io.sc.platform.core.frontend/src/platform/components/form/FormElement.vue
  12. 92
      io.sc.platform.core.frontend/src/platform/components/form/FormField.ts
  13. 172
      io.sc.platform.core.frontend/src/platform/components/form/FormGroup.vue
  14. 18
      io.sc.platform.core.frontend/src/platform/components/form/ts/Constant.ts
  15. 2
      io.sc.platform.core.frontend/src/platform/components/form/ts/Form.ts
  16. 6
      io.sc.platform.core.frontend/src/platform/components/grid/TdContent.vue
  17. 9
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  18. 6
      io.sc.platform.core.frontend/src/platform/components/grid/extra/Editor.vue
  19. 2
      io.sc.platform.core.frontend/src/platform/components/grid/ts/function/RequestApi.ts
  20. 4
      io.sc.platform.core.frontend/src/platform/components/grid/ts/types/PropsType.ts
  21. 10
      io.sc.platform.core.frontend/src/platform/components/icon/WIcon.vue
  22. 10
      io.sc.platform.core.frontend/src/platform/components/number/WInteger.vue
  23. 10
      io.sc.platform.core.frontend/src/platform/components/number/WNumber.vue
  24. 10
      io.sc.platform.core.frontend/src/platform/components/password/WPassword.vue
  25. 10
      io.sc.platform.core.frontend/src/platform/components/position/WPosition.vue
  26. 10
      io.sc.platform.core.frontend/src/platform/components/radio/WRadio.vue
  27. 10
      io.sc.platform.core.frontend/src/platform/components/select/WGridSelect.vue
  28. 10
      io.sc.platform.core.frontend/src/platform/components/select/WInputSelect.vue
  29. 10
      io.sc.platform.core.frontend/src/platform/components/select/WOrgSelect.vue
  30. 10
      io.sc.platform.core.frontend/src/platform/components/select/WRoleSelect.vue
  31. 10
      io.sc.platform.core.frontend/src/platform/components/select/WSelect.vue
  32. 10
      io.sc.platform.core.frontend/src/platform/components/select/WUserSelect.vue
  33. 10
      io.sc.platform.core.frontend/src/platform/components/text/WText.vue
  34. 19
      io.sc.platform.core.frontend/src/platform/components/textarea/WTextarea.vue

2
io.sc.platform.core.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "platform-core", "name": "platform-core",
"version": "8.2.60", "version": "8.2.64",
"description": "前端核心包,用于快速构建前端的脚手架", "description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件", "//main": "库的主文件",
"main": "dist/platform-core.js", "main": "dist/platform-core.js",

17
io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckbox.vue

@ -25,6 +25,10 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
></q-checkbox> ></q-checkbox>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field> </q-field>
</template> </template>
<template v-else> <template v-else>
@ -35,18 +39,25 @@
:readonly="fieldMethodsClass.getReadOnly(props, modelValue)" :readonly="fieldMethodsClass.getReadOnly(props, modelValue)"
:disable="fieldMethodsClass.getDisable(props, modelValue)" :disable="fieldMethodsClass.getDisable(props, modelValue)"
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
></q-checkbox> >
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-checkbox>
</template> </template>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const checkboxRef = ref(); const checkboxRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel({ type: Boolean, default: false }); const modelValue = defineModel({ type: Boolean, default: false });
interface FieldProps extends FormFieldProps { interface FieldProps extends FormFieldProps {
@ -58,6 +69,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckboxGroup.vue

@ -40,16 +40,22 @@
:disable="fieldMethodsClass.getDisable(props, modelValue)" :disable="fieldMethodsClass.getDisable(props, modelValue)"
/> />
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field> </q-field>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const checkboxGroupRef = ref(); const checkboxGroupRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<Array<string> | Array<number>>(); const modelValue = defineModel<Array<string> | Array<number>>();
interface FieldProps extends FormFieldProps { interface FieldProps extends FormFieldProps {
@ -71,6 +77,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
}, },
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

23
io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue

@ -20,26 +20,15 @@
</div> </div>
<div ref="codemirrorContainerRef" :style="`width:100%; padding-top: ${lineNumber ? 4 : 2}px; overflow: auto;`"></div> <div ref="codemirrorContainerRef" :style="`width:100%; padding-top: ${lineNumber ? 4 : 2}px; overflow: auto;`"></div>
</template> </template>
<template v-if="!Tools.isEmpty(modelValue) && attrs.button" #append> <template v-for="slotName in fieldMethods.slotNames" :key="slotName" #[slotName]>
<q-btn <slot v-if="fieldMethods.isTemplateSlot" :name="slotName"></slot>
round <FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
dense
flat
v-bind="attrs.button"
:style="{
content: '',
position: 'absolute',
bottom: '5px',
right: '5px',
}"
@click.stop.prevent="buttonClick(attrs.button)"
/>
</template> </template>
</q-field> </q-field>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, onMounted, onUnmounted, watch } from 'vue'; import { ref, useAttrs, onMounted, onUnmounted, watch, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { EditorView } from '@codemirror/view'; import { EditorView } from '@codemirror/view';
import { EditorState, StateEffect, Compartment } from '@codemirror/state'; import { EditorState, StateEffect, Compartment } from '@codemirror/state';
@ -62,10 +51,12 @@ import Toolbar from '@/platform/components/math/toolbar/Toolbar.vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const fieldRef = ref(); const fieldRef = ref();
const codemirrorContainerRef = ref(); const codemirrorContainerRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
let editorView = null; let editorView = null;
@ -127,6 +118,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_: any) => { updateValue = (value_: any) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/color/WColorInput.vue

@ -51,17 +51,23 @@
@click="restoreDefaultValue" @click="restoreDefaultValue"
></q-btn> ></q-btn>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue'; import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const colorRef = ref(); const colorRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
const isShow = ref(false); const isShow = ref(false);
@ -76,6 +82,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false, restore: false,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
isShow.value = false; isShow.value = false;
if (props['onUpdateValue']) { if (props['onUpdateValue']) {

10
io.sc.platform.core.frontend/src/platform/components/color/WColorInputPalette.vue

@ -56,18 +56,24 @@
@click="restoreDefaultValue" @click="restoreDefaultValue"
></q-btn> ></q-btn>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue'; import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import { quasarColors } from './quasarColors'; import { quasarColors } from './quasarColors';
import FormElementSlot from '../form/FormElementSlot.vue';
const colorRef = ref(); const colorRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
const isShow = ref(false); const isShow = ref(false);
@ -82,6 +88,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false, restore: false,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
modelValue.value = value_; modelValue.value = value_;
isShow.value = false; isShow.value = false;

10
io.sc.platform.core.frontend/src/platform/components/cron/WCron.vue

@ -55,11 +55,15 @@
</q-popup-proxy> </q-popup-proxy>
</q-btn> </q-btn>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import SecondSegment from './w-cron-segment/SecondSegment.vue'; import SecondSegment from './w-cron-segment/SecondSegment.vue';
import MinuteSegment from './w-cron-segment/MinuteSegment.vue'; import MinuteSegment from './w-cron-segment/MinuteSegment.vue';
@ -70,9 +74,11 @@ import WeekSegment from './w-cron-segment/WeekSegment.vue';
import YearSegment from './w-cron-segment/YearSegment.vue'; import YearSegment from './w-cron-segment/YearSegment.vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const cronRef = ref(); const cronRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
const isShow = ref(false); const isShow = ref(false);
@ -91,6 +97,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/date/WDate.vue

@ -29,18 +29,24 @@
</q-popup-proxy> </q-popup-proxy>
</q-icon> </q-icon>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, watch } from 'vue'; import { ref, useAttrs, watch, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const dateRef = ref(); const dateRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
@ -48,6 +54,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/date/WDateRange.vue

@ -30,18 +30,24 @@
</q-popup-proxy> </q-popup-proxy>
</q-icon> </q-icon>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, computed } from 'vue'; import { ref, useAttrs, computed, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const dateRangeRef = ref(); const dateRangeRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<object>(); const modelValue = defineModel<object>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
@ -49,6 +55,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/file/WFile.vue

@ -20,17 +20,23 @@
<template v-if="!fieldMethodsClass.getReadOnly(props, modelValue)" #append> <template v-if="!fieldMethodsClass.getReadOnly(props, modelValue)" #append>
<q-icon name="attachment" /> <q-icon name="attachment" />
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-file> </q-file>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const fileRef = ref(); const fileRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<File | Array<File>>(); const modelValue = defineModel<File | Array<File>>();
interface FieldProps extends FormFieldProps { interface FieldProps extends FormFieldProps {
@ -41,6 +47,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
type: 'file', type: 'file',
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

2
io.sc.platform.core.frontend/src/platform/components/form/FormElement.vue

@ -1,6 +1,6 @@
<template> <template>
<template v-if="field.type === Constant.GROUP_TYPE"> <template v-if="field.type === Constant.GROUP_TYPE">
<FormGroup v-if="showFormGroupComputed" v-bind="field" :fields="field.fields" :style="form.getFieldStyle(field)"></FormGroup> <FormGroup v-if="showFormGroupComputed" v-bind="field" :fields="field.fields" :component-style="form.getFieldStyle(field)"></FormGroup>
</template> </template>
<template v-else> <template v-else>
<Field :field="props.field"></Field> <Field :field="props.field"></Field>

92
io.sc.platform.core.frontend/src/platform/components/form/FormField.ts

@ -9,22 +9,73 @@ export interface FormFieldProps {
readOnlyIf?: boolean | (() => void); // 是否只读 readOnlyIf?: boolean | (() => void); // 是否只读
disableIf?: boolean | (() => void); // 是否禁用 disableIf?: boolean | (() => void); // 是否禁用
rules?: Array<() => void>; // 验证规则集合 rules?: Array<() => void>; // 验证规则集合
slot?: object; // 插槽集合
onUpdateValue?: () => void; // 值改变事件函数 onUpdateValue?: () => void; // 值改变事件函数
} }
export abstract class FormFieldMethods { export abstract class FormFieldMethods {
// 值改变事件 /**
*
*/
isTemplateSlot?: boolean;
/**
*
*/
slotNames?: string[];
/**
*
* @param value_
*/
abstract updateValue(value_): void; abstract updateValue(value_): void;
// 验证方法 /**
*
*/
abstract validate(): Promise<boolean> | boolean; abstract validate(): Promise<boolean> | boolean;
// 设置值 /**
*
* @param value_
*/
abstract setValue(value_): void; abstract setValue(value_): void;
// 获取值 /**
*
*/
abstract getValue(): any; abstract getValue(): any;
// 清空值 /**
*
*/
abstract clearValue(): void; abstract clearValue(): void;
// 获取验证规则集结果 /**
*
* @param slots
* @returns
*/
getSlotType(slots: any) {
return Object.keys(slots).length > 0;
}
/**
*
* @param slots
* @param props
*/
getSlotNames(slots: any, props: any) {
if (Object.keys(slots).length > 0) {
return Object.keys(slots);
} else if (props['slot']) {
return Object.keys(props['slot']);
}
return [];
}
/**
*
* @param props_
* @param value_
* @param componentRef_
* @param defaultValue_
* @returns
*/
getRules(props_, value_, componentRef_, defaultValue_) { getRules(props_, value_, componentRef_, defaultValue_) {
let result = props_.rules || <any>[]; let result = props_.rules || <any>[];
if (!Tools.isEmpty(defaultValue_)) { if (!Tools.isEmpty(defaultValue_)) {
@ -42,8 +93,12 @@ export abstract class FormFieldMethods {
} }
return result; return result;
} }
/**
// 获取是否必填结果 *
* @param props_
* @param value_
* @returns
*/
getRequired(props_, value_) { getRequired(props_, value_) {
if (!Tools.isEmpty(props_.requiredIf)) { if (!Tools.isEmpty(props_.requiredIf)) {
if (typeof props_.requiredIf === 'boolean') { if (typeof props_.requiredIf === 'boolean') {
@ -54,7 +109,12 @@ export abstract class FormFieldMethods {
} }
return false; return false;
} }
// 获取是否显示结果 /**
*
* @param props_
* @param value_
* @returns
*/
getShow(props_, value_) { getShow(props_, value_) {
if (!Tools.isEmpty(props_.showIf)) { if (!Tools.isEmpty(props_.showIf)) {
if (typeof props_.showIf === 'boolean') { if (typeof props_.showIf === 'boolean') {
@ -65,7 +125,12 @@ export abstract class FormFieldMethods {
} }
return true; return true;
} }
// 获取是否只读结果 /**
*
* @param props_
* @param value_
* @returns
*/
getReadOnly(props_, value_) { getReadOnly(props_, value_) {
if (props_.form && props_.form.getStatus() === 'view') { if (props_.form && props_.form.getStatus() === 'view') {
return true; return true;
@ -79,7 +144,12 @@ export abstract class FormFieldMethods {
} }
return false; return false;
} }
// 获取是否禁用结果 /**
*
* @param props_
* @param value_
* @returns
*/
getDisable(props_, value_) { getDisable(props_, value_) {
if (!Tools.isEmpty(props_.disableIf)) { if (!Tools.isEmpty(props_.disableIf)) {
if (typeof props_.disableIf === 'boolean') { if (typeof props_.disableIf === 'boolean') {

172
io.sc.platform.core.frontend/src/platform/components/form/FormGroup.vue

@ -1,9 +1,10 @@
<template> <template>
<div> <div :style="componentStyle">
<div v-if="cardModeComputed">
<q-card flat bordered> <q-card flat bordered>
<q-item dense style="padding: 0px"> <q-item dense style="padding: 0px">
<q-item-section> <q-item-section>
<q-item-label header :style="headerStyleComputed"> <q-item-label header :style="cardModeHeaderStyleComputed">
<q-icon v-if="props.icon" :name="props.icon" size="sm" v-bind="props.iconAttrs" /> <q-icon v-if="props.icon" :name="props.icon" size="sm" v-bind="props.iconAttrs" />
<span style="margin-left: 5px">{{ label }}</span> <span style="margin-left: 5px">{{ label }}</span>
</q-item-label> </q-item-label>
@ -11,14 +12,24 @@
</q-item> </q-item>
<q-separator /> <q-separator />
<q-card-section style="padding: 8px"> <q-card-section style="padding: 8px">
<div class="grid" :style="layoutStyleComputed"> <div :class="props.class" :style="contentStyleComputed">
<template v-for="(field, index) in fields as any" :key="String(index)"> <template v-for="(field, index) in fields as any" :key="String(index)">
<div :class="field.class" :style="formElementDivStyle(field)">
<FormElement :field="field"></FormElement> <FormElement :field="field"></FormElement>
</div>
</template> </template>
</div> </div>
</q-card-section> </q-card-section>
</q-card> </q-card>
</div> </div>
<div v-else :class="props.class" :style="contentStyleComputed">
<template v-for="(field, index) in fields as any" :key="String(index)">
<div :class="field.class" :style="formElementDivStyle(field)">
<FormElement :field="field"></FormElement>
</div>
</template>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -26,6 +37,7 @@ import { inject, computed } from 'vue';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { Form } from './ts/Form'; import { Form } from './ts/Form';
import { Constant } from './ts/Constant';
import FormElement from './FormElement.vue'; import FormElement from './FormElement.vue';
const $q = useQuasar(); const $q = useQuasar();
@ -53,16 +65,35 @@ const colors = [red, orange, yellow, green, teal, blue, purple, grey];
const colorJson = { red, orange, yellow, green, teal, blue, purple, grey }; const colorJson = { red, orange, yellow, green, teal, blue, purple, grey };
const props = defineProps({ const props = defineProps({
// //
mode: { type: String, default: Constant.FORM_GROUP_MODE.CONTAINER },
// card-
label: { type: String, default: '' }, label: { type: String, default: '' },
// // card-
color: { type: String, default: undefined }, headerBgColor: { type: String, default: undefined },
// // card-
icon: { type: String, default: undefined }, icon: { type: String, default: undefined },
// // card-
iconAttrs: { type: Object, default: undefined }, iconAttrs: { type: Object, default: undefined },
// form // div`class`carddivcontainerdiv
class: { type: String, default: undefined },
// divcarddivcontainerdiv
style: { type: String, default: undefined },
// divleftrightcenterbetweenform
//
// left = display: flex; justify-content: flex-start;
// right = display: flex; justify-content: flex-end;
// center = display: flex; justify-content: center;
// between = display: flex; justify-content: space-between;
// form = form ;
// classstylealigndivclassstylealignstyle
align: { type: String, default: undefined },
// `align` `form` form
colsNum: { type: [Number, Object], default: 0 }, colsNum: { type: [Number, Object], default: 0 },
// 使alignx
xGap: { type: Number, default: 8 },
// 使aligny
yGap: { type: Number, default: 4 },
// //
fields: { fields: {
type: Array, type: Array,
@ -70,9 +101,75 @@ const props = defineProps({
return []; return [];
}, },
}, },
// ()
componentStyle: {
type: Object,
default: undefined,
},
});
/**
* 当前屏幕断点一列应该显示的元素个数
*/
const screenColsNumComputed = computed(() => {
if (typeof props.colsNum === 'number' && props.colsNum > 0) {
return props.colsNum;
} else if (typeof props.colsNum === 'object') {
const screen = { ...form.cm.screenCols, ...props.colsNum };
return screen[$q.screen.name];
}
return form.cm.screenCols[$q.screen.name];
});
/**
* 使用form布局时的样式
*/
const useFormLayoutStyleComputed = computed(() => {
const style = { display: 'grid' };
if (typeof props.colsNum === 'number' && props.colsNum > 0) {
style['grid-template-columns'] = 'repeat(' + props.colsNum + ', minmax(0, 1fr))';
} else {
style['grid-template-columns'] = 'repeat(' + screenColsNumComputed.value + ', minmax(0, 1fr))';
}
style['column-gap'] = form.props.xGap + 'px';
style['row-gap'] = form.props.yGap + 'px';
return style;
}); });
const headerStyleComputed = computed(() => { const jsonStyle2String = (json: any) => {
return Object.entries(json)
.map(([k, v]) => `${k}:${v}`)
.join(';');
};
/**
* 快速布局对应的样式
*/
const alignJson = {
left: {
value: 'left',
style: 'display:flex; justify-content: flex-start;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
right: {
value: 'right',
style: 'display:flex; justify-content: flex-end;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
center: {
value: 'center',
style: 'display:flex; justify-content: center;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
between: {
value: 'between',
style: 'display:flex; justify-content: space-between;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
form: {
value: 'form',
style: jsonStyle2String(useFormLayoutStyleComputed.value),
},
};
/**
* card模式标题块样式
*/
const cardModeHeaderStyleComputed = computed(() => {
const style = { const style = {
// //
display: 'flex', display: 'flex',
@ -81,16 +178,16 @@ const headerStyleComputed = computed(() => {
color: '#000', color: '#000',
padding: '5px', padding: '5px',
}; };
if (props.color) { if (props.headerBgColor) {
// //
if (props.color === 'auto') { if (props.headerBgColor === 'auto') {
const index = form.fieldArray.value.findIndex((item) => item.label === props.label); const index = form.fieldArray.value.findIndex((item) => item.label === props.label);
let colorIndex = index > -1 && index < colors.length ? index : getRandomInt(); let colorIndex = index > -1 && index < colors.length ? index : getRandomInt();
style['background-color'] = colors[colorIndex]; style['background-color'] = colors[colorIndex];
} else if (Tools.hasOwnProperty(colorJson, props.color)) { } else if (Tools.hasOwnProperty(colorJson, props.headerBgColor)) {
style['background-color'] = colorJson[props.color]; style['background-color'] = colorJson[props.headerBgColor];
} else { } else {
style['background-color'] = props.color; style['background-color'] = props.headerBgColor;
} }
} }
return style; return style;
@ -103,25 +200,36 @@ const getRandomInt = () => {
return Math.floor(Math.random() * (max - min + 1) + min); return Math.floor(Math.random() * (max - min + 1) + min);
}; };
const screenColsNumComputed = computed(() => { /**
if (typeof props.colsNum === 'number' && props.colsNum > 0) { * 当前为card模式
return props.colsNum; */
} else if (typeof props.colsNum === 'object') { const cardModeComputed = computed(() => {
const screen = { ...form.cm.screenCols, ...props.colsNum }; return props.mode === Constant.FORM_GROUP_MODE.CARD;
return screen[$q.screen.name];
}
return form.cm.screenCols[$q.screen.name];
}); });
const layoutStyleComputed = computed(() => { /**
const style = {}; * 分组下内容块使用的样式
if (typeof props.colsNum === 'number' && props.colsNum > 0) { */
style['grid-template-columns'] = 'repeat(' + props.colsNum + ', minmax(0, 1fr))'; const contentStyleComputed = computed(() => {
} else { let styleStr = '';
style['grid-template-columns'] = 'repeat(' + screenColsNumComputed.value + ', minmax(0, 1fr))'; if (props.style) {
//
styleStr = props.style + (props.style.trim().endsWith(';') ? '' : ';');
} }
style['column-gap'] = form.props.xGap + 'px'; if (props.align && Tools.hasOwnProperty(alignJson, props.align)) {
style['row-gap'] = form.props.yGap + 'px'; styleStr += alignJson[props.align]['style'];
return style; }
return styleStr;
}); });
const formElementDivStyle = (field: any) => {
let styleStr = '';
if (field.style) {
styleStr = field.style + (field.style.trim().endsWith(';') ? '' : ';');
}
if (props.align && props.align === alignJson.form.value) {
styleStr += jsonStyle2String(form.getFieldStyle(field));
}
return styleStr;
};
</script> </script>

18
io.sc.platform.core.frontend/src/platform/components/form/ts/Constant.ts

@ -1,3 +1,14 @@
class FormGroupMode {
/**
* `icon` `label`
*/
static CARD = 'card';
/**
* `fields` `div`
*/
static CONTAINER = 'container';
}
/** /**
* *
*/ */
@ -8,7 +19,12 @@ export class Constant {
static STATUS_ADD = 'add'; static STATUS_ADD = 'add';
/** /**
* *
*/ */
static GROUP_TYPE = 'w-form-group'; static GROUP_TYPE = 'w-form-group';
/**
* `w-form-group`
*/
static FORM_GROUP_MODE = FormGroupMode;
} }

2
io.sc.platform.core.frontend/src/platform/components/form/ts/Form.ts

@ -102,7 +102,7 @@ export class Form {
} else { } else {
if (field.colSpan === 'full') { if (field.colSpan === 'full') {
// col-span-${screenColsNumComputed.value} // col-span-${screenColsNumComputed.value}
style['grid-column'] = `span ${screenColsNum} / span ${screenColsNum}`; style['grid-column'] = `1 / -1`;
} else { } else {
if (field.colSpan && screenColsNum >= field.colSpan) { if (field.colSpan && screenColsNum >= field.colSpan) {
// col-span-${field.colSpan} // col-span-${field.colSpan}

6
io.sc.platform.core.frontend/src/platform/components/grid/TdContent.vue

@ -22,10 +22,8 @@ import { Constant, GridTools } from './ts/index';
const tools = <GridTools>inject('tools'); const tools = <GridTools>inject('tools');
const props = defineProps({ const props = defineProps({
value: { value: {
type: [Object, String, Number], type: null,
default: () => { default: '',
return '';
},
}, },
col: { col: {
type: Object, type: Object,

9
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -108,6 +108,15 @@ watch(
}, },
); );
// props
watch(
() => props.toolbarActions,
(newVal, oldVal) => {
tools.props = props;
getTopRef()?.handleToolbarActions();
},
);
eventBus.on('onLocaleChanged', (local) => { eventBus.on('onLocaleChanged', (local) => {
nextTick(() => { nextTick(() => {
topRef.value?.handleQueryFormShowField(); topRef.value?.handleQueryFormShowField();

6
io.sc.platform.core.frontend/src/platform/components/grid/extra/Editor.vue

@ -105,8 +105,6 @@ const addData = (dialogFormData) => {
} else { } else {
tools.apiFM.localMode.addLocalData(dialogFormData, undefined); tools.apiFM.localMode.addLocalData(dialogFormData, undefined);
} }
//
tools.em.afterEditorDataSubmit({ grid: tools.instance, data: dialogFormData });
}; };
const updateData = (dialogFormData) => { const updateData = (dialogFormData) => {
const selected = tools.apiFM.getData.getSelectedRow(); const selected = tools.apiFM.getData.getSelectedRow();
@ -121,8 +119,6 @@ const updateData = (dialogFormData) => {
dialogFormData['children'] = selected['children']; dialogFormData['children'] = selected['children'];
} }
tools.apiFM.localMode.updateLocalData(dialogFormData); tools.apiFM.localMode.updateLocalData(dialogFormData);
//
tools.em.afterEditorDataSubmit({ grid: tools.instance, data: dialogFormData });
}; };
const localModeSave = (dialogFormData: any, formStatus: string, closeDialog: boolean) => { const localModeSave = (dialogFormData: any, formStatus: string, closeDialog: boolean) => {
@ -132,6 +128,8 @@ const localModeSave = (dialogFormData: any, formStatus: string, closeDialog: boo
updateData(dialogFormData); updateData(dialogFormData);
} }
saveLoading.value = false; saveLoading.value = false;
//
tools.em.afterEditorDataSubmit(dialogFormData);
if (closeDialog) { if (closeDialog) {
dialogRef.value.hide(); dialogRef.value.hide();
} }

2
io.sc.platform.core.frontend/src/platform/components/grid/ts/function/RequestApi.ts

@ -130,7 +130,7 @@ export class RequestApi extends Base {
callback(resp); callback(resp);
} }
NotifyManager.info($t('tip.operationSuccess') || ''); NotifyManager.info($t('tip.operationSuccess') || '');
this.tools?.em.afterEditorDataSubmit({ grid: this.instance, data: resp.data }); this.tools?.em.afterEditorDataSubmit(resp.data);
}) })
.catch((error) => { .catch((error) => {
if (error?.code === 1001) { if (error?.code === 1001) {

4
io.sc.platform.core.frontend/src/platform/components/grid/ts/types/PropsType.ts

@ -58,7 +58,7 @@ export type PropsType = {
/** /**
* GETPOST使使 * GETPOST使使
*/ */
customFetch: Function | undefined, customFetch?: Function | undefined,
/** /**
* *
*/ */
@ -170,7 +170,7 @@ export type PropsType = {
/** /**
* alone `format` 使format进行内容显示处理 * alone `format` 使format进行内容显示处理
*/ */
groupByTitle: string | Function, groupByTitle?: string | Function,
/** /**
* *
*/ */

10
io.sc.platform.core.frontend/src/platform/components/icon/WIcon.vue

@ -88,11 +88,15 @@
@click="restoreDefaultValue" @click="restoreDefaultValue"
></q-btn> ></q-btn>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue'; import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
@ -103,9 +107,11 @@ import eva from './icons/eva-icons.json';
import fontawesomeBrands from './icons/fontawesome-v6-icons-brands.json'; import fontawesomeBrands from './icons/fontawesome-v6-icons-brands.json';
import fontawesomeRegular from './icons/fontawesome-v6-icons-regular.json'; import fontawesomeRegular from './icons/fontawesome-v6-icons-regular.json';
import fontawesomeSolid from './icons/fontawesome-v6-icons-solid.json'; import fontawesomeSolid from './icons/fontawesome-v6-icons-solid.json';
import FormElementSlot from '../form/FormElementSlot.vue';
const iconRef = ref(); const iconRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
const leftWidthRef = ref(30); const leftWidthRef = ref(30);
@ -123,6 +129,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false, restore: false,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/number/WInteger.vue

@ -16,22 +16,30 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
> >
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> <template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { FormValidators } from '@/platform/components'; import { FormValidators } from '@/platform/components';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const numberRef = ref(); const numberRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<number>(); const modelValue = defineModel<number>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
const props = withDefaults(defineProps<FieldProps>(), { showIf: true }); // 使withDefaults const props = withDefaults(defineProps<FieldProps>(), { showIf: true }); // 使withDefaults
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
// FieldMethods // FieldMethods
updateValue = (value_) => { updateValue = (value_) => {
const floatValue = parseInt(value_); const floatValue = parseInt(value_);

10
io.sc.platform.core.frontend/src/platform/components/number/WNumber.vue

@ -16,18 +16,24 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
> >
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> <template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, computed } from 'vue'; import { ref, useAttrs, computed, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormValidators } from '@/platform/components'; import { FormValidators } from '@/platform/components';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const numberRef = ref(); const numberRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<number>(); const modelValue = defineModel<number>();
interface FieldProps extends FormFieldProps { interface FieldProps extends FormFieldProps {
@ -36,6 +42,8 @@ interface FieldProps extends FormFieldProps {
} }
const props = withDefaults(defineProps<FieldProps>(), { precision: undefined, showIf: true }); // 使withDefaults const props = withDefaults(defineProps<FieldProps>(), { precision: undefined, showIf: true }); // 使withDefaults
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
// FieldMethods // FieldMethods
updateValue = (value_) => { updateValue = (value_) => {
const floatValue = parseFloat(value_); const floatValue = parseFloat(value_);

10
io.sc.platform.core.frontend/src/platform/components/password/WPassword.vue

@ -16,17 +16,23 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
> >
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> <template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const pwdRef = ref(); const pwdRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
@ -34,6 +40,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/position/WPosition.vue

@ -57,17 +57,23 @@
@click="restoreDefaultValue" @click="restoreDefaultValue"
></q-btn> ></q-btn>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue'; import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const positionRef = ref(); const positionRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
const positionList = ['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right']; const positionList = ['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'];
@ -83,6 +89,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false, restore: false,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
isShow.value = false; isShow.value = false;
modelValue.value = value_; modelValue.value = value_;

10
io.sc.platform.core.frontend/src/platform/components/radio/WRadio.vue

@ -59,17 +59,23 @@
@click.stop.prevent="fieldMethodsClass.clearValue" @click.stop.prevent="fieldMethodsClass.clearValue"
></q-btn> ></q-btn>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field> </q-field>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const radioRef = ref(); const radioRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | boolean | number>(); const modelValue = defineModel<string | boolean | number>();
interface FieldProps extends FormFieldProps { interface FieldProps extends FormFieldProps {
@ -93,6 +99,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
}, },
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WGridSelect.vue

@ -50,19 +50,25 @@
<template v-if="counter" #counter> <template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div> <div>{{ modelValue?.length }}</div>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field> </q-field>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, useAttrs, toRaw, watch, onMounted, nextTick } from 'vue'; import { ref, computed, useAttrs, toRaw, watch, onMounted, nextTick, useSlots } from 'vue';
import { Tools, axios } from '@/platform'; import { Tools, axios } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref(); const textSelectRef = ref();
const gridRef = ref(); const gridRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>(); // const modelValue = defineModel<string | Array<string>>(); //
const modelDisplayValue = ref(''); // const modelDisplayValue = ref(''); //
const customDisplayValue = ref(''); // setDisplayValue const customDisplayValue = ref(''); // setDisplayValue
@ -103,6 +109,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
selectableIf: undefined, selectableIf: undefined,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
// //
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {

10
io.sc.platform.core.frontend/src/platform/components/select/WInputSelect.vue

@ -35,18 +35,24 @@
<template v-if="counter" #counter> <template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div> <div>{{ modelValue?.length }}</div>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeMount, ref, useAttrs, watch, useSlots } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { onBeforeMount, ref, useAttrs, watch } from 'vue';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref(); const textSelectRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
const modelDisplayValue = ref(''); // const modelDisplayValue = ref(''); //
@ -61,6 +67,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
counter: false, // counter: false, //
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WOrgSelect.vue

@ -60,18 +60,24 @@
<template v-if="counter" #counter> <template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div> <div>{{ modelValue?.length }}</div>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount } from 'vue'; import { ref, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount, useSlots } from 'vue';
import { Tools, axios, Environment, Formater } from '@/platform'; import { Tools, axios, Environment, Formater } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref(); const textSelectRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>(); const modelValue = defineModel<string | Array<string>>();
const modelObjectValue = ref(<any>[]); // const modelObjectValue = ref(<any>[]); //
const orgGridRef = ref(); const orgGridRef = ref();
@ -141,6 +147,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
queryCriteria: undefined, queryCriteria: undefined,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WRoleSelect.vue

@ -74,18 +74,24 @@
<template v-if="counter" #counter> <template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div> <div>{{ modelValue?.length }}</div>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, useAttrs, toRaw, watch, onMounted } from 'vue'; import { ref, computed, useAttrs, toRaw, watch, onMounted, useSlots } from 'vue';
import { Tools, axios, Environment, Formater } from '@/platform'; import { Tools, axios, Environment, Formater } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref(); const textSelectRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>(); const modelValue = defineModel<string | Array<string>>();
const modelObjectValue = ref(<any>[]); // const modelObjectValue = ref(<any>[]); //
const roleGridRef = ref(); const roleGridRef = ref();
@ -123,6 +129,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
queryCriteria: undefined, // criteria queryCriteria: undefined, // criteria
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WSelect.vue

@ -16,17 +16,23 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
> >
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> <template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-select> </q-select>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue'; import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const selectRef = ref(); const selectRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | number | boolean | Array<string> | Array<number> | Array<boolean>>(); const modelValue = defineModel<string | number | boolean | Array<string> | Array<number> | Array<boolean>>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
@ -34,6 +40,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WUserSelect.vue

@ -107,18 +107,24 @@
<template v-if="counter" #counter> <template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div> <div>{{ modelValue?.length }}</div>
</template> </template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount } from 'vue'; import { ref, reactive, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount, useSlots } from 'vue';
import { Tools, axios, Environment, Formater, $t, SessionManager } from '@/platform'; import { Tools, axios, Environment, Formater, $t, SessionManager } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref(); const textSelectRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>(); const modelValue = defineModel<string | Array<string>>();
const modelObjectValue = ref(<any>[]); // const modelObjectValue = ref(<any>[]); //
const userGridRef = ref(); const userGridRef = ref();
@ -184,6 +190,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
roleQueryCriteria: undefined, // roleQueryCriteria: undefined, //
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/text/WText.vue

@ -15,16 +15,22 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
> >
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> <template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, computed } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textRef = ref(); const textRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
@ -32,6 +38,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

19
io.sc.platform.core.frontend/src/platform/components/textarea/WTextarea.vue

@ -15,26 +15,23 @@
@update:model-value="fieldMethodsClass.updateValue" @update:model-value="fieldMethodsClass.updateValue"
> >
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template> <template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template #default><slot></slot></template> <template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<template #prepend><slot name="prepend"></slot></template> <slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<template #append><slot name="append"></slot></template> <FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
<template #before><slot name="before"></slot></template> </template>
<template #after><slot name="after"></slot></template>
<template #error><slot name="error"></slot></template>
<template #hint><slot name="hint"></slot></template>
<template #counter><slot name="counter"></slot></template>
<template #loading><slot name="loading"></slot></template>
</q-input> </q-input>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts'; import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { ref, useAttrs, useSlots } from 'vue';
import FormElementSlot from '../form/FormElementSlot.vue';
import { FormFieldMethods } from '../form/FormField'; import { FormFieldMethods } from '../form/FormField';
const textareaRef = ref(); const textareaRef = ref();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>(); const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {} interface FieldProps extends FormFieldProps {}
@ -42,6 +39,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true, showIf: true,
}); });
class FieldMethods extends FormFieldMethods { class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => { updateValue = (value_) => {
if (props['onUpdateValue']) { if (props['onUpdateValue']) {
props['onUpdateValue']({ props['onUpdateValue']({

Loading…
Cancel
Save