feat: 新增业务组件

This commit is contained in:
xlsea 2024-09-11 17:34:31 +08:00
parent 9cbbaff297
commit 0a62e4dcaa
6 changed files with 107 additions and 70 deletions

View File

@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
defineOptions({ defineOptions({
name: 'TableColumnCheckAlert' name: 'TableRowCheckAlert'
}); });
const checkedRowKeys = defineModel<CommonType.IdType[]>('columns', { required: true }); const checkedRowKeys = defineModel<CommonType.IdType[]>('checkedRowKeys', { required: true });
</script> </script>
<template> <template>

View File

@ -7,16 +7,17 @@ defineOptions({
interface Props { interface Props {
defaultExpanded?: boolean; defaultExpanded?: boolean;
siderTitle?: string;
} }
withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {
defaultExpanded: false defaultExpanded: false,
siderTitle: undefined
}); });
const time = new Date().getTime(); const time = new Date().getTime();
const breakpoints = useBreakpoints(breakpointsTailwind); const breakpoints = useBreakpoints(breakpointsTailwind);
const isCollapse = breakpoints.smaller('lg'); const isCollapse = breakpoints.smaller('lg');
const title = defineModel<string>('title');
</script> </script>
<template> <template>
@ -36,11 +37,11 @@ const title = defineModel<string>('title');
content-class="sider-layout-card-content" content-class="sider-layout-card-content"
> >
<NCollapse v-if="isCollapse" :default-expanded-names="defaultExpanded ? [`table-sider-layout${time}`] : []"> <NCollapse v-if="isCollapse" :default-expanded-names="defaultExpanded ? [`table-sider-layout${time}`] : []">
<NCollapseItem :title="title" :name="`table-sider-layout${time}`" display-directive="show"> <NCollapseItem :title="siderTitle" :name="`table-sider-layout${time}`" display-directive="show">
<slot name="sider" /> <slot name="sider" />
<template #header> <template #header>
<slot name="header"> <slot name="header">
<span>{{ title }}</span> <span>{{ siderTitle }}</span>
</slot> </slot>
</template> </template>
<template #header-extra> <template #header-extra>
@ -65,7 +66,7 @@ const title = defineModel<string>('title');
<slot name="sider" /> <slot name="sider" />
<template #header> <template #header>
<slot name="header"> <slot name="header">
<span>{{ title }}</span> <span>{{ siderTitle }}</span>
</slot> </slot>
</template> </template>
<template #header-extra> <template #header-extra>

View File

@ -0,0 +1,61 @@
<script setup lang="ts">
import { useBoolean } from '@sa/hooks';
import { enableStatusRecord } from '@/constants/business';
defineOptions({
name: 'StatusSwitch'
});
interface Props {
disabled?: boolean;
info?: string;
}
const props = withDefaults(defineProps<Props>(), {
disabled: false,
info: ''
});
const value = defineModel<Api.Common.EnableStatus>('value', { default: '0' });
interface Emits {
(e: 'submitted', value: Api.Common.EnableStatus, callback: (flag: boolean) => void): void;
}
const emit = defineEmits<Emits>();
/** 状态切换过程的 loading 状态 */
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean();
const handleUpdateValue = (val: Api.Common.EnableStatus) => {
value.value = val === '0' ? '1' : '0';
window.$dialog?.warning({
title: '系统提示',
content: `确定要${enableStatusRecord[val]} ${props.info} 吗?`,
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
startLoading();
emit('submitted', val, flag => {
if (flag) value.value = val;
endLoading();
});
},
onNegativeClick: () => {}
});
};
</script>
<template>
<NSwitch
v-model:value="value"
:loading="loading"
:rubber-band="false"
checked-value="1"
unchecked-value="0"
:disabled="props.disabled"
@update:value="handleUpdateValue"
/>
</template>
<style scoped></style>

View File

