feat: 布局调整&卡片组件调整

This commit is contained in:
baiqi 2023-07-27 14:57:31 +08:00 committed by 刘瑞斌
parent 8be2a18195
commit 5bd61bf764
5 changed files with 178 additions and 155 deletions

View File

@ -1,18 +1,26 @@
<template> <template>
<a-spin class="block h-full" :loading="props.loading" :size="28"> <a-spin class="block h-full" :loading="props.loading" :size="28">
<div class="ms-card relative h-full pr-[10px]"> <div
:class="[
'ms-card',
'relative',
'h-full',
props.autoHeight ? '' : 'min-h-[500px]',
props.noContentPadding ? 'ms-card--noContentPadding' : 'p-[24px]',
]"
>
<div v-if="!props.simple" class="card-header"> <div v-if="!props.simple" class="card-header">
<div v-if="!props.hideBack" class="back-btn" @click="back"><icon-arrow-left /></div> <div v-if="!props.hideBack" class="back-btn" @click="back"><icon-arrow-left /></div>
<div class="text-[var(--color-text-000)]">{{ props.title }}</div> <div class="text-[var(--color-text-000)]">{{ props.title }}</div>
</div> </div>
<a-divider v-if="!props.simple" class="mb-[16px]" /> <a-divider v-if="!props.simple" class="mb-[16px]" />
<div class="mr-[-10px]"> <div class="ms-card-container">
<a-scrollbar <a-scrollbar
class="pr-[10px]" class="pr-[5px]"
:style="{ :style="{
overflowY: 'auto', overflowY: 'auto',
minWidth: 1000, minWidth: 1000,
height: `calc(100vh - ${cardOverHeight}px)`, height: props.autoHeight ? 'auto' : `calc(100vh - ${cardOverHeight}px)`,
}" }"
> >
<slot></slot> <slot></slot>
@ -49,15 +57,18 @@
const props = withDefaults( const props = withDefaults(
defineProps< defineProps<
Partial<{ Partial<{
simple: boolean; simple: boolean; //
title: string; title: string; //
hideContinue: boolean; hideContinue: boolean; //
hideFooter: boolean; hideFooter: boolean; //
loading: boolean; loading: boolean; // loading
isEdit: boolean; isEdit: boolean; //
specialHeight: number; // specialHeight: number; //
hideBack: boolean; hideBack: boolean; //
handleBack: () => void; autoHeight: boolean; //
hasBreadcrumb: boolean; //
noContentPadding: boolean; // padding
handleBack: () => void; //
}> }>
>(), >(),
{ {
@ -67,6 +78,9 @@
isEdit: false, isEdit: false,
specialHeight: 0, specialHeight: 0,
hideBack: false, hideBack: false,
autoHeight: false,
hasBreadcrumb: false,
noContentPadding: false,
} }
); );
@ -75,16 +89,18 @@
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
const _spcialHeight = props.hasBreadcrumb ? 31 + props.specialHeight : props.specialHeight; // 31
const cardOverHeight = computed(() => { const cardOverHeight = computed(() => {
if (props.simple) { if (props.simple) {
// //
return 163; return 136 + _spcialHeight;
} }
if (props.hideFooter) { if (props.hideFooter) {
// //
return 192; return 192;
} }
return 256 + props.specialHeight; return 246 + _spcialHeight;
}); });
function back() { function back() {
@ -98,6 +114,22 @@
<style lang="less" scoped> <style lang="less" scoped>
.ms-card { .ms-card {
@apply overflow-hidden bg-white;
border-radius: var(--border-radius-large);
box-shadow: 0 0 10px rgb(120 56 135 / 5%);
&--noContentPadding {
border-radius: var(--border-radius-large) var(--border-radius-large) 0 0;
.card-header {
padding: 24px 24px 0;
}
.arco-divider {
@apply mb-0;
}
.ms-card-container {
padding: 0;
}
}
.card-header { .card-header {
@apply flex items-center; @apply flex items-center;
.back-btn { .back-btn {

View File

@ -14,12 +14,4 @@
<script lang="ts" setup></script> <script lang="ts" setup></script>
<style lang="less" scoped> <style lang="less" scoped></style>
.page-content {
@apply overflow-hidden bg-white;
padding: 24px 14px 24px 24px;
border-radius: var(--border-radius-large);
box-shadow: 0 0 10px rgb(120 56 135 / 5%);
}
</style>

View File

@ -3,7 +3,7 @@
:loading="loading" :loading="loading"
:title="title" :title="title"
:is-edit="isEdit" :is-edit="isEdit"
:special-height="34" has-breadcrumb
@save="beforeSave" @save="beforeSave"
@save-and-continue="beforeSave(true)" @save-and-continue="beforeSave(true)"
> >

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<MsCard :loading="loading" simple> <MsCard :loading="loading" has-breadcrumb simple>
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<a-button type="primary" @click="addPool"> <a-button type="primary" @click="addPool">
{{ t('system.resourcePool.createPool') }} {{ t('system.resourcePool.createPool') }}

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <MsCard simple>
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<div> <div>
<a-button class="mr-3" type="primary" @click="showUserModal('create')"> <a-button class="mr-3" type="primary" @click="showUserModal('create')">
@ -84,136 +84,134 @@
</template> </template>
</template> </template>
</ms-base-table> </ms-base-table>
<a-modal </MsCard>
v-model:visible="visible" <a-modal
:title="userFormMode === 'create' ? t('system.user.createUserModalTitle') : t('system.user.editUserModalTitle')" v-model:visible="visible"
title-align="start" :title="userFormMode === 'create' ? t('system.user.createUserModalTitle') : t('system.user.editUserModalTitle')"
class="ms-modal-form ms-modal-medium" title-align="start"
:mask-closable="false" class="ms-modal-form ms-modal-medium"
@close="handleUserModalClose" :mask-closable="false"
> @close="handleUserModalClose"
<a-form ref="userFormRef" class="rounded-[4px]" :model="userForm" layout="vertical"> >
<MsBatchForm <a-form ref="userFormRef" class="rounded-[4px]" :model="userForm" layout="vertical">
ref="batchFormRef" <MsBatchForm
:models="batchFormModels" ref="batchFormRef"
:form-mode="userFormMode" :models="batchFormModels"
add-text="system.user.addUser" :form-mode="userFormMode"
:default-vals="userForm.list" add-text="system.user.addUser"
max-height="250px" :default-vals="userForm.list"
></MsBatchForm> max-height="250px"
<a-form-item class="mb-0" field="userGroup" :label="t('system.user.createUserUserGroup')"> ></MsBatchForm>
<a-select <a-form-item class="mb-0" field="userGroup" :label="t('system.user.createUserUserGroup')">
v-model="userForm.userGroup" <a-select
multiple v-model="userForm.userGroup"
:placeholder="t('system.user.createUserUserGroupPlaceholder')" multiple
allow-clear :placeholder="t('system.user.createUserUserGroupPlaceholder')"
> allow-clear
<a-option
v-for="item of userGroupOptions"
:key="item.id"
:tag-props="{ closable: item.closeable }"
:value="item.id"
:disabled="item.selected"
>
{{ item.name }}
</a-option>
</a-select>
</a-form-item>
</a-form>
<template #footer>
<a-button type="secondary" :disabled="loading" @click="cancelCreate">
{{ t('system.user.editUserModalCancelCreate') }}
</a-button>
<a-button v-if="userFormMode === 'create'" type="secondary" :loading="loading" @click="saveAndContinue">
{{ t('system.user.editUserModalSaveAndContinue') }}
</a-button>
<a-button type="primary" :loading="loading" @click="beforeCreateUser">
{{
t(userFormMode === 'create' ? 'system.user.editUserModalCreateUser' : 'system.user.editUserModalEditUser')
}}
</a-button>
</template>
</a-modal>
<a-modal
v-model:visible="importVisible"
:title="t('system.user.importModalTitle')"
title-align="start"
class="ms-modal-upload"
>
<a-alert class="mb-[16px]" closable>
{{ t('system.user.importModalTip') }}
<a-button type="text" size="small" @click="downLoadUserTemplate">
{{ t('system.user.importDownload') }}
</a-button>
</a-alert>
<MsUpload
v-model:file-list="userImportFile"
accept="excel"
:show-file-list="false"
:auto-upload="false"
:disabled="importLoading"
></MsUpload>
<template #footer>
<a-button type="secondary" :disabled="importLoading" @click="cancelImport">
{{ t('system.user.importModalCancel') }}
</a-button>
<a-button type="primary" :loading="importLoading" :disabled="userImportFile.length === 0" @click="importUser">
{{ t('system.user.importModalConfirm') }}
</a-button>
</template>
</a-modal>
<a-modal v-model:visible="importResultVisible" title-align="start" class="ms-modal-upload">
<template #title>
<icon-exclamation-circle-fill
v-if="importResult === 'fail'"
class="mr-[8px] text-[20px] text-[rgb(var(--warning-6))]"
/>
<icon-close-circle-fill
v-if="importResult === 'allFail'"
class="mr-[8px] text-[20px] text-[rgb(var(--danger-6))]"
/>
{{ importResultTitle }}
</template>
<div v-if="importResult === 'success'" class="flex flex-col items-center justify-center">
<icon-check-circle-fill class="text-[32px] text-[rgb(var(--success-6))]" />
<div class="mb-[8px] mt-[16px] text-[16px] font-medium text-[var(--color-text-000)]">
{{ t('system.user.importSuccess') }}
</div>
<div class="sub-text">
{{ t('system.user.importResultSuccessContent', { successNum: importSuccessCount }) }}
</div>
</div>
<template v-else>
<div>
{{ t('system.user.importResultContent', { successNum: importSuccessCount, failNum: importFailCount }) }}
</div>
<div>
{{ t('system.user.importResultContentSubStart') }}
<a-link
class="text-[rgb(var(--primary-5))]"
:href="importErrorFileUrl"
:download="`${t('system.user.importErrorFile')}.pdf`"
>{{ t('system.user.importResultContentDownload') }}</a-link
>{{ t('system.user.importResultContentSubEnd') }}</div
> >
</template> <a-option
<template #footer> v-for="item of userGroupOptions"
<a-button type="text" class="!text-[var(--color-text-1)]" @click="cancelImport"> :key="item.id"
{{ t('system.user.importResultReturn') }} :tag-props="{ closable: item.closeable }"
</a-button> :value="item.id"
<a-button type="text" @click="continueImport"> :disabled="item.selected"
{{ t('system.user.importResultContinue') }} >
</a-button> {{ item.name }}
</template> </a-option>
</a-modal> </a-select>
<inviteModal v-model:visible="inviteVisible"></inviteModal> </a-form-item>
<batchModal </a-form>
v-model:visible="showBatchModal" <template #footer>
:table-selected="tableSelected" <a-button type="secondary" :disabled="loading" @click="cancelCreate">
:action="batchAction" {{ t('system.user.editUserModalCancelCreate') }}
:tree-data="treeData" </a-button>
></batchModal> <a-button v-if="userFormMode === 'create'" type="secondary" :loading="loading" @click="saveAndContinue">
</div> {{ t('system.user.editUserModalSaveAndContinue') }}
</a-button>
<a-button type="primary" :loading="loading" @click="beforeCreateUser">
{{ t(userFormMode === 'create' ? 'system.user.editUserModalCreateUser' : 'system.user.editUserModalEditUser') }}
</a-button>
</template>
</a-modal>
<a-modal
v-model:visible="importVisible"
:title="t('system.user.importModalTitle')"
title-align="start"
class="ms-modal-upload"
>
<a-alert class="mb-[16px]" closable>
{{ t('system.user.importModalTip') }}
<a-button type="text" size="small" @click="downLoadUserTemplate">
{{ t('system.user.importDownload') }}
</a-button>
</a-alert>
<MsUpload
v-model:file-list="userImportFile"
accept="excel"
:show-file-list="false"
:auto-upload="false"
:disabled="importLoading"
></MsUpload>
<template #footer>
<a-button type="secondary" :disabled="importLoading" @click="cancelImport">
{{ t('system.user.importModalCancel') }}
</a-button>
<a-button type="primary" :loading="importLoading" :disabled="userImportFile.length === 0" @click="importUser">
{{ t('system.user.importModalConfirm') }}
</a-button>
</template>
</a-modal>
<a-modal v-model:visible="importResultVisible" title-align="start" class="ms-modal-upload">
<template #title>
<icon-exclamation-circle-fill
v-if="importResult === 'fail'"
class="mr-[8px] text-[20px] text-[rgb(var(--warning-6))]"
/>
<icon-close-circle-fill
v-if="importResult === 'allFail'"
class="mr-[8px] text-[20px] text-[rgb(var(--danger-6))]"
/>
{{ importResultTitle }}
</template>
<div v-if="importResult === 'success'" class="flex flex-col items-center justify-center">
<icon-check-circle-fill class="text-[32px] text-[rgb(var(--success-6))]" />
<div class="mb-[8px] mt-[16px] text-[16px] font-medium text-[var(--color-text-000)]">
{{ t('system.user.importSuccess') }}
</div>
<div class="sub-text">
{{ t('system.user.importResultSuccessContent', { successNum: importSuccessCount }) }}
</div>
</div>
<template v-else>
<div>
{{ t('system.user.importResultContent', { successNum: importSuccessCount, failNum: importFailCount }) }}
</div>
<div>
{{ t('system.user.importResultContentSubStart') }}
<a-link
class="text-[rgb(var(--primary-5))]"
:href="importErrorFileUrl"
:download="`${t('system.user.importErrorFile')}.pdf`"
>{{ t('system.user.importResultContentDownload') }}</a-link
>{{ t('system.user.importResultContentSubEnd') }}</div
>
</template>
<template #footer>
<a-button type="text" class="!text-[var(--color-text-1)]" @click="cancelImport">
{{ t('system.user.importResultReturn') }}
</a-button>
<a-button type="text" @click="continueImport">
{{ t('system.user.importResultContinue') }}
</a-button>
</template>
</a-modal>
<inviteModal v-model:visible="inviteVisible"></inviteModal>
<batchModal
v-model:visible="showBatchModal"
:table-selected="tableSelected"
:action="batchAction"
:tree-data="treeData"
></batchModal>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -248,6 +246,7 @@
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import type { SimpleUserInfo, SystemRole, UserListItem } from '@/models/setting/user'; import type { SimpleUserInfo, SystemRole, UserListItem } from '@/models/setting/user';
import type { FormItemModel, MsBatchFormInstance } from '@/components/bussiness/ms-batch-form/types'; import type { FormItemModel, MsBatchFormInstance } from '@/components/bussiness/ms-batch-form/types';
import MsCard from '@/components/pure/ms-card/index.vue';
const { t } = useI18n(); const { t } = useI18n();