Browse Source

表格优化提交

main
likunming 1 year ago
parent
commit
51559c5007
  1. 2
      io.sc.platform.core.frontend/package.json
  2. 15
      io.sc.platform.core.frontend/src/platform/components/form/WForm.vue
  3. 235
      io.sc.platform.core.frontend/src/platform/components/form/elements/WIcon.vue
  4. 14
      io.sc.platform.core.frontend/src/platform/components/form/elements/WNumber.vue
  5. 3
      io.sc.platform.core.frontend/src/platform/components/form/elements/WText.vue
  6. 6
      io.sc.platform.core.frontend/src/platform/components/form/elements/WTextBtn.vue
  7. 6
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

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

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

15
io.sc.platform.core.frontend/src/platform/components/form/WForm.vue

@ -24,7 +24,6 @@
v-else
:form-ref="formRef"
v-bind="field"
:form-data="formData"
:form="instance"
:class="
(field.colsFirst ? 'col-start-1 ' : ' ') +
@ -51,6 +50,12 @@ import { PageStatusEnum } from '@/platform/components/utils';
const $q = useQuasar();
const attrs = useAttrs();
const props = defineProps({
modelValue: {
type: Object,
default: () => {
return {};
},
},
colsNum: { type: [Number, Object], default: 0 },
colsXGap: { type: Number, default: 8 },
colsYGap: { type: Number, default: 4 },
@ -131,7 +136,13 @@ for (const field of fields_.value as any) {
}
}
const formData = reactive(formModel);
let formData = reactive(Object.keys(props.modelValue).length > 0 ? props.modelValue : formModel);
watch(
() => props.modelValue,
(newVal, oldVal) => {
formData = reactive(Object.keys(props.modelValue).length > 0 ? props.modelValue : formModel);
},
);
const screenColsNumComputed = computed(() => {
if (typeof props.colsNum === 'number' && props.colsNum > 0) {

235
io.sc.platform.core.frontend/src/platform/components/form/elements/WIcon.vue

@ -1,84 +1,99 @@
<template>
<q-input v-model="valueRef" @update:model-value="valueChanged">
<template #prepend>
<q-icon v-if="valueRef" :name="valueRef"> </q-icon>
<w-icon-empty v-else></w-icon-empty>
</template>
<template #append>
<q-btn icon="bi-search" size="10px" padding="2px" flat square unelevated :title="$t('select')">
<q-popup-proxy v-model:model-value="isShow" anchor="bottom right" self="top right" :offset="[0, 10]" @show="show">
<q-splitter v-model="leftWidthRef" style="width: 800px; height: 300px; position: relative">
<template #before>
<q-tabs v-model="selectedTab" align="left" vertical dense no-caps outside-arrows mobile-arrows>
<q-tab v-for="iconSet in iconSets" :key="iconSet.name" :name="iconSet.name">
<span class="w-[180px] text-left" :title="iconSet.label">
{{ iconSet.label }}
</span>
</q-tab>
</q-tabs>
</template>
<template #after>
<div class="pl-4 pt-2" style="width: 300px; height: 50px">
<q-input v-model="searchRef" outlined dense>
<template #append>
<q-btn round flat icon="bi-search" size="10px" />
</template>
</q-input>
</div>
<q-tab-panels
v-model="selectedTab"
style="height: calc(100% - 50px)"
animated
swipeable
vertical
transition-prev="jump-up"
transition-next="jump-up"
:keep-alive="true"
>
<q-tab-panel v-for="iconSet in iconSets" :key="iconSet.name" :name="iconSet.name" class="full-height">
<div class="row full-height" style="overflow: scroll">
<div v-for="item in iconSet.icons" :key="item">
<div
:id="item"
class="grid justify-items-center q-pa-sm"
:title="item"
:style="
item === valueRef
? 'background-color:var(--q-negative);'
: searchRef && item.indexOf(searchRef) !== -1
? 'background-color:var(--q-warning);'
: ''
"
>
<q-icon size="26px" :name="item" class="cursor-pointer" @click="iconItemClick(item)"> </q-icon>
<div v-show="showIfComputed">
<q-input
ref="iconRef"
v-model="valueRef"
:hide-bottom-space="true"
:hide-hint="true"
:outlined="true"
:dense="true"
v-bind="attrs"
:rules="rulesComputed"
:readonly="readonlyIfComputed"
:disable="disableIfComputed"
@update:model-value="valueChanged"
>
<template #prepend>
<q-icon v-if="valueRef" :name="valueRef"> </q-icon>
<w-icon-empty v-else></w-icon-empty>
</template>
<template #append>
<q-btn icon="bi-search" size="10px" padding="2px" flat square unelevated :title="$t('select')">
<q-popup-proxy v-model:model-value="isShow" anchor="bottom right" self="top right" :offset="[0, 10]" @show="show">
<q-splitter v-model="leftWidthRef" style="width: 800px; height: 300px; position: relative">
<template #before>
<q-tabs v-model="selectedTab" align="left" vertical dense no-caps outside-arrows mobile-arrows>
<q-tab v-for="iconSet in iconSets" :key="iconSet.name" :name="iconSet.name">
<span class="w-[180px] text-left" :title="iconSet.label">
{{ iconSet.label }}
</span>
</q-tab>
</q-tabs>
</template>
<template #after>
<div class="pl-4 pt-2" style="width: 300px; height: 50px">
<q-input v-model="searchRef" outlined dense>
<template #append>
<q-btn round flat icon="bi-search" size="10px" />
</template>
</q-input>
</div>
<q-tab-panels
v-model="selectedTab"
style="height: calc(100% - 50px)"
animated
swipeable
vertical
transition-prev="jump-up"
transition-next="jump-up"
:keep-alive="true"
>
<q-tab-panel v-for="iconSet in iconSets" :key="iconSet.name" :name="iconSet.name" class="full-height">
<div class="row full-height" style="overflow: scroll">
<div v-for="item in iconSet.icons" :key="item">
<div
:id="item"
class="grid justify-items-center q-pa-sm"
:title="item"
:style="
item === valueRef
? 'background-color:var(--q-negative);'
: searchRef && item.indexOf(searchRef) !== -1
? 'background-color:var(--q-warning);'
: ''
"
>
<q-icon size="26px" :name="item" class="cursor-pointer" @click="iconItemClick(item)"> </q-icon>
</div>
</div>
</div>
</div>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-popup-proxy>
</q-btn>
<!-- 恢复默认值按钮 -->
<q-btn
v-if="restore"
icon="bi-arrow-counterclockwise"
size="10px"
padding="2px"
flat
square
unelevated
:title="$t('restore')"
:style="{ 'margin-left': '5px', border: '1px solid #e5e7eb', color: restoreValue, 'background-color': computedStoreBackgroundColorValue }"
@click="restoreDefaultValue"
></q-btn>
</template>
</q-input>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-popup-proxy>
</q-btn>
<!-- 恢复默认值按钮 -->
<q-btn
v-if="restore"
icon="bi-arrow-counterclockwise"
size="10px"
padding="2px"
flat
square
unelevated
:title="$t('restore')"
:style="{ 'margin-left': '5px', border: '1px solid #e5e7eb', color: restoreValue, 'background-color': computedStoreBackgroundColorValue }"
@click="restoreDefaultValue"
></q-btn>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, toRaw, onMounted } from 'vue';
import { ref, toRaw, onMounted, computed, useAttrs, watch } from 'vue';
import { Tools } from '@/platform';
import { FormValidators } from '@/platform/components';
import bootstrap from './icons/bootstrap.json';
import materialIcons from './icons/material-icons.json';
import materialSymbolsOutlined from './icons/material-symbols-outlined.json';
@ -87,9 +102,42 @@ import fontawesomeBrands from './icons/fontawesome-v6-icons-brands.json';
import fontawesomeRegular from './icons/fontawesome-v6-icons-regular.json';
import fontawesomeSolid from './icons/fontawesome-v6-icons-solid.json';
const attrs = useAttrs();
const rules = attrs.rules;
const iconRef = ref();
const props = defineProps({
modelValue: { type: String, default: '' },
restore: { type: Boolean, default: false },
showIf: {
type: Function,
default: () => {
return true;
},
},
required: {
type: Boolean,
default: false,
},
requiredIf: {
type: Function,
default: undefined,
},
readonlyIf: {
type: Function,
default: () => {
return false;
},
},
disableIf: {
type: Function,
default: () => {
return false;
},
},
form: {
type: Object,
default: undefined,
},
});
const emit = defineEmits(['update:modelValue']);
@ -108,8 +156,45 @@ const selectedTab = ref('bootstrap');
const isShow = ref(false);
const searchRef = ref('');
const valueRef = ref(props.modelValue || 'bi-arrow-up-left-square');
watch(
() => props.modelValue,
(newVal, oldVal) => {
valueRef.value = newVal;
},
);
const restoreValue = toRaw(props.modelValue || '');
const rulesComputed = computed(() => {
let result = rules || <any>[];
if (showIfComputed.value && requiredIfComputed.value) {
result.push(FormValidators.required());
} else if (!showIfComputed.value) {
result = [];
}
if (iconRef?.value) {
iconRef.value.resetValidation();
}
return result;
});
const showIfComputed = computed(() => {
return props.showIf(props.form);
});
const requiredIfComputed = computed(() => {
if (props.requiredIf) {
return props.requiredIf(props.form) || false;
} else if (props.required) {
return true;
}
return false;
});
const readonlyIfComputed = computed(() => {
return props.readonlyIf(props.form);
});
const disableIfComputed = computed(() => {
return props.disableIf(props.form);
});
if (Tools.isEmpty(valueRef.value)) {
selectedTab.value = 'bootstrap';
} else if (valueRef.value.startsWith('bi')) {

14
io.sc.platform.core.frontend/src/platform/components/form/elements/WNumber.vue

@ -14,6 +14,7 @@
:readonly="readonlyIfComputed"
:disable="disableIfComputed"
@update:model-value="updateModelValue"
@change="changeValue"
>
<template #label> <span v-if="requiredIfComputed" style="color: red">*</span> {{ attrs.label }}</template>
</q-input>
@ -28,6 +29,10 @@ const numberRef = ref();
const attrs = useAttrs();
const rules = attrs.rules;
const props = defineProps({
onChange: {
type: Function,
default: () => {},
},
modelValue: { type: Number, default: undefined },
precision: { type: Number, default: 0 },
showIf: {
@ -61,7 +66,7 @@ const props = defineProps({
default: undefined,
},
});
const emit = defineEmits(['update:modelValue']);
const emit = defineEmits(['update:modelValue', 'change']);
const numberValue = ref(props.modelValue);
watch(
() => props.modelValue,
@ -85,7 +90,7 @@ const rulesComputed = computed(() => {
});
const showIfComputed = computed(() => {
return props.showIf(props.form);
return props.showIf(numberValue.value, props.form);
});
const requiredIfComputed = computed(() => {
if (props.requiredIf) {
@ -103,6 +108,9 @@ const disableIfComputed = computed(() => {
});
const updateModelValue = (value) => {
emit('update:modelValue', Number(value));
emit('update:modelValue', Number(value), props.form);
};
const changeValue = (value) => {
emit('change', value, props.form);
};
</script>

3
io.sc.platform.core.frontend/src/platform/components/form/elements/WText.vue

@ -59,7 +59,7 @@ const props = defineProps({
default: undefined,
},
});
const emit = defineEmits(['update:modelValue']);
const emit = defineEmits(['update:modelValue', 'changeValue']);
const textValue = ref(props.modelValue);
watch(
() => props.modelValue,
@ -101,5 +101,6 @@ const disableIfComputed = computed(() => {
const updateModelValue = (value) => {
emit('update:modelValue', value);
emit('changeValue', value, props.form);
};
</script>

6
io.sc.platform.core.frontend/src/platform/components/form/elements/WTextBtn.vue

@ -12,11 +12,7 @@
:rules="rulesComputed"
:readonly="readonlyIfComputed"
:disable="disableIfComputed"
@focus="
() => {
console.info('ffffffff');
}
"
@focus="() => {}"
@update:model-value="updateModelValue"
>
<template #label> <span v-if="requiredIfComputed" style="color: red">*</span> {{ attrs.label }}</template>

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

@ -24,7 +24,7 @@
<template #top="scope">
<q-resize-observer @resize="onResize" />
<div class="col">
<w-form ref="queryFormRef" v-bind="props.queryFormAttrs" :fields="props.queryFormFields" :cols-num="queryFormColsNum"></w-form>
<w-form ref="queryFormRef" v-bind="props.queryFormAttrs" :fields="table.queryFormFields" :cols-num="queryFormColsNum"></w-form>
<div
v-if="title || buttons_.length > 0 || configButton || table.queryFormFields.length > 0"
class="flex flex-nowrap items-end"
@ -2090,11 +2090,11 @@ const handlerQueryFormShowField = () => {
}
if (currRowColsNum <= rowColsNum) {
table.queryFormFields.push(item);
item.showIf = () => {
item.showIf = (form) => {
return true;
};
} else {
item.showIf = () => {
item.showIf = (form) => {
return false;
};
}

Loading…
Cancel
Save