界面样式调整
parent
1b8c1bc0ef
commit
9e579d589b
2
.env
2
.env
|
|
@ -1,5 +1,5 @@
|
||||||
# 标题
|
# 标题
|
||||||
VITE_APP_TITLE=智慧小区管理后台
|
VITE_APP_TITLE=智慧小区平台
|
||||||
|
|
||||||
# 项目本地运行端口号
|
# 项目本地运行端口号
|
||||||
VITE_PORT=80
|
VITE_PORT=80
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,8 @@ $prefix-cls: #{$elNamespace}-breadcrumb;
|
||||||
color: var(--top-header-text-color);
|
color: var(--top-header-text-color);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--el-color-primary);
|
color: #fff;
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +111,8 @@ $prefix-cls: #{$elNamespace}-breadcrumb;
|
||||||
color: var(--top-header-text-color);
|
color: var(--top-header-text-color);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--el-color-primary);
|
color: #fff;
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -119,10 +121,10 @@ $prefix-cls: #{$elNamespace}-breadcrumb;
|
||||||
.#{$prefix-cls}__inner {
|
.#{$prefix-cls}__inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--el-text-color-placeholder);
|
color: rgba(255, 255, 255, 0.65);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--el-text-color-placeholder);
|
color: rgba(255, 255, 255, 0.65);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,12 @@ watch(
|
||||||
]"
|
]"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
<!-- <img-->
|
<div class="flex items-center justify-center w-[40px] h-[40px] rounded-md bg-white/10">
|
||||||
<!-- class="h-[calc(var(--logo-height)-10px)] w-[calc(var(--logo-height)-10px)]"-->
|
<svg viewBox="0 0 1024 1024" width="28" height="28" fill="white">
|
||||||
<!-- src="@/assets/imgs/logo.png"-->
|
<path d="M512 64L128 256v512l384 192 384-192V256L512 64zm0 72l304 152v448L512 888 208 736V288L512 136z"/>
|
||||||
<!-- />-->
|
<path d="M288 512h128l64-160 96 288 64-128h128" stroke="white" stroke-width="40" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:class="[
|
:class="[
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,13 @@ export default defineComponent({
|
||||||
class={[
|
class={[
|
||||||
prefixCls,
|
prefixCls,
|
||||||
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between',
|
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between',
|
||||||
'dark:bg-[var(--el-bg-color)]'
|
'bg-[#1677ff] text-white'
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{layout.value !== 'top' ? (
|
{layout.value !== 'top' ? (
|
||||||
<div class="h-full flex items-center">
|
<div class="h-full flex items-center">
|
||||||
{hamburger.value && layout.value !== 'cutMenu' ? (
|
{hamburger.value && layout.value !== 'cutMenu' ? (
|
||||||
<Collapse class="custom-hover" color="var(--top-header-text-color)"></Collapse>
|
<Collapse class="custom-hover" color="#fff"></Collapse>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{breadcrumb.value ? <Breadcrumb class="lt-md:hidden"></Breadcrumb> : undefined}
|
{breadcrumb.value ? <Breadcrumb class="lt-md:hidden"></Breadcrumb> : undefined}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -71,20 +71,20 @@ export default defineComponent({
|
||||||
<div class="h-full flex items-center">
|
<div class="h-full flex items-center">
|
||||||
{hasTenantVisitPermission.value ? <TenantVisit /> : undefined}
|
{hasTenantVisitPermission.value ? <TenantVisit /> : undefined}
|
||||||
{screenfull.value ? (
|
{screenfull.value ? (
|
||||||
<Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull>
|
<Screenfull class="custom-hover" color="#fff"></Screenfull>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{search.value ? <RouterSearch isModal={false} color="var(--top-header-text-color)"/> : undefined}
|
{search.value ? <RouterSearch isModal={false} color="#fff"/> : undefined}
|
||||||
{size.value ? (
|
{size.value ? (
|
||||||
<SizeDropdown class="custom-hover" color="var(--top-header-text-color)"></SizeDropdown>
|
<SizeDropdown class="custom-hover" color="#fff"></SizeDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{locale.value ? (
|
{locale.value ? (
|
||||||
<LocaleDropdown
|
<LocaleDropdown
|
||||||
class="custom-hover"
|
class="custom-hover"
|
||||||
color="var(--top-header-text-color)"
|
color="#fff"
|
||||||
></LocaleDropdown>
|
></LocaleDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{message.value ? (
|
{message.value ? (
|
||||||
<Message class="custom-hover" color="var(--top-header-text-color)"></Message>
|
<Message class="custom-hover" color="#fff"></Message>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<UserInfo></UserInfo>
|
<UserInfo></UserInfo>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -99,5 +99,20 @@ $prefix-cls: #{$namespace}-tool-header;
|
||||||
|
|
||||||
.#{$prefix-cls} {
|
.#{$prefix-cls} {
|
||||||
transition: left var(--transition-time-02);
|
transition: left var(--transition-time-02);
|
||||||
|
|
||||||
|
.custom-hover {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.layout-border__right) {
|
||||||
|
border-right: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ export const useRenderLayout = () => {
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
'absolute top-0 left-0 h-full layout-border__right',
|
'absolute top-0 left-0 h-full',
|
||||||
{ '!fixed z-3000': mobile.value }
|
{ '!fixed z-3000': mobile.value }
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{logo.value ? (
|
{logo.value ? (
|
||||||
<Logo
|
<Logo
|
||||||
class={[
|
class={[
|
||||||
'bg-[var(--left-menu-bg-color)] relative',
|
'bg-[#1677ff] relative',
|
||||||
{
|
{
|
||||||
'!pl-0': mobile.value && collapse.value,
|
'!pl-0': mobile.value && collapse.value,
|
||||||
'w-[var(--left-menu-min-width)]': appStore.getCollapse,
|
'w-[var(--left-menu-min-width)]': appStore.getCollapse,
|
||||||
|
|
@ -99,7 +99,7 @@ export const useRenderLayout = () => {
|
||||||
>
|
>
|
||||||
<ToolHeader
|
<ToolHeader
|
||||||
class={[
|
class={[
|
||||||
'bg-[var(--top-header-bg-color)]',
|
'bg-[#1677ff]',
|
||||||
{
|
{
|
||||||
'layout-border__bottom': !tagsView.value
|
'layout-border__bottom': !tagsView.value
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,31 +5,31 @@
|
||||||
|
|
||||||
--left-menu-min-width: 64px;
|
--left-menu-min-width: 64px;
|
||||||
|
|
||||||
--left-menu-bg-color: #001529;
|
--left-menu-bg-color: #ffffff !important;
|
||||||
|
|
||||||
--left-menu-bg-light-color: #0f2438;
|
--left-menu-bg-light-color: #f5f7fa !important;
|
||||||
|
|
||||||
--left-menu-bg-active-color: var(--el-color-primary);
|
--left-menu-bg-active-color: #e6f7ff !important;
|
||||||
|
|
||||||
--left-menu-text-color: #bfcbd9;
|
--left-menu-text-color: #333333 !important;
|
||||||
|
|
||||||
--left-menu-text-active-color: #fff;
|
--left-menu-text-active-color: #1677ff !important;
|
||||||
|
|
||||||
--left-menu-collapse-bg-active-color: var(--el-color-primary);
|
--left-menu-collapse-bg-active-color: #1677ff !important;
|
||||||
/* left menu end */
|
/* left menu end */
|
||||||
|
|
||||||
/* logo start */
|
/* logo start */
|
||||||
--logo-height: 50px;
|
--logo-height: 70px;
|
||||||
|
|
||||||
--logo-title-text-color: #fff;
|
--logo-title-text-color: #fff;
|
||||||
/* logo end */
|
/* logo end */
|
||||||
|
|
||||||
/* header start */
|
/* header start */
|
||||||
--top-header-bg-color: '#fff';
|
--top-header-bg-color: #1677ff !important;
|
||||||
|
|
||||||
--top-header-text-color: 'inherit';
|
--top-header-text-color: #fff !important;
|
||||||
|
|
||||||
--top-header-hover-color: #f6f6f6;
|
--top-header-hover-color: rgba(255, 255, 255, 0.2);
|
||||||
|
|
||||||
--top-tool-height: var(--logo-height);
|
--top-tool-height: var(--logo-height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="home-container">
|
||||||
<el-card shadow="never">
|
<!-- 欢迎区域 -->
|
||||||
|
<el-card shadow="never" class="welcome-card">
|
||||||
<el-skeleton :loading="loading" animated>
|
<el-skeleton :loading="loading" animated>
|
||||||
<el-row :gutter="16" justify="space-between">
|
<el-row :gutter="16" justify="space-between">
|
||||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||||
|
|
@ -10,10 +11,10 @@
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<div>
|
<div>
|
||||||
<div class="text-20px">
|
<div class="text-20px">
|
||||||
{{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
|
你好 {{ username }} 祝你开心每一天!
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-10px text-14px text-gray-500">
|
<div class="mt-10px text-14px text-gray-500">
|
||||||
{{ t('workplace.toady') }},20℃ - 32℃!
|
今日晴,20℃ - 32℃!
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -21,7 +22,7 @@
|
||||||
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
<el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
|
||||||
<div class="h-70px flex items-center justify-end lt-sm:mt-10px">
|
<div class="h-70px flex items-center justify-end lt-sm:mt-10px">
|
||||||
<div class="px-8px text-right">
|
<div class="px-8px text-right">
|
||||||
<div class="mb-16px text-14px text-gray-400">{{ t('workplace.project') }}</div>
|
<div class="mb-16px text-14px text-gray-400">项目数</div>
|
||||||
<CountTo
|
<CountTo
|
||||||
class="text-20px"
|
class="text-20px"
|
||||||
:start-val="0"
|
:start-val="0"
|
||||||
|
|
@ -31,7 +32,7 @@
|
||||||
</div>
|
</div>
|
||||||
<el-divider direction="vertical" />
|
<el-divider direction="vertical" />
|
||||||
<div class="px-8px text-right">
|
<div class="px-8px text-right">
|
||||||
<div class="mb-16px text-14px text-gray-400">{{ t('workplace.toDo') }}</div>
|
<div class="mb-16px text-14px text-gray-400">待办</div>
|
||||||
<CountTo
|
<CountTo
|
||||||
class="text-20px"
|
class="text-20px"
|
||||||
:start-val="0"
|
:start-val="0"
|
||||||
|
|
@ -41,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
<div class="px-8px text-right">
|
<div class="px-8px text-right">
|
||||||
<div class="mb-16px text-14px text-gray-400">{{ t('workplace.access') }}</div>
|
<div class="mb-16px text-14px text-gray-400">项目访问</div>
|
||||||
<CountTo
|
<CountTo
|
||||||
class="text-20px"
|
class="text-20px"
|
||||||
:start-val="0"
|
:start-val="0"
|
||||||
|
|
@ -54,153 +55,156 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-skeleton>
|
</el-skeleton>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row class="mt-8px" :gutter="8" justify="space-between">
|
<!-- 主要内容区域 -->
|
||||||
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px">
|
<el-row class="mt-8px" :gutter="8" justify="space-between">
|
||||||
<el-card shadow="never">
|
<el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-8px">
|
||||||
<template #header>
|
<!-- 小区项目列表 -->
|
||||||
<div class="h-3 flex justify-between">
|
<el-card shadow="never">
|
||||||
<span>{{ t('workplace.project') }}</span>
|
<template #header>
|
||||||
<el-link
|
<div class="h-3 flex justify-between">
|
||||||
type="primary"
|
<span>项目数</span>
|
||||||
:underline="false"
|
<el-link type="primary" :underline="false" @click="handleMoreClick">
|
||||||
href="https://github.com/yudaocode"
|
更多
|
||||||
target="_blank"
|
</el-link>
|
||||||
>
|
|
||||||
{{ t('action.more') }}
|
|
||||||
</el-link>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-skeleton :loading="loading" animated>
|
|
||||||
<el-row>
|
|
||||||
<el-col
|
|
||||||
v-for="(item, index) in projects"
|
|
||||||
:key="`card-${index}`"
|
|
||||||
:xl="8"
|
|
||||||
:lg="8"
|
|
||||||
:md="8"
|
|
||||||
:sm="24"
|
|
||||||
:xs="24"
|
|
||||||
>
|
|
||||||
<el-card
|
|
||||||
shadow="hover"
|
|
||||||
class="mr-5px mt-5px cursor-pointer"
|
|
||||||
@click="handleProjectClick(item.message)"
|
|
||||||
>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<Icon
|
|
||||||
:icon="item.icon"
|
|
||||||
:size="25"
|
|
||||||
class="mr-8px"
|
|
||||||
:style="{ color: item.color }"
|
|
||||||
/>
|
|
||||||
<span class="text-16px">{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="mt-12px text-12px text-gray-400">{{ t(item.message) }}</div>
|
|
||||||
<div class="mt-12px flex justify-between text-12px text-gray-400">
|
|
||||||
<span>{{ item.personal }}</span>
|
|
||||||
<span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-skeleton>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="never" class="mt-8px">
|
|
||||||
<el-skeleton :loading="loading" animated>
|
|
||||||
<el-row :gutter="20" justify="space-between">
|
|
||||||
<el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
|
|
||||||
<el-card shadow="hover" class="mb-8px">
|
|
||||||
<el-skeleton :loading="loading" animated>
|
|
||||||
<Echart :options="pieOptionsData" :height="280" />
|
|
||||||
</el-skeleton>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
|
|
||||||
<el-card shadow="hover" class="mb-8px">
|
|
||||||
<el-skeleton :loading="loading" animated>
|
|
||||||
<Echart :options="barOptionsData" :height="280" />
|
|
||||||
</el-skeleton>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-skeleton>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-8px">
|
|
||||||
<el-card shadow="never">
|
|
||||||
<template #header>
|
|
||||||
<div class="h-3 flex justify-between">
|
|
||||||
<span>{{ t('workplace.shortcutOperation') }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-skeleton :loading="loading" animated>
|
|
||||||
<el-row>
|
|
||||||
<el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-8px">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<Icon :icon="item.icon" class="mr-8px" :style="{ color: item.color }" />
|
|
||||||
<el-link type="default" :underline="false" @click="handleShortcutClick(item.url)">
|
|
||||||
{{ item.name }}
|
|
||||||
</el-link>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-skeleton>
|
|
||||||
</el-card>
|
|
||||||
<el-card shadow="never" class="mt-8px">
|
|
||||||
<template #header>
|
|
||||||
<div class="h-3 flex justify-between">
|
|
||||||
<span>{{ t('workplace.notice') }}</span>
|
|
||||||
<el-link type="primary" :underline="false">{{ t('action.more') }}</el-link>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-skeleton :loading="loading" animated>
|
|
||||||
<div v-for="(item, index) in notice" :key="`dynamics-${index}`">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<el-avatar :src="avatar" :size="35" class="mr-16px">
|
|
||||||
<img src="@/assets/imgs/avatar.gif" alt="" />
|
|
||||||
</el-avatar>
|
|
||||||
<div>
|
|
||||||
<div class="text-14px">
|
|
||||||
<Highlight :keys="item.keys.map((v) => t(v))">
|
|
||||||
{{ item.type }} : {{ item.title }}
|
|
||||||
</Highlight>
|
|
||||||
</div>
|
|
||||||
<div class="mt-16px text-12px text-gray-400">
|
|
||||||
{{ formatTime(item.date, 'yyyy-MM-dd') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<el-divider />
|
</template>
|
||||||
</div>
|
<el-skeleton :loading="loading" animated>
|
||||||
</el-skeleton>
|
<el-row>
|
||||||
</el-card>
|
<el-col
|
||||||
</el-col>
|
v-for="(item, index) in projects"
|
||||||
</el-row>
|
:key="`card-${index}`"
|
||||||
|
:xl="8"
|
||||||
|
:lg="8"
|
||||||
|
:md="8"
|
||||||
|
:sm="24"
|
||||||
|
:xs="24"
|
||||||
|
>
|
||||||
|
<el-card
|
||||||
|
shadow="hover"
|
||||||
|
class="mr-5px mt-5px cursor-pointer"
|
||||||
|
@click="handleProjectClick(item)"
|
||||||
|
>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<Icon
|
||||||
|
:icon="item.icon"
|
||||||
|
:size="25"
|
||||||
|
class="mr-8px"
|
||||||
|
:style="{ color: item.color }"
|
||||||
|
/>
|
||||||
|
<span class="text-16px">{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-12px text-12px text-gray-400">{{ item.description }}</div>
|
||||||
|
<div class="mt-12px flex justify-between text-12px text-gray-400">
|
||||||
|
<span>{{ item.location }}</span>
|
||||||
|
<span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 图表区域 -->
|
||||||
|
<el-card shadow="never" class="mt-8px">
|
||||||
|
<el-skeleton :loading="loading" animated>
|
||||||
|
<el-row :gutter="20" justify="space-between">
|
||||||
|
<el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
|
||||||
|
<el-card shadow="hover" class="mb-8px">
|
||||||
|
<el-skeleton :loading="loading" animated>
|
||||||
|
<Echart :options="pieOptionsData" :height="280" />
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
|
||||||
|
<el-card shadow="hover" class="mb-8px">
|
||||||
|
<el-skeleton :loading="loading" animated>
|
||||||
|
<Echart :options="barOptionsData" :height="280" />
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右侧区域 -->
|
||||||
|
<el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-8px">
|
||||||
|
<!-- 快捷入口 -->
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="h-3 flex justify-between">
|
||||||
|
<span>快捷入口</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-skeleton :loading="loading" animated>
|
||||||
|
<el-row>
|
||||||
|
<el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-8px">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<Icon :icon="item.icon" class="mr-8px" :style="{ color: item.color }" />
|
||||||
|
<el-link type="default" :underline="false" @click="handleShortcutClick(item.url)">
|
||||||
|
{{ item.name }}
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 通知公告 -->
|
||||||
|
<el-card shadow="never" class="mt-8px">
|
||||||
|
<template #header>
|
||||||
|
<div class="h-3 flex justify-between">
|
||||||
|
<span>通知公告</span>
|
||||||
|
<el-link type="primary" :underline="false" @click="handleNoticeMoreClick">更多</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-skeleton :loading="loading" animated>
|
||||||
|
<div v-for="(item, index) in notice" :key="`dynamics-${index}`">
|
||||||
|
<div class="flex items-start">
|
||||||
|
<el-avatar :src="avatar" :size="35" class="mr-16px">
|
||||||
|
<img src="@/assets/imgs/avatar.gif" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="text-14px">
|
||||||
|
<span class="text-gray-800">{{ item.type }}:</span>
|
||||||
|
<span class="text-gray-600">{{ item.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-8px text-12px text-gray-400">
|
||||||
|
{{ formatTime(item.date, 'yyyy-MM-dd') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-divider v-if="index < notice.length - 1" />
|
||||||
|
</div>
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { set } from 'lodash-es'
|
import { set } from 'lodash-es'
|
||||||
import { EChartsOption } from 'echarts'
|
import { EChartsOption } from 'echarts'
|
||||||
import { formatTime } from '@/utils'
|
import { formatTime } from '@/utils'
|
||||||
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
// import { useWatermark } from '@/hooks/web/useWatermark'
|
|
||||||
import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
|
import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
|
||||||
import { pieOptions, barOptions } from './echarts-data'
|
import { pieOptions, barOptions } from './echarts-data'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
import { CommunityApi, Community } from '@/api/community/community'
|
||||||
|
import { NoticeApi, Notice as NoticeInfo } from '@/api/community/notice'
|
||||||
|
|
||||||
defineOptions({ name: 'Index' })
|
defineOptions({ name: 'Index' })
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
// const { setWatermark } = useWatermark()
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const avatar = userStore.getUser.avatar
|
const avatar = userStore.getUser.avatar
|
||||||
const username = userStore.getUser.nickname
|
const username = userStore.getUser.nickname
|
||||||
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
|
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
|
||||||
|
|
||||||
// 获取统计数
|
// 获取统计数
|
||||||
let totalSate = reactive<WorkplaceTotal>({
|
let totalSate = reactive<WorkplaceTotal>({
|
||||||
project: 0,
|
project: 0,
|
||||||
|
|
@ -209,100 +213,57 @@ let totalSate = reactive<WorkplaceTotal>({
|
||||||
})
|
})
|
||||||
|
|
||||||
const getCount = async () => {
|
const getCount = async () => {
|
||||||
const data = {
|
try {
|
||||||
project: 40,
|
const data = await CommunityApi.getCommunitySimpleList()
|
||||||
access: 2340,
|
totalSate.project = data.length
|
||||||
todo: 10
|
totalSate.access = 2340
|
||||||
|
totalSate.todo = 10
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取小区数量失败:', error)
|
||||||
}
|
}
|
||||||
totalSate = Object.assign(totalSate, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取项目数
|
// 获取小区列表
|
||||||
let projects = reactive<Project[]>([])
|
let projects = reactive<Project[]>([])
|
||||||
const getProject = async () => {
|
const getProject = async () => {
|
||||||
const data = [
|
try {
|
||||||
{
|
const data = await CommunityApi.getCommunityPage({
|
||||||
name: 'ruoyi-vue-pro',
|
pageNo: 1,
|
||||||
icon: 'simple-icons:springboot',
|
pageSize: 100
|
||||||
message: 'github.com/YunaiV/ruoyi-vue-pro',
|
})
|
||||||
personal: 'Spring Boot 单体架构',
|
|
||||||
time: new Date('2025-01-02'),
|
projects = data.list.map((item: Community) => ({
|
||||||
color: '#6DB33F'
|
name: item.communityName || '',
|
||||||
},
|
icon: 'ep:house',
|
||||||
{
|
description: item.streetName || item.districtName || '智慧社区',
|
||||||
name: 'yudao-ui-admin-vue3',
|
location: item.communityAddress || '',
|
||||||
icon: 'ep:element-plus',
|
time: new Date(),
|
||||||
message: 'github.com/yudaocode/yudao-ui-admin-vue3',
|
|
||||||
personal: 'Vue3 + element-plus 管理后台',
|
|
||||||
time: new Date('2025-02-03'),
|
|
||||||
color: '#409EFF'
|
color: '#409EFF'
|
||||||
},
|
}))
|
||||||
{
|
} catch (error) {
|
||||||
name: 'yudao-ui-mall-uniapp',
|
console.error('获取小区列表失败:', error)
|
||||||
icon: 'icon-park-outline:mall-bag',
|
}
|
||||||
message: 'github.com/yudaocode/yudao-ui-mall-uniapp',
|
|
||||||
personal: 'Vue3 + uniapp 商城手机端',
|
|
||||||
time: new Date('2025-03-04'),
|
|
||||||
color: '#ff4d4f'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'yudao-cloud',
|
|
||||||
icon: 'material-symbols:cloud-outline',
|
|
||||||
message: 'github.com/YunaiV/yudao-cloud',
|
|
||||||
personal: 'Spring Cloud 微服务架构',
|
|
||||||
time: new Date('2025-04-05'),
|
|
||||||
color: '#1890ff'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'yudao-ui-admin-vben',
|
|
||||||
icon: 'devicon:antdesign',
|
|
||||||
message: 'github.com/yudaocode/yudao-ui-admin-vben',
|
|
||||||
personal: 'Vue3 + vben5(antd) 管理后台',
|
|
||||||
time: new Date('2025-05-06'),
|
|
||||||
color: '#e18525'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'yudao-ui-admin-uniapp',
|
|
||||||
icon: 'ant-design:mobile',
|
|
||||||
message: 'github.com/yudaocode/yudao-ui-admin-uniapp',
|
|
||||||
personal: 'Vue3 + uniapp 管理手机端',
|
|
||||||
time: new Date('2025-06-01'),
|
|
||||||
color: '#2979ff'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
projects = Object.assign(projects, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取通知公告
|
// 获取通知公告
|
||||||
let notice = reactive<Notice[]>([])
|
let notice = reactive<Notice[]>([])
|
||||||
const getNotice = async () => {
|
const getNotice = async () => {
|
||||||
const data = [
|
try {
|
||||||
{
|
const data = await NoticeApi.getNoticePage({
|
||||||
title: '系统支持 JDK 8/17/21,Vue 2/3',
|
pageNo: 1,
|
||||||
type: '技术兼容性',
|
pageSize: 4,
|
||||||
keys: ['JDK', 'Vue'],
|
status: 1
|
||||||
date: new Date()
|
})
|
||||||
},
|
|
||||||
{
|
notice = data.list.map((item: NoticeInfo) => ({
|
||||||
title: '后端提供 Spring Boot 2.7/3.2 + Cloud 双架构',
|
title: item.title || '',
|
||||||
type: '架构灵活性',
|
type: item.publisher || '系统通知',
|
||||||
keys: ['Boot', 'Cloud'],
|
keys: [item.title || ''],
|
||||||
date: new Date()
|
date: new Date(item.createTime || '')
|
||||||
},
|
}))
|
||||||
{
|
} catch (error) {
|
||||||
title: '全部开源,个人与企业可 100% 直接使用,无需授权',
|
console.error('获取通知公告失败:', error)
|
||||||
type: '开源免授权',
|
}
|
||||||
keys: ['无需授权'],
|
|
||||||
date: new Date()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '国内使用最广泛的快速开发平台,远超 10w+ 企业使用',
|
|
||||||
type: '广泛企业认可',
|
|
||||||
keys: ['最广泛', '10w+'],
|
|
||||||
date: new Date()
|
|
||||||
}
|
|
||||||
]
|
|
||||||
notice = Object.assign(notice, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取快捷入口
|
// 获取快捷入口
|
||||||
|
|
@ -311,87 +272,88 @@ let shortcut = reactive<Shortcut[]>([])
|
||||||
const getShortcut = async () => {
|
const getShortcut = async () => {
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
name: '首页',
|
name: '社区动态',
|
||||||
icon: 'ion:home-outline',
|
icon: 'ep:document',
|
||||||
url: '/',
|
url: '/operation/post',
|
||||||
color: '#1fdaca'
|
color: '#1677ff'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '商城中心',
|
name: '通知公告',
|
||||||
icon: 'ep:shop',
|
icon: 'ep:bell',
|
||||||
url: '/mall/home',
|
url: '/operation/notice',
|
||||||
color: '#ff6b6b'
|
color: '#ff6b6b'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'AI 大模型',
|
name: '知识课堂',
|
||||||
icon: 'tabler:ai',
|
icon: 'ep:reading',
|
||||||
url: '/ai/chat',
|
url: '/operation/knowledge-class',
|
||||||
color: '#7c3aed'
|
color: '#7c3aed'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ERP 系统',
|
name: '小区活动',
|
||||||
icon: 'simple-icons:erpnext',
|
icon: 'ep:calendar',
|
||||||
url: '/erp/home',
|
url: '/operation/activity',
|
||||||
color: '#3fb27f'
|
color: '#3fb27f'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CRM 系统',
|
name: '小区管理',
|
||||||
icon: 'simple-icons:civicrm',
|
icon: 'ep:office-building',
|
||||||
url: '/crm/backlog',
|
url: '/system/community',
|
||||||
color: '#4daf1bc9'
|
color: '#4daf1bc9'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'IoT 物联网',
|
name: 'Banner管理',
|
||||||
icon: 'fa-solid:hdd',
|
icon: 'ep:picture',
|
||||||
url: '/iot/home',
|
url: '/system/banner',
|
||||||
color: '#1a73e8'
|
color: '#1a73e8'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
shortcut = Object.assign(shortcut, data)
|
shortcut = Object.assign(shortcut, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户来源
|
// 用户访问来源
|
||||||
const getUserAccessSource = async () => {
|
const getUserAccessSource = async () => {
|
||||||
const data = [
|
const data = [
|
||||||
{ value: 335, name: 'analysis.directAccess' },
|
{ value: 335, name: '直接访问' },
|
||||||
{ value: 310, name: 'analysis.mailMarketing' },
|
{ value: 310, name: '邮件营销' },
|
||||||
{ value: 234, name: 'analysis.allianceAdvertising' },
|
{ value: 234, name: '联盟广告' },
|
||||||
{ value: 135, name: 'analysis.videoAdvertising' },
|
{ value: 135, name: '视频广告' },
|
||||||
{ value: 1548, name: 'analysis.searchEngines' }
|
{ value: 1548, name: '搜索引擎' }
|
||||||
]
|
]
|
||||||
set(
|
set(
|
||||||
pieOptionsData,
|
pieOptionsData,
|
||||||
'legend.data',
|
'legend.data',
|
||||||
data.map((v) => t(v.name))
|
data.map((v) => v.name)
|
||||||
)
|
)
|
||||||
pieOptionsData!.series![0].data = data.map((v) => {
|
pieOptionsData!.series![0].data = data.map((v) => {
|
||||||
return {
|
return {
|
||||||
name: t(v.name),
|
name: v.name,
|
||||||
value: v.value
|
value: v.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
|
const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
|
||||||
|
|
||||||
// 周活跃量
|
// 周活跃量
|
||||||
const getWeeklyUserActivity = async () => {
|
const getWeeklyUserActivity = async () => {
|
||||||
const data = [
|
const data = [
|
||||||
{ value: 13253, name: 'analysis.monday' },
|
{ value: 13253, name: '周一' },
|
||||||
{ value: 34235, name: 'analysis.tuesday' },
|
{ value: 34235, name: '周二' },
|
||||||
{ value: 26321, name: 'analysis.wednesday' },
|
{ value: 26321, name: '周三' },
|
||||||
{ value: 12340, name: 'analysis.thursday' },
|
{ value: 12340, name: '周四' },
|
||||||
{ value: 24643, name: 'analysis.friday' },
|
{ value: 24643, name: '周五' },
|
||||||
{ value: 1322, name: 'analysis.saturday' },
|
{ value: 1322, name: '周六' },
|
||||||
{ value: 1324, name: 'analysis.sunday' }
|
{ value: 1324, name: '周日' }
|
||||||
]
|
]
|
||||||
set(
|
set(
|
||||||
barOptionsData,
|
barOptionsData,
|
||||||
'xAxis.data',
|
'xAxis.data',
|
||||||
data.map((v) => t(v.name))
|
data.map((v) => v.name)
|
||||||
)
|
)
|
||||||
set(barOptionsData, 'series', [
|
set(barOptionsData, 'series', [
|
||||||
{
|
{
|
||||||
name: t('analysis.activeQuantity'),
|
name: '活跃用户',
|
||||||
data: data.map((v) => v.value),
|
data: data.map((v) => v.value),
|
||||||
type: 'bar'
|
type: 'bar'
|
||||||
}
|
}
|
||||||
|
|
@ -410,13 +372,34 @@ const getAllApi = async () => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleProjectClick = (message: string) => {
|
const handleProjectClick = (item: Project) => {
|
||||||
window.open(`https://${message}`, '_blank')
|
// TODO: 跳转到小区详情页
|
||||||
|
console.log('点击小区:', item.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleShortcutClick = (url: string) => {
|
const handleShortcutClick = (url: string) => {
|
||||||
router.push(url)
|
router.push(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleMoreClick = () => {
|
||||||
|
router.push('/system/community')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleNoticeMoreClick = () => {
|
||||||
|
router.push('/operation/notice')
|
||||||
|
}
|
||||||
|
|
||||||
getAllApi()
|
getAllApi()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.home-container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-card {
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,107 +1,462 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div :class="prefixCls" class="login-container">
|
||||||
:class="prefixCls"
|
<div class="login-content">
|
||||||
class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px"
|
<!-- 登录卡片 -->
|
||||||
>
|
<div class="login-card">
|
||||||
<div class="relative mx-auto h-full flex">
|
<!-- Logo 图标 -->
|
||||||
<div
|
<div class="login-logo">
|
||||||
:class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"
|
<div class="logo-icon">
|
||||||
>
|
<svg viewBox="0 0 1024 1024" width="60" height="60">
|
||||||
<!-- 左上角的 logo + 系统标题 -->
|
<path
|
||||||
<div class="relative flex items-center text-white">
|
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372S306.6 140 512 140s372 166.6 372 372-166.6 372-372 372z"
|
||||||
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
|
fill="#1677ff"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
|
||||||
|
fill="#1677ff"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 左边的背景图 + 欢迎语 -->
|
|
||||||
<div class="h-[calc(100%-60px)] flex items-center justify-center">
|
<!-- 标题 -->
|
||||||
<TransitionGroup
|
<h2 class="login-title">智慧小区云平台</h2>
|
||||||
appear
|
|
||||||
enter-active-class="animate__animated animate__bounceInLeft"
|
<!-- 登录表单 -->
|
||||||
tag="div"
|
<el-form
|
||||||
>
|
ref="formLogin"
|
||||||
<img key="1" alt="" class="w-350px" src="@/assets/svgs/login-box-bg.svg" />
|
:model="loginData.loginForm"
|
||||||
<div key="2" class="text-3xl text-white">{{ t('login.welcome') }}</div>
|
:rules="LoginRules"
|
||||||
<div key="3" class="mt-5 text-14px font-normal text-white">
|
class="login-form"
|
||||||
{{ t('login.message') }}
|
size="large"
|
||||||
</div>
|
|
||||||
</TransitionGroup>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="relative flex-1 p-30px dark:bg-[var(--login-bg-color)] lt-sm:p-10px overflow-x-hidden overflow-y-auto"
|
|
||||||
>
|
|
||||||
<!-- 右上角的主题、语言选择 -->
|
|
||||||
<div
|
|
||||||
class="flex items-center justify-between at-2xl:justify-end at-xl:justify-end"
|
|
||||||
style="color: var(--el-text-color-primary);"
|
|
||||||
>
|
>
|
||||||
<div class="flex items-center at-2xl:hidden at-xl:hidden">
|
<el-form-item prop="username">
|
||||||
<span class="text-20px font-bold" >{{ underlineToHump(appStore.getTitle) }}</span>
|
<el-input
|
||||||
|
v-model="loginData.loginForm.username"
|
||||||
|
placeholder="请输入用户名称"
|
||||||
|
:prefix-icon="iconAvatar"
|
||||||
|
@blur="handleUsernameBlur"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input
|
||||||
|
v-model="loginData.loginForm.password"
|
||||||
|
placeholder="请输入登录密码"
|
||||||
|
:prefix-icon="iconLock"
|
||||||
|
show-password
|
||||||
|
type="password"
|
||||||
|
@keyup.enter="getCode()"
|
||||||
|
@blur="handlePasswordBlur"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 租户选择 -->
|
||||||
|
<el-form-item v-if="loginData.tenantEnable === 'true'" prop="tenantId">
|
||||||
|
<el-select
|
||||||
|
ref="tenantSelectRef"
|
||||||
|
v-model="loginData.loginForm.tenantId"
|
||||||
|
placeholder="请选择租户"
|
||||||
|
:prefix-icon="iconHouse"
|
||||||
|
style="width: 100%"
|
||||||
|
:disabled="tenantList.length === 0"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="tenant in tenantList"
|
||||||
|
:key="tenant.tenantId"
|
||||||
|
:label="tenant.tenantName"
|
||||||
|
:value="tenant.tenantId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 记住密码 -->
|
||||||
|
<div class="login-options">
|
||||||
|
<el-checkbox v-model="loginData.loginForm.rememberMe">
|
||||||
|
记住密码
|
||||||
|
</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-end space-x-10px h-48px">
|
|
||||||
<ThemeSwitch />
|
<!-- 登录按钮 -->
|
||||||
<LocaleDropdown />
|
<el-form-item>
|
||||||
</div>
|
<el-button
|
||||||
</div>
|
:loading="loginLoading"
|
||||||
<!-- 右边的登录界面 -->
|
type="primary"
|
||||||
<Transition appear enter-active-class="animate__animated animate__bounceInRight">
|
class="login-button"
|
||||||
<div
|
@click="getCode()"
|
||||||
class="m-auto h-[calc(100%-60px)] w-[100%] flex items-center at-2xl:max-w-500px at-lg:max-w-500px at-md:max-w-500px at-xl:max-w-500px"
|
>
|
||||||
>
|
登录
|
||||||
<!-- 账号登录 -->
|
</el-button>
|
||||||
<LoginForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
|
</el-form-item>
|
||||||
<!-- 手机登录 -->
|
</el-form>
|
||||||
<MobileForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
|
|
||||||
<!-- 二维码登录 -->
|
|
||||||
<QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
|
|
||||||
<!-- 注册 -->
|
|
||||||
<RegisterForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
|
|
||||||
<!-- 三方登录 -->
|
|
||||||
<SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
|
|
||||||
<!-- 忘记密码 -->
|
|
||||||
<ForgetPasswordForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧插图 -->
|
||||||
|
<div class="login-illustration">
|
||||||
|
<img src="@/assets/svgs/login-box-bg.svg" alt="illustration" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 主题和语言切换 -->
|
||||||
|
<div class="login-tools">
|
||||||
|
<ThemeSwitch />
|
||||||
|
<LocaleDropdown />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { underlineToHump } from '@/utils'
|
import { underlineToHump } from '@/utils'
|
||||||
|
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
|
import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
|
||||||
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
|
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
|
||||||
|
import { useIcon } from '@/hooks/web/useIcon'
|
||||||
import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue, ForgetPasswordForm } from './components'
|
import * as authUtil from '@/utils/auth'
|
||||||
|
import { usePermissionStore } from '@/store/modules/permission'
|
||||||
|
import * as LoginApi from '@/api/login'
|
||||||
|
import { ElLoading } from 'element-plus'
|
||||||
|
|
||||||
defineOptions({ name: 'Login' })
|
defineOptions({ name: 'Login' })
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
const message = useMessage()
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
const prefixCls = getPrefixCls('login')
|
const prefixCls = getPrefixCls('login')
|
||||||
|
|
||||||
|
const iconHouse = useIcon({ icon: 'ep:house' })
|
||||||
|
const iconAvatar = useIcon({ icon: 'ep:avatar' })
|
||||||
|
const iconLock = useIcon({ icon: 'ep:lock' })
|
||||||
|
|
||||||
|
const formLogin = ref()
|
||||||
|
const loginLoading = ref(false)
|
||||||
|
const captchaType = ref('blockPuzzle')
|
||||||
|
const tenantList = ref<LoginApi.TenantInfo[]>([])
|
||||||
|
const tenantSelectRef = ref()
|
||||||
|
const isFetchingTenants = ref(false)
|
||||||
|
|
||||||
|
const LoginRules = {
|
||||||
|
username: [required],
|
||||||
|
password: [required],
|
||||||
|
tenantId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择租户',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const loginData = reactive({
|
||||||
|
captchaEnable: import.meta.env.VITE_APP_CAPTCHA_ENABLE,
|
||||||
|
tenantEnable: import.meta.env.VITE_APP_TENANT_ENABLE,
|
||||||
|
loginForm: {
|
||||||
|
tenantId: undefined as number | undefined,
|
||||||
|
username: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',
|
||||||
|
password: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',
|
||||||
|
captchaVerification: '',
|
||||||
|
rememberMe: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const verify = ref()
|
||||||
|
const loading = ref()
|
||||||
|
const { push } = useRouter()
|
||||||
|
const permissionStore = usePermissionStore()
|
||||||
|
|
||||||
|
// 用户名失焦时获取租户列表
|
||||||
|
const handleUsernameBlur = async () => {
|
||||||
|
if (loginData.tenantEnable !== 'true') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await fetchTenantList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 密码失焦时获取租户列表
|
||||||
|
const handlePasswordBlur = async () => {
|
||||||
|
if (loginData.tenantEnable !== 'true') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await fetchTenantList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取租户列表
|
||||||
|
const fetchTenantList = async () => {
|
||||||
|
const username = loginData.loginForm.username?.trim()
|
||||||
|
const password = loginData.loginForm.password?.trim()
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFetchingTenants.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isFetchingTenants.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await LoginApi.getUserTenantList({
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res || !res.tenants || res.tenants.length === 0) {
|
||||||
|
message.error('无权限访问该系统')
|
||||||
|
tenantList.value = []
|
||||||
|
loginData.loginForm.tenantId = undefined
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tenantList.value = res.tenants
|
||||||
|
|
||||||
|
if (res.tenants.length === 1) {
|
||||||
|
loginData.loginForm.tenantId = res.tenants[0].tenantId
|
||||||
|
} else {
|
||||||
|
loginData.loginForm.tenantId = undefined
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取租户列表失败:', error)
|
||||||
|
tenantList.value = []
|
||||||
|
loginData.loginForm.tenantId = undefined
|
||||||
|
} finally {
|
||||||
|
isFetchingTenants.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
const getCode = async () => {
|
||||||
|
if (loginData.tenantEnable === 'true' && tenantList.value.length === 0) {
|
||||||
|
const username = loginData.loginForm.username?.trim()
|
||||||
|
const password = loginData.loginForm.password?.trim()
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
message.error('请输入用户名和密码')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetchTenantList()
|
||||||
|
|
||||||
|
if (tenantList.value.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tenantList.value.length === 1) {
|
||||||
|
loginData.loginForm.tenantId = tenantList.value[0].tenantId
|
||||||
|
continueLogin()
|
||||||
|
} else {
|
||||||
|
if (tenantSelectRef.value) {
|
||||||
|
tenantSelectRef.value.visible = true
|
||||||
|
}
|
||||||
|
message.info('请选择要登录的租户')
|
||||||
|
}
|
||||||
|
} else if (loginData.tenantEnable === 'true' && tenantList.value.length > 0) {
|
||||||
|
if (!loginData.loginForm.tenantId) {
|
||||||
|
message.error('请选择租户')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continueLogin()
|
||||||
|
} else {
|
||||||
|
continueLogin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const continueLogin = () => {
|
||||||
|
if (loginData.captchaEnable === 'false') {
|
||||||
|
handleLogin({})
|
||||||
|
} else {
|
||||||
|
verify.value?.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTenantId = () => {
|
||||||
|
if (loginData.loginForm.tenantId) {
|
||||||
|
authUtil.setTenantId(loginData.loginForm.tenantId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLoginFormCache = () => {
|
||||||
|
const loginForm = authUtil.getLoginForm()
|
||||||
|
if (loginForm) {
|
||||||
|
loginData.loginForm = {
|
||||||
|
...loginData.loginForm,
|
||||||
|
username: loginForm.username ? loginForm.username : loginData.loginForm.username,
|
||||||
|
password: loginForm.password ? loginForm.password : loginData.loginForm.password,
|
||||||
|
rememberMe: loginForm.rememberMe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTenantByWebsite = async () => {
|
||||||
|
if (loginData.tenantEnable === 'true') {
|
||||||
|
const website = location.host
|
||||||
|
const res = await LoginApi.getTenantByWebsite(website)
|
||||||
|
if (res) {
|
||||||
|
authUtil.setTenantId(res.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLogin = async (params: any) => {
|
||||||
|
loginLoading.value = true
|
||||||
|
try {
|
||||||
|
setTenantId()
|
||||||
|
await formLogin.value.validate()
|
||||||
|
const loginDataLoginForm = { ...loginData.loginForm }
|
||||||
|
loginDataLoginForm.captchaVerification = params.captchaVerification
|
||||||
|
const res = await LoginApi.login(loginDataLoginForm)
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loading.value = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: '正在加载系统中...',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
if (loginDataLoginForm.rememberMe) {
|
||||||
|
authUtil.setLoginForm(loginDataLoginForm)
|
||||||
|
} else {
|
||||||
|
authUtil.removeLoginForm()
|
||||||
|
}
|
||||||
|
authUtil.setToken(res)
|
||||||
|
await push({ path: '/' })
|
||||||
|
} finally {
|
||||||
|
loginLoading.value = false
|
||||||
|
loading.value?.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getLoginFormCache()
|
||||||
|
getTenantByWebsite()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
$prefix-cls: #{$namespace}-login;
|
.login-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background: #1677ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.#{$prefix-cls} {
|
.login-content {
|
||||||
overflow: auto;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 100px;
|
||||||
|
max-width: 1200px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 40px;
|
||||||
|
}
|
||||||
|
|
||||||
&__left {
|
.login-card {
|
||||||
&::before {
|
background: #ffffff;
|
||||||
position: absolute;
|
border-radius: 8px;
|
||||||
top: 0;
|
padding: 40px;
|
||||||
left: 0;
|
width: 380px;
|
||||||
z-index: -1;
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||||||
width: 100%;
|
}
|
||||||
height: 100%;
|
|
||||||
background-image: url('@/assets/svgs/login-bg.svg');
|
.login-logo {
|
||||||
background-position: center;
|
display: flex;
|
||||||
background-repeat: no-repeat;
|
justify-content: center;
|
||||||
content: '';
|
margin-bottom: 16px;
|
||||||
}
|
|
||||||
|
.logo-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1677ff;
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-select .el-input__wrapper) {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-options {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
:deep(.el-checkbox__label) {
|
||||||
|
color: #1677ff;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 44px;
|
||||||
|
font-size: 16px;
|
||||||
|
background: #1677ff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #4096ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-illustration {
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 500px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-tools {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
:deep(svg) {
|
||||||
|
fill: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.login-illustration {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-content {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.login-card {
|
||||||
|
width: 100%;
|
||||||
|
padding: 30px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-content {
|
||||||
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -33,32 +33,33 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button type="primary" @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon icon="ep:search" class="mr-5px" /> 查询
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="openForm('create')"
|
|
||||||
v-hasPermi="['system:dept:create']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="danger" plain @click="toggleExpandAll">
|
<el-button @click="resetQuery">
|
||||||
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
:disabled="checkedIds.length === 0"
|
|
||||||
@click="handleDeleteBatch"
|
|
||||||
v-hasPermi="['system:dept:delete']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['system:dept:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新建
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" plain @click="toggleExpandAll">
|
||||||
|
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table
|
<el-table
|
||||||
|
|
@ -68,16 +69,31 @@
|
||||||
:default-expand-all="isExpandAll"
|
:default-expand-all="isExpandAll"
|
||||||
v-if="refreshTable"
|
v-if="refreshTable"
|
||||||
@selection-change="handleRowCheckboxChange"
|
@selection-change="handleRowCheckboxChange"
|
||||||
|
:header-cell-style="{
|
||||||
|
background: '#1890ff',
|
||||||
|
color: '#ffffff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: '14px',
|
||||||
|
borderColor: '#1890ff'
|
||||||
|
}"
|
||||||
|
:cell-style="{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
color: '#333333',
|
||||||
|
borderColor: '#ebeef5'
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column prop="name" label="部门名称" />
|
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||||
<el-table-column prop="leader" label="负责人">
|
<el-table-column prop="name" label="部门名称" min-width="150" />
|
||||||
|
<el-table-column prop="leader" label="负责人" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ userList.find((user) => user.id === scope.row.leaderUserId)?.nickname }}
|
{{ userList.find((user) => user.id === scope.row.leaderUserId)?.nickname }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="sort" label="排序" />
|
<el-table-column prop="sort" label="排序" width="80" />
|
||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -89,7 +105,7 @@
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center" width="120px" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -97,7 +113,7 @@
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
v-hasPermi="['system:dept:update']"
|
v-hasPermi="['system:dept:update']"
|
||||||
>
|
>
|
||||||
修改
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
|
||||||
|
|
@ -37,54 +37,76 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button type="primary" @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon icon="ep:search" class="mr-5px" /> 查询
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="openForm('create')"
|
|
||||||
v-hasPermi="['system:dict:create']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="resetQuery">
|
||||||
type="success"
|
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||||
plain
|
|
||||||
@click="handleExport"
|
|
||||||
:loading="exportLoading"
|
|
||||||
v-hasPermi="['system:dict:export']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
:disabled="checkedIds.length === 0"
|
|
||||||
@click="handleDeleteBatch"
|
|
||||||
v-hasPermi="['system:dict:delete']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['system:dict:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新建
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['system:dict:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
|
<el-table
|
||||||
<el-table-column type="selection" width="55" />
|
v-loading="loading"
|
||||||
<el-table-column label="字典编码" align="center" prop="id" />
|
:data="list"
|
||||||
<el-table-column label="字典标签" align="center" prop="label" />
|
:stripe="true"
|
||||||
<el-table-column label="字典键值" align="center" prop="value" />
|
:show-overflow-tooltip="true"
|
||||||
<el-table-column label="字典排序" align="center" prop="sort" />
|
@selection-change="handleRowCheckboxChange"
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
:header-cell-style="{
|
||||||
|
background: '#1890ff',
|
||||||
|
color: '#ffffff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: '14px',
|
||||||
|
borderColor: '#1890ff'
|
||||||
|
}"
|
||||||
|
:cell-style="{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
color: '#333333',
|
||||||
|
borderColor: '#ebeef5'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||||
|
<el-table-column label="字典编码" align="center" prop="id" width="100" />
|
||||||
|
<el-table-column label="字典标签" align="center" prop="label" min-width="120" />
|
||||||
|
<el-table-column label="字典键值" align="center" prop="value" width="120" />
|
||||||
|
<el-table-column label="字典排序" align="center" prop="sort" width="100" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="颜色类型" align="center" prop="colorType" />
|
<el-table-column label="颜色类型" align="center" prop="colorType" width="100" />
|
||||||
<el-table-column label="CSS Class" align="center" prop="cssClass" />
|
<el-table-column label="CSS Class" align="center" prop="cssClass" width="120" />
|
||||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip min-width="150" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="创建时间"
|
label="创建时间"
|
||||||
align="center"
|
align="center"
|
||||||
|
|
@ -92,7 +114,7 @@
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center" width="120px" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -100,7 +122,7 @@
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
v-hasPermi="['system:dict:update']"
|
v-hasPermi="['system:dict:update']"
|
||||||
>
|
>
|
||||||
修改
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
|
||||||
|
|
@ -53,60 +53,73 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery">
|
<el-button type="primary" @click="handleQuery">
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
<Icon class="mr-5px" icon="ep:search" /> 查询
|
||||||
搜索
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="resetQuery">
|
<el-button @click="resetQuery">
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
<Icon class="mr-5px" icon="ep:refresh" /> 重置
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:dict:create']"
|
|
||||||
plain
|
|
||||||
type="primary"
|
|
||||||
@click="openForm('create')"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:dict:export']"
|
|
||||||
:loading="exportLoading"
|
|
||||||
plain
|
|
||||||
type="success"
|
|
||||||
@click="handleExport"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:download" />
|
|
||||||
导出
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:dict:delete']"
|
|
||||||
:disabled="checkedIds.length === 0"
|
|
||||||
plain
|
|
||||||
type="danger"
|
|
||||||
@click="handleDeleteBatch"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:delete" />
|
|
||||||
批量删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['system:dict:create']"
|
||||||
|
plain
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('create')"
|
||||||
|
>
|
||||||
|
<Icon class="mr-5px" icon="ep:plus" /> 新建
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['system:dict:export']"
|
||||||
|
:loading="exportLoading"
|
||||||
|
plain
|
||||||
|
type="primary"
|
||||||
|
@click="handleExport"
|
||||||
|
>
|
||||||
|
<Icon class="mr-5px" icon="ep:download" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
|
<el-table
|
||||||
<el-table-column type="selection" width="55" />
|
v-loading="loading"
|
||||||
<el-table-column align="center" label="字典编号" prop="id" />
|
:data="list"
|
||||||
<el-table-column align="center" label="字典名称" prop="name" show-overflow-tooltip />
|
:stripe="true"
|
||||||
<el-table-column align="center" label="字典类型" prop="type" width="300" />
|
:show-overflow-tooltip="true"
|
||||||
<el-table-column align="center" label="状态" prop="status">
|
@selection-change="handleRowCheckboxChange"
|
||||||
|
:header-cell-style="{
|
||||||
|
background: '#1890ff',
|
||||||
|
color: '#ffffff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: '14px',
|
||||||
|
borderColor: '#1890ff'
|
||||||
|
}"
|
||||||
|
:cell-style="{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
color: '#333333',
|
||||||
|
borderColor: '#ebeef5'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||||
|
<el-table-column align="center" label="字典编号" prop="id" width="100" />
|
||||||
|
<el-table-column align="center" label="字典名称" prop="name" show-overflow-tooltip min-width="150" />
|
||||||
|
<el-table-column align="center" label="字典类型" prop="type" width="200" />
|
||||||
|
<el-table-column align="center" label="状态" prop="status" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="备注" prop="remark" />
|
<el-table-column align="center" label="备注" prop="remark" min-width="150" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
align="center"
|
align="center"
|
||||||
|
|
@ -114,7 +127,7 @@
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
width="180"
|
width="180"
|
||||||
/>
|
/>
|
||||||
<el-table-column align="center" label="操作">
|
<el-table-column align="center" label="操作" width="180px" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['system:dict:update']"
|
v-hasPermi="['system:dict:update']"
|
||||||
|
|
@ -122,7 +135,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
>
|
>
|
||||||
修改
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<router-link :to="'/dict/type/data/' + scope.row.type">
|
<router-link :to="'/dict/type/data/' + scope.row.type">
|
||||||
<el-button link type="primary">数据</el-button>
|
<el-button link type="primary">数据</el-button>
|
||||||
|
|
|
||||||
|
|
@ -33,35 +33,36 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery">
|
<el-button type="primary" @click="handleQuery">
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
<Icon class="mr-5px" icon="ep:search" /> 查询
|
||||||
搜索
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="resetQuery">
|
<el-button @click="resetQuery">
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
<Icon class="mr-5px" icon="ep:refresh" /> 重置
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:menu:create']"
|
|
||||||
plain
|
|
||||||
type="primary"
|
|
||||||
@click="openForm('create')"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
<el-button plain type="danger" @click="toggleExpandAll">
|
|
||||||
<Icon class="mr-5px" icon="ep:sort" />
|
|
||||||
展开/折叠
|
|
||||||
</el-button>
|
|
||||||
<el-button plain @click="refreshMenu">
|
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
|
||||||
刷新菜单缓存
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['system:menu:create']"
|
||||||
|
plain
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('create')"
|
||||||
|
>
|
||||||
|
<Icon class="mr-5px" icon="ep:plus" /> 新建
|
||||||
|
</el-button>
|
||||||
|
<el-button plain type="primary" @click="toggleExpandAll">
|
||||||
|
<Icon class="mr-5px" icon="ep:sort" /> 展开/折叠
|
||||||
|
</el-button>
|
||||||
|
<el-button plain type="primary" @click="refreshMenu">
|
||||||
|
<Icon class="mr-5px" icon="ep:refresh" /> 刷新菜单缓存
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-auto-resizer>
|
<el-auto-resizer>
|
||||||
|
|
|
||||||
|
|
@ -37,48 +37,70 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button type="primary" @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon icon="ep:search" class="mr-5px" /> 查询
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="openForm('create')"
|
|
||||||
v-hasPermi="['system:post:create']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="resetQuery">
|
||||||
type="success"
|
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||||
plain
|
|
||||||
@click="handleExport"
|
|
||||||
:loading="exportLoading"
|
|
||||||
v-hasPermi="['system:post:export']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
plain
|
|
||||||
:disabled="checkedIds.length === 0"
|
|
||||||
@click="handleDeleteBatch"
|
|
||||||
v-hasPermi="['system:post:delete']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['system:post:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新建
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['system:post:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
|
<el-table
|
||||||
<el-table-column type="selection" width="55" />
|
v-loading="loading"
|
||||||
<el-table-column label="岗位编号" align="center" prop="id" />
|
:data="list"
|
||||||
<el-table-column label="岗位名称" align="center" prop="name" />
|
:stripe="true"
|
||||||
<el-table-column label="岗位编码" align="center" prop="code" />
|
:show-overflow-tooltip="true"
|
||||||
<el-table-column label="岗位顺序" align="center" prop="sort" />
|
@selection-change="handleRowCheckboxChange"
|
||||||
<el-table-column label="岗位备注" align="center" prop="remark" />
|
:header-cell-style="{
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
background: '#1890ff',
|
||||||
|
color: '#ffffff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: '14px',
|
||||||
|
borderColor: '#1890ff'
|
||||||
|
}"
|
||||||
|
:cell-style="{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
color: '#333333',
|
||||||
|
borderColor: '#ebeef5'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||||
|
<el-table-column label="岗位编号" align="center" prop="id" width="100" />
|
||||||
|
<el-table-column label="岗位名称" align="center" prop="name" min-width="120" />
|
||||||
|
<el-table-column label="岗位编码" align="center" prop="code" width="120" />
|
||||||
|
<el-table-column label="岗位顺序" align="center" prop="sort" width="100" />
|
||||||
|
<el-table-column label="岗位备注" align="center" prop="remark" min-width="150" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -90,7 +112,7 @@
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center" width="120px" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
|
||||||
|
|
@ -48,62 +48,75 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery">
|
<el-button type="primary" @click="handleQuery">
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
<Icon class="mr-5px" icon="ep:search" /> 查询
|
||||||
搜索
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="resetQuery">
|
<el-button @click="resetQuery">
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
<Icon class="mr-5px" icon="ep:refresh" /> 重置
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:role:create']"
|
|
||||||
plain
|
|
||||||
type="primary"
|
|
||||||
@click="openForm('create')"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:role:export']"
|
|
||||||
:loading="exportLoading"
|
|
||||||
plain
|
|
||||||
type="success"
|
|
||||||
@click="handleExport"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:download" />
|
|
||||||
导出
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['system:role:delete']"
|
|
||||||
:disabled="checkedIds.length === 0"
|
|
||||||
plain
|
|
||||||
type="danger"
|
|
||||||
@click="handleDeleteBatch"
|
|
||||||
>
|
|
||||||
<Icon class="mr-5px" icon="ep:delete" />
|
|
||||||
批量删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['system:role:create']"
|
||||||
|
plain
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('create')"
|
||||||
|
>
|
||||||
|
<Icon class="mr-5px" icon="ep:plus" /> 新建
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['system:role:export']"
|
||||||
|
:loading="exportLoading"
|
||||||
|
plain
|
||||||
|
type="primary"
|
||||||
|
@click="handleExport"
|
||||||
|
>
|
||||||
|
<Icon class="mr-5px" icon="ep:download" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
|
<el-table
|
||||||
<el-table-column type="selection" width="55" />
|
v-loading="loading"
|
||||||
<el-table-column align="center" label="角色编号" prop="id" />
|
:data="list"
|
||||||
<el-table-column align="center" label="角色名称" prop="name" />
|
:stripe="true"
|
||||||
<el-table-column label="角色类型" align="center" prop="type">
|
:show-overflow-tooltip="true"
|
||||||
|
@selection-change="handleRowCheckboxChange"
|
||||||
|
:header-cell-style="{
|
||||||
|
background: '#1890ff',
|
||||||
|
color: '#ffffff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: '14px',
|
||||||
|
borderColor: '#1890ff'
|
||||||
|
}"
|
||||||
|
:cell-style="{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
color: '#333333',
|
||||||
|
borderColor: '#ebeef5'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||||
|
<el-table-column align="center" label="角色编号" prop="id" width="100" />
|
||||||
|
<el-table-column align="center" label="角色名称" prop="name" min-width="120" />
|
||||||
|
<el-table-column label="角色类型" align="center" prop="type" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.SYSTEM_ROLE_TYPE" :value="scope.row.type" />
|
<dict-tag :type="DICT_TYPE.SYSTEM_ROLE_TYPE" :value="scope.row.type" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="角色标识" prop="code" />
|
<el-table-column align="center" label="角色标识" prop="code" width="120" />
|
||||||
<el-table-column align="center" label="显示顺序" prop="sort" />
|
<el-table-column align="center" label="显示顺序" prop="sort" width="100" />
|
||||||
<el-table-column align="center" label="备注" prop="remark" />
|
<el-table-column align="center" label="备注" prop="remark" min-width="120" />
|
||||||
<el-table-column align="center" label="状态" prop="status">
|
<el-table-column align="center" label="状态" prop="status" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -115,7 +128,7 @@
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
width="180"
|
width="180"
|
||||||
/>
|
/>
|
||||||
<el-table-column :width="300" align="center" label="操作">
|
<el-table-column label="操作" align="center" min-width="200px" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['system:role:update']"
|
v-hasPermi="['system:role:update']"
|
||||||
|
|
@ -128,8 +141,6 @@
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['system:permission:assign-role-menu']"
|
v-hasPermi="['system:permission:assign-role-menu']"
|
||||||
link
|
link
|
||||||
preIcon="ep:basketball"
|
|
||||||
title="菜单权限"
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openAssignMenuForm(scope.row)"
|
@click="openAssignMenuForm(scope.row)"
|
||||||
>
|
>
|
||||||
|
|
@ -138,8 +149,6 @@
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['system:permission:assign-role-data-scope']"
|
v-hasPermi="['system:permission:assign-role-data-scope']"
|
||||||
link
|
link
|
||||||
preIcon="ep:coin"
|
|
||||||
title="数据权限"
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openDataPermissionForm(scope.row)"
|
@click="openDataPermissionForm(scope.row)"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -38,35 +38,56 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button type="primary" @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon icon="ep:search" class="mr-5px" /> 查询
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
@click="openForm('create')"
|
|
||||||
v-hasPermi="['system:tenant-package:create']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" class="mr-5px" />
|
|
||||||
新增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button @click="resetQuery">
|
||||||
type="danger"
|
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||||
plain
|
|
||||||
:disabled="checkedIds.length === 0"
|
|
||||||
@click="handleDeleteBatch"
|
|
||||||
v-hasPermi="['system:tenant-package:delete']"
|
|
||||||
>
|
|
||||||
<Icon icon="ep:delete" class="mr-5px" />
|
|
||||||
批量删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 操作按钮栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<div class="mb-15px">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['system:tenant-package:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新建
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
|
<el-table
|
||||||
<el-table-column type="selection" width="55" />
|
row-key="id"
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
:stripe="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
@selection-change="handleRowCheckboxChange"
|
||||||
|
:header-cell-style="{
|
||||||
|
background: '#1890ff',
|
||||||
|
color: '#ffffff',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: '14px',
|
||||||
|
borderColor: '#1890ff'
|
||||||
|
}"
|
||||||
|
:cell-style="{
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '14px',
|
||||||
|
color: '#333333',
|
||||||
|
borderColor: '#ebeef5'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="序号" align="center" type="index" width="80" />
|
||||||
<el-table-column label="套餐编号" align="center" prop="id" width="120" />
|
<el-table-column label="套餐编号" align="center" prop="id" width="120" />
|
||||||
<el-table-column label="套餐名" align="center" prop="name" />
|
<el-table-column label="套餐名" align="center" prop="name" />
|
||||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||||
|
|
@ -82,7 +103,7 @@
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" min-width="120px" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -90,7 +111,7 @@
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
v-hasPermi="['system:tenant-package:update']"
|
v-hasPermi="['system:tenant-package:update']"
|
||||||
>
|
>
|
||||||
修改
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue