优化一些显示问题

This commit is contained in:
gary.fu
2024-01-25 17:08:34 +08:00
parent 3887d39449
commit 5fa3fdbc78
17 changed files with 147 additions and 36 deletions

View File

@@ -90,6 +90,10 @@ html, body, #app, .index-container {
display: block; display: block;
} }
.flex-column {
flex-direction: column;
}
.container-center { .container-center {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@@ -21,6 +21,10 @@ const props = defineProps({
type: String, type: String,
default: '' default: ''
}, },
autoPageShowTitle: {
type: Boolean,
default: false
},
placeholder: { placeholder: {
type: String, type: String,
default: '' default: ''
@@ -29,11 +33,11 @@ const props = defineProps({
type: String, type: String,
default: '' default: ''
}, },
idKey: { idProp: {
type: String, type: String,
default: 'value' default: 'value'
}, },
labelKey: { labelProp: {
type: String, type: String,
default: 'label' default: 'label'
}, },
@@ -47,7 +51,7 @@ const props = defineProps({
}, },
inputWidth: { inputWidth: {
type: String, type: String,
default: '220px' default: '200px'
}, },
autocompleteConfig: { autocompleteConfig: {
type: Object, type: Object,
@@ -61,6 +65,14 @@ const props = defineProps({
type: Number, type: Number,
default: 4 default: 4
}, },
rowSize: {
type: Number,
default: 6
},
tabStretch: {
type: Boolean,
default: true
},
clearable: { clearable: {
type: Boolean, type: Boolean,
default: true default: true
@@ -122,8 +134,8 @@ const autoPage = ref({
}) })
const loadingData = ref(false) const loadingData = ref(false)
const idProp = computed(() => props.autocompleteConfig?.idKey || props.idKey) const idProp = computed(() => props.autocompleteConfig?.idProp || props.idProp)
const labelProp = computed(() => props.autocompleteConfig?.labelKey || props.labelKey) const labelProp = computed(() => props.autocompleteConfig?.labelProp || props.labelProp)
const showSelectPage = computed(() => { const showSelectPage = computed(() => {
return props.selectPageConfig && (!keywords.value || lastAutocompleteLabel.value === keywords.value) return props.selectPageConfig && (!keywords.value || lastAutocompleteLabel.value === keywords.value)
@@ -303,8 +315,8 @@ const parsedSelectPageData = computed(() => {
}) })
const getSelectPage = (totalCount) => { const getSelectPage = (totalCount) => {
const pageSize = 5 const pageSize = props.rowSize
const pageCount = Math.ceil((totalCount + pageSize - 1) / pageSize) const pageCount = Math.floor((totalCount + pageSize - 1) / pageSize)
return { return {
pageNumber: 1, pageNumber: 1,
pageSize, pageSize,
@@ -321,10 +333,22 @@ const selectPagePagination = (tab) => {
const selectPagePaginationChange = (tab, pageNumber) => { const selectPagePaginationChange = (tab, pageNumber) => {
const pager = selectPagePageConfig.value?.[tab.id] const pager = selectPagePageConfig.value?.[tab.id]
pager.pageNumber = pageNumber pager.pageNumber = pageNumber
console.info('==================selectPagePaginationChange', tab, pageNumber, pager)
selectPageData.value = { ...selectPageData.value } selectPageData.value = { ...selectPageData.value }
} }
const autoTitle = computed(() => {
if (!showSelectPage.value && !props.autoPageShowTitle) {
return undefined
}
return props.title || props.placeholder
})
watch(() => props.selectPageConfig, () => {
selectPagePageConfig.value = {}
selectPageData.value = {}
selectPageTab.value = null
})
</script> </script>
<template> <template>
@@ -334,7 +358,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
popper-class="common-autocomplete" popper-class="common-autocomplete"
placement="bottom-start" placement="bottom-start"
:width="autocompleteWidth" :width="autocompleteWidth"
:title="title||placeholder" :title="autoTitle"
> >
<template #reference> <template #reference>
<el-input <el-input
@@ -355,6 +379,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
v-model="selectPageTab" v-model="selectPageTab"
class="common-select-page" class="common-select-page"
type="border-card" type="border-card"
:stretch="tabStretch"
@tab-click="onInputKeywords(false)" @tab-click="onInputKeywords(false)"
> >
<el-tab-pane <el-tab-pane
@@ -363,7 +388,7 @@ const selectPagePaginationChange = (tab, pageNumber) => {
:name="tab.id" :name="tab.id"
> >
<template #label> <template #label>
<span>{{ tab.label }}</span> <span>{{ tab.label || (tab.labelKey && $t(tab.labelKey)) || tab.id }}</span>
</template> </template>
<template #default> <template #default>
<div <div

View File

@@ -50,14 +50,16 @@ export interface CommonAutocompleteProps {
disabled?: boolean; disabled?: boolean;
// 没有输入时是否可以搜索 // 没有输入时是否可以搜索
emptySearchEnabled?: boolean; emptySearchEnabled?: boolean;
// 是否在自动完成时显示标题
autoPageShowTitle?: boolean;
// 自动完成标题 // 自动完成标题
title?: string; title?: string;
// 占位符 // 占位符
placeholder?: string; placeholder?: string;
// id字段名 // id字段名
idKey?: string; idProp?: string;
// label字段名 // label字段名
labelKey?: string; labelProp?: string;
// 防抖延时 // 防抖延时
debounceTime?: number; debounceTime?: number;
// 自动完成宽度 // 自动完成宽度
@@ -68,6 +70,8 @@ export interface CommonAutocompleteProps {
selectPageConfig?: CommonSelectPageOption; selectPageConfig?: CommonSelectPageOption;
// 可选项列默认显示几列 // 可选项列默认显示几列
colSize?: number; colSize?: number;
// 可选项列默认显示几行
rowSize?: number;
// 加载提示loading // 加载提示loading
loadingText?: string; loadingText?: string;
// 最低高度 // 最低高度

View File

@@ -10,7 +10,8 @@ const route = useRoute()
const breadcrumbs = computed(() => { const breadcrumbs = computed(() => {
const exists = [] const exists = []
return route.matched.map(item => { return route.matched.map((item, index) => {
item = index === route.matched.length - 1 ? route : item
const menuInfo = useMenuInfo(item) const menuInfo = useMenuInfo(item)
let icon = '' let icon = ''
if (menuInfo && menuInfo.icon) { if (menuInfo && menuInfo.icon) {
@@ -28,7 +29,7 @@ const breadcrumbs = computed(() => {
if (notExist) { if (notExist) {
exists.push(item.menuName) exists.push(item.menuName)
} }
return notExist return notExist && !item.menuName.endsWith('Base')
}) })
}) })
</script> </script>

View File

@@ -20,16 +20,24 @@ const props = defineProps({
model: { model: {
type: Object, type: Object,
required: true required: true
},
labelWidth: {
type: String,
default: null
} }
}) })
const inputType = computed(() => useInputType(props.option)) const inputType = computed(() => useInputType(props.option))
const modelAttrs = computed(() => { const modelAttrs = computed(() => {
const attrs = { ...props.option.attrs } const option = props.option
if (attrs.clearable === undefined && ['el-input', 'el-select', 'common-autocomplete', 'el-autocomplete', 'el-cascader', 'el-tree-select'].includes(inputType.value)) { const attrs = { ...option.attrs }
if (attrs.clearable === undefined && ['el-input', 'el-select', 'el-select-v2', 'common-autocomplete', 'el-autocomplete', 'el-cascader', 'el-tree-select'].includes(inputType.value)) {
attrs.clearable = true attrs.clearable = true
} }
if (inputType.value === 'common-autocomplete' && option.getAutocompleteLabel) {
attrs.defaultLabel = option.getAutocompleteLabel(props.model, option)
}
return attrs return attrs
}) })
@@ -41,6 +49,10 @@ const label = computed(() => {
return option.label return option.label
}) })
const showLabel = computed(() => {
return props.option.showLabel !== false && props.labelWidth !== '0'
})
const formModel = computed(() => props.option.model || props.model) const formModel = computed(() => props.option.model || props.model)
const modelValue = computed({ const modelValue = computed({
@@ -105,7 +117,7 @@ const initFormModel = () => {
const option = props.option const option = props.option
if (option.prop) { if (option.prop) {
const defaultVal = get(formModel.value, option.prop) const defaultVal = get(formModel.value, option.prop)
set(formModel.value, option.prop, defaultVal || option.value || undefined) set(formModel.value, option.prop, defaultVal ?? option.value ?? undefined)
} }
} }
} }
@@ -114,15 +126,36 @@ initFormModel()
watch(() => props.option, initFormModel, { deep: true }) watch(() => props.option, initFormModel, { deep: true })
const hasModelText = computed(() => {
return !!(modelAttrs.value.modelText || modelAttrs.value.modelTextFunc)
})
const emit = defineEmits(['change'])
const controlChange = (...args) => {
const option = props.option
if (option.change) {
option.change(...args)
}
emit('change', ...args)
}
const formItemEnabled = computed(() => props.option.enabled !== false)
</script> </script>
<template> <template>
<el-form-item <el-form-item
v-if="formItemEnabled"
ref="formItemRef" ref="formItemRef"
:rules="rules" :rules="rules"
:prop="option.prop" :prop="option.prop"
:label-width="labelWidth"
> >
<template #label> <template
v-if="showLabel"
#label
>
<span>{{ label }}</span> <span>{{ label }}</span>
<el-tooltip <el-tooltip
v-if="option.tooltip||option.tooltipFunc" v-if="option.tooltip||option.tooltipFunc"
@@ -151,8 +184,14 @@ watch(() => props.option, initFormModel, { deep: true })
:placeholder="option.placeholder" :placeholder="option.placeholder"
:disabled="option.disabled" :disabled="option.disabled"
:readonly="option.readonly" :readonly="option.readonly"
@change="option.change" @change="controlChange"
> >
<template
v-if="hasModelText"
#default
>
{{ modelAttrs.modelText || modelAttrs.modelTextFunc(modelValue) }}
</template>
<template v-if="children&&children.length"> <template v-if="children&&children.length">
<control-child <control-child
v-for="(childItem, index) in children" v-for="(childItem, index) in children"

View File

@@ -11,11 +11,13 @@ const props = defineProps({
*/ */
options: { options: {
type: Array, type: Array,
required: true default () {
return []
}
}, },
labelWidth: { labelWidth: {
type: String, type: String,
default: '100px' default: '110px'
}, },
model: { model: {
type: Object, type: Object,
@@ -94,6 +96,7 @@ defineExpose({
:model="formModel" :model="formModel"
/> />
<common-form-control <common-form-control
v-if="option.enabled!==false"
:model="formModel" :model="formModel"
:option="option" :option="option"
/> />

View File

@@ -35,7 +35,7 @@ const menuCls = computed(() => {
}) })
const dropdownClick = (menuItem, $event) => { const dropdownClick = (menuItem, $event) => {
if (menuItem.click) { if (menuItem.click) {
menuItem.click(router, $event) menuItem.click($event)
} else { } else {
const route = menuItem.route || menuItem.index const route = menuItem.route || menuItem.index
if (route) { if (route) {
@@ -85,7 +85,7 @@ const dropdownClick = (menuItem, $event) => {
v-else-if="isDropdown" v-else-if="isDropdown"
:key="menuItem.index||index" :key="menuItem.index||index"
:class="menuCls" :class="menuCls"
@click="menuItem.click&&menuItem.click(router, $event)" @click="menuItem.click&&menuItem.click($event)"
> >
<el-dropdown class="common-dropdown"> <el-dropdown class="common-dropdown">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
@@ -120,7 +120,7 @@ const dropdownClick = (menuItem, $event) => {
:route="menuItem.route" :route="menuItem.route"
v-bind="menuItem.attrs" v-bind="menuItem.attrs"
:index="menuItem.index" :index="menuItem.index"
@click="menuItem.click&&menuItem.click(router, $event)" @click="menuItem.click&&menuItem.click(menuItem, $event)"
> >
<common-icon <common-icon
:size="menuItem.iconSize" :size="menuItem.iconSize"

View File

@@ -1,4 +1,8 @@
<script setup> <script setup>
import { formatDate } from '@/components/utils'
import { computed } from 'vue'
import { get } from 'lodash'
/** /**
* 配置信息 * 配置信息
* @type {CommonTableColumnProps} * @type {CommonTableColumnProps}
@@ -20,6 +24,21 @@ const props = defineProps({
} }
}) })
const formatter = computed(() => {
const column = props.column
if (!column.formatter && column.dateFormat) { // 没有formatter但是有dateFormat
return row => {
const data = getPropertyData(row)
return formatDate(data, column.dateFormat)
}
}
return column.formatter
})
const getPropertyData = (row) => {
return get(row, props.column.property)
}
</script> </script>
<template> <template>
@@ -29,7 +48,7 @@ const props = defineProps({
:prop="column.prop||column.property" :prop="column.prop||column.property"
:width="column.width" :width="column.width"
v-bind="column.attrs" v-bind="column.attrs"
:formatter="column.formatter" :formatter="formatter"
> >
<template <template
v-if="column.slot||column.click" v-if="column.slot||column.click"
@@ -41,7 +60,7 @@ const props = defineProps({
v-bind="column.linkAttrs" v-bind="column.linkAttrs"
@click="column.click(scope.row, scope)" @click="column.click(scope.row, scope)"
> >
{{ column.formatter?column.formatter(scope.row, scope):scope.row[column.property] }} {{ formatter?formatter(scope.row, scope):getPropertyData(scope.row) }}
</el-link> </el-link>
<slot <slot
v-bind="scope" v-bind="scope"

View File

@@ -102,7 +102,7 @@ const calcColumns = computed(() => {
} }
_columns = [..._columns, buttonColumn] _columns = [..._columns, buttonColumn]
} }
return _columns return _columns.filter(column => column.enabled !== false)
}) })
const emit = defineEmits(['pageSizeChange', 'currentPageChange', 'update:page']) const emit = defineEmits(['pageSizeChange', 'currentPageChange', 'update:page'])
@@ -127,7 +127,7 @@ defineExpose({
<template> <template>
<el-container <el-container
v-loading="loading" v-loading="loading"
class="no_flex" class="flex-column"
:element-loading-text="loadingText" :element-loading-text="loadingText"
> >
<el-table <el-table
@@ -160,7 +160,7 @@ defineExpose({
</common-table-column> </common-table-column>
</el-table> </el-table>
<el-pagination <el-pagination
v-if="page&&page.pageCount&&page.pageCount>1" v-if="page&&page.pageCount"
class="common-pagination" class="common-pagination"
v-bind="pageAttrs" v-bind="pageAttrs"
:total="page.totalCount" :total="page.totalCount"

View File

@@ -2,10 +2,12 @@ import CommonIcon from '@/components/common-icon/index.vue'
import CommonIconSelect from '@/components/common-icon-select/index.vue' import CommonIconSelect from '@/components/common-icon-select/index.vue'
import CommonForm from '@/components/common-form/index.vue' import CommonForm from '@/components/common-form/index.vue'
import CommonFormControl from '@/components/common-form-control/index.vue' import CommonFormControl from '@/components/common-form-control/index.vue'
import CommonFormLabel from '@/components/common-form-control/common-form-label.vue'
import CommonMenu from '@/components/common-menu/index.vue' import CommonMenu from '@/components/common-menu/index.vue'
import CommonMenuItem from '@/components/common-menu-item/index.vue' import CommonMenuItem from '@/components/common-menu-item/index.vue'
import CommonTabsView from '@/components/common-tabs-view/index.vue' import CommonTabsView from '@/components/common-tabs-view/index.vue'
import CommonTable from '@/components/common-table/index.vue' import CommonTable from '@/components/common-table/index.vue'
import CommonTableForm from '@/components/common-table-form/index.vue'
import CommonBreadcrumb from '@/components/common-breadcrumb/index.vue' import CommonBreadcrumb from '@/components/common-breadcrumb/index.vue'
import CommonWindow from '@/components/common-window/index.vue' import CommonWindow from '@/components/common-window/index.vue'
import CommonAutocomplete from '@/components/common-autocomplete/index.vue' import CommonAutocomplete from '@/components/common-autocomplete/index.vue'
@@ -22,10 +24,12 @@ export default {
Vue.component('CommonIconSelect', CommonIconSelect) Vue.component('CommonIconSelect', CommonIconSelect)
Vue.component('CommonForm', CommonForm) Vue.component('CommonForm', CommonForm)
Vue.component('CommonFormControl', CommonFormControl) Vue.component('CommonFormControl', CommonFormControl)
Vue.component('CommonFormLabel', CommonFormLabel)
Vue.component('CommonMenu', CommonMenu) Vue.component('CommonMenu', CommonMenu)
Vue.component('CommonMenuItem', CommonMenuItem) Vue.component('CommonMenuItem', CommonMenuItem)
Vue.component('CommonTabsView', CommonTabsView) Vue.component('CommonTabsView', CommonTabsView)
Vue.component('CommonTable', CommonTable) Vue.component('CommonTable', CommonTable)
Vue.component('CommonTableForm', CommonTableForm)
Vue.component('CommonBreadcrumb', CommonBreadcrumb) Vue.component('CommonBreadcrumb', CommonBreadcrumb)
Vue.component('CommonWindow', CommonWindow) Vue.component('CommonWindow', CommonWindow)
Vue.component('CommonAutocomplete', CommonAutocomplete) Vue.component('CommonAutocomplete', CommonAutocomplete)

View File

@@ -1,5 +1,6 @@
import { ref } from 'vue' import { ref } from 'vue'
import { $i18nBundle } from '@/messages' import { $i18nBundle } from '@/messages'
import dayjs from 'dayjs'
const calcWithIf = menuItem => { const calcWithIf = menuItem => {
['icon', 'labelKey', 'label', 'html'].forEach(key => { ['icon', 'labelKey', 'label', 'html'].forEach(key => {
@@ -73,3 +74,15 @@ export const useParentRoute = function (route) {
} }
return route return route
} }
export const formatDate = (date, format) => {
if (date) {
return dayjs(date).format(format || 'YYYY-MM-DD HH:mm:ss')
}
}
export const formatDay = (date, format) => {
if (date) {
return dayjs(date).format(format || 'YYYY-MM-DD')
}
}

View File

@@ -7,7 +7,7 @@ const globalConfigStore = useGlobalConfigStore()
const menuConfigStore = useMenuConfigStore() const menuConfigStore = useMenuConfigStore()
const allMenus = computed(() => { const allMenus = computed(() => {
const topMenus = menuConfigStore.loadBaseTopMenus() const topMenus = menuConfigStore.loadBaseTopMenus().value
const businessMenus = menuConfigStore.calcBusinessMenus() const businessMenus = menuConfigStore.calcBusinessMenus()
if (globalConfigStore.layoutMode === GlobalLayoutMode.TOP) { if (globalConfigStore.layoutMode === GlobalLayoutMode.TOP) {
return [...businessMenus, ...topMenus.slice(1)] return [...businessMenus, ...topMenus.slice(1)]

View File

@@ -27,8 +27,8 @@ export const loadAutoCities = (data, config) => {
*/ */
export const useCityAutocompleteConfig = () => { export const useCityAutocompleteConfig = () => {
return { return {
idKey: 'code', idProp: 'code',
labelKey: $i18nMsg('nameCn', 'nameEn'), labelProp: $i18nMsg('nameCn', 'nameEn'),
columns: [{ columns: [{
label: $i18nMsg('代码', 'Code'), label: $i18nMsg('代码', 'Code'),
property: 'code' property: 'code'

View File

@@ -10,7 +10,7 @@ export const useMenuConfigStore = defineStore('menuConfig', () => {
return { return {
businessMenus, businessMenus,
loadBaseTopMenus () { loadBaseTopMenus () {
return useBaseTopMenus() return ref(useBaseTopMenus())
}, },
async loadBusinessMenus () { async loadBusinessMenus () {
businessMenus.value = await loadAndParseMenus() businessMenus.value = await loadAndParseMenus()

View File

@@ -13,7 +13,6 @@ const tabsViewStore = useTabsViewStore()
const showLeftMenu = computed(() => { const showLeftMenu = computed(() => {
return globalConfigStore.layoutMode === GlobalLayoutMode.LEFT return globalConfigStore.layoutMode === GlobalLayoutMode.LEFT
}) })
menuConfigStore.loadBaseTopMenus()
menuConfigStore.loadBusinessMenus() menuConfigStore.loadBusinessMenus()
</script> </script>

View File

@@ -82,7 +82,7 @@ const doSearch = form => {
<template> <template>
<el-container <el-container
class="no_flex" class="flex-column"
> >
<common-form <common-form
inline inline

View File

@@ -130,7 +130,7 @@ const submitForm = () => {
<template> <template>
<el-container <el-container
class="no_flex" class="flex-column"
> >
<common-form <common-form
inline inline