@ -1,31 +0,0 @@
<script setup lang="ts">
import type { TagProps } from 'naive-ui';
import { useAttrs } from 'vue';
import { enableStatusRecord } from '@/constants/business';
import { isNotNull } from '@/utils/common';
defineOptions({
name: 'StatusTag'
});
interface Props {
[key: string]: any;
}
defineProps<Props>();
const status = defineModel<Api.Common.EnableStatus>('value', { required: true });
const tagMap: Record<Api.Common.EnableStatus, NaiveUI.ThemeColor> = {
'0': 'success',
'1': 'warning'
};
const attrs: TagProps = useAttrs();
</script>
<template>
<NTag v-if="isNotNull(status)" :type="tagMap[status]" v-bind="attrs">{{ enableStatusRecord[status] }}</NTag>
</template>
<style scoped></style>

View File

@ -114,12 +114,15 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
SoybeanAvatar: typeof import('./../components/custom/soybean-avatar.vue')['default'] SoybeanAvatar: typeof import('./../components/custom/soybean-avatar.vue')['default']
StatusSwitch: typeof import('./../components/custom/status-switch.vue')['default']
StatusTag: typeof import('./../components/custom/status-tag.vue')['default'] StatusTag: typeof import('./../components/custom/status-tag.vue')['default']
SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default'] SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default']
SystemLogo: typeof import('./../components/common/system-logo.vue')['default'] SystemLogo: typeof import('./../components/common/system-logo.vue')['default']
TableCheckAlert: typeof import('./../components/common/table-check-alert.vue')['default']
TableColumnCheckAlert: typeof import('./../components/advanced/table-column-check-alert.vue')['default'] TableColumnCheckAlert: typeof import('./../components/advanced/table-column-check-alert.vue')['default']
TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default'] TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default']
TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default'] TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default']
TableRowCheckAlert: typeof import('./../components/advanced/table-row-check-alert.vue')['default']
TableSiderLayout: typeof import('./../components/advanced/table-sider-layout.vue')['default'] TableSiderLayout: typeof import('./../components/advanced/table-sider-layout.vue')['default']
ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default'] ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default']
WaveBg: typeof import('./../components/custom/wave-bg.vue')['default'] WaveBg: typeof import('./../components/custom/wave-bg.vue')['default']

View File

@ -146,40 +146,43 @@ async function edit(userId: CommonType.IdType) {
</script> </script>
<template> <template>
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto"> <TableSiderLayout sider-title="部门列表">
<UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" /> <div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
<NCard title="用户列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper"> <UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
<template #header-extra> <TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
<TableHeaderOperation <NCard title="用户列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
v-model:columns="columnChecks" <template #header-extra>
:disabled-delete="checkedRowKeys.length === 0" <TableHeaderOperation
v-model:columns="columnChecks"
:disabled-delete="checkedRowKeys.length === 0"
:loading="loading"
@add="handleAdd"
@delete="handleBatchDelete"
@refresh="getData"
/>
</template>
<NDataTable
v-model:checked-row-keys="checkedRowKeys"
:columns="columns"
:data="data"
size="small"
:flex-height="!appStore.isMobile"
:scroll-x="962"
:loading="loading" :loading="loading"
@add="handleAdd" remote
@delete="handleBatchDelete" :row-key="row => row.userId"
@refresh="getData" :pagination="mobilePagination"
class="h-full"
/> />
</template> <UserOperateDrawer
<NDataTable v-model:visible="drawerVisible"
v-model:checked-row-keys="checkedRowKeys" :operate-type="operateType"
:columns="columns" :row-data="editingData"
:data="data" @submitted="getDataByPage"
size="small" />
:flex-height="!appStore.isMobile" </NCard>
:scroll-x="962" </div>
:loading="loading" </TableSiderLayout>
remote
:row-key="row => row.userId"
:pagination="mobilePagination"
class="sm:h-full"
/>
<UserOperateDrawer
v-model:visible="drawerVisible"
:operate-type="operateType"
:row-data="editingData"
@submitted="getDataByPage"
/>
</NCard>
</div>
</template> </template>
<style scoped></style> <style scoped></style>