init
This commit is contained in:
34
src/layout/footer.vue
Normal file
34
src/layout/footer.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<!-- 页脚 -->
|
||||
<template>
|
||||
<div class="ele-text-center" style="padding: 16px 0;">
|
||||
<!-- <a-space size="large">
|
||||
<a
|
||||
class="ele-text-secondary"
|
||||
href="https://eleadmin.com"
|
||||
target="_blank">
|
||||
{{ $t('layout.footer.website') }}
|
||||
</a>
|
||||
<a
|
||||
class="ele-text-secondary"
|
||||
href="https://eleadmin.com/doc/eleadminpro/"
|
||||
target="_blank">
|
||||
{{ $t('layout.footer.document') }}
|
||||
</a>
|
||||
<a
|
||||
class="ele-text-secondary"
|
||||
href="https://eleadmin.com/goods/9"
|
||||
target="_blank">
|
||||
{{ $t('layout.footer.authorization') }}
|
||||
</a>
|
||||
</a-space> -->
|
||||
<div class="ele-text-secondary" style="margin-top: 8px;">
|
||||
{{ $t('layout.footer.copyright') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'EleFooter'
|
||||
}
|
||||
</script>
|
||||
163
src/layout/header-right.vue
Normal file
163
src/layout/header-right.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<!-- 顶栏右侧区域按钮 -->
|
||||
<template>
|
||||
<div class="ele-admin-header-tool">
|
||||
<div class="ele-admin-header-tool-item hidden-sm-and-down" @click="changeFullscreen">
|
||||
<fullscreen-exit-outlined v-if="fullscreen"/>
|
||||
<fullscreen-outlined v-else/>
|
||||
</div>
|
||||
<!-- 语言切换 -->
|
||||
<!-- <div class="ele-admin-header-tool-item">
|
||||
<a-dropdown placement="bottomCenter" :overlay-style="{minWidth: '120px', paddingTop: '17px'}">
|
||||
<global-outlined style="transform: scale(1.08);"/>
|
||||
<template #overlay>
|
||||
<a-menu :selected-keys="language" @click="changeLanguage">
|
||||
<a-menu-item key="en">English</a-menu-item>
|
||||
<a-menu-item key="zh_CN">简体中文</a-menu-item>
|
||||
<a-menu-item key="zh_TW">繁體中文</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div> -->
|
||||
<!-- 消息通知 -->
|
||||
<!-- <div class="ele-admin-header-tool-item">
|
||||
<ele-notice/>
|
||||
</div> -->
|
||||
<!-- 用户信息 -->
|
||||
<div class="ele-admin-header-tool-item">
|
||||
<a-dropdown placement="bottomCenter" :overlay-style="{minWidth: '120px'}">
|
||||
<div class="ele-admin-header-avatar">
|
||||
<a-avatar :src="loginUser.avatar"/>
|
||||
<span>{{ loginUser.nickname }} </span>
|
||||
<down-outlined/>
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu @click="onUserDropClick">
|
||||
<a-menu-item key="profile">
|
||||
<div class="ele-cell">
|
||||
<user-outlined/>
|
||||
<div class="ele-cell-content">{{ $t('layout.header.profile') }}</div>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="password">
|
||||
<div class="ele-cell">
|
||||
<key-outlined/>
|
||||
<div class="ele-cell-content">{{ $t('layout.header.password') }}</div>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
<a-menu-divider/>
|
||||
<a-menu-item key="logout">
|
||||
<div class="ele-cell">
|
||||
<logout-outlined/>
|
||||
<div class="ele-cell-content">{{ $t('layout.header.logout') }}</div>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
<!-- 主题设置 -->
|
||||
<div v-if="showSetting" class="ele-admin-header-tool-item" @click="openSetting">
|
||||
<MoreOutlined/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {createVNode} from 'vue';
|
||||
import {
|
||||
DownOutlined,
|
||||
MoreOutlined,
|
||||
UserOutlined,
|
||||
KeyOutlined,
|
||||
LogoutOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
FullscreenOutlined,
|
||||
FullscreenExitOutlined,
|
||||
// GlobalOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import {toggleFullscreen, isFullscreen} from 'ele-admin-pro/packages/util.js';
|
||||
// import EleNotice from './notice';
|
||||
|
||||
export default {
|
||||
name: 'EleHeaderRight',
|
||||
components: {
|
||||
DownOutlined,
|
||||
MoreOutlined,
|
||||
UserOutlined,
|
||||
KeyOutlined,
|
||||
LogoutOutlined,
|
||||
FullscreenOutlined,
|
||||
FullscreenExitOutlined,
|
||||
// GlobalOutlined,
|
||||
// EleNotice
|
||||
},
|
||||
emits: ['item-click', 'change-language'],
|
||||
props: {
|
||||
// 是否显示打开设置抽屉按钮
|
||||
showSetting: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 当前登录用户信息
|
||||
loginUser() {
|
||||
return this.$store.state.user.user;
|
||||
},
|
||||
// 当前语言
|
||||
language() {
|
||||
return [this.$i18n.locale];
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 是否全屏状态
|
||||
fullscreen: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 个人信息下拉菜单点击 */
|
||||
onUserDropClick({key}) {
|
||||
if (key === 'logout') {
|
||||
// 退出登录
|
||||
this.$confirm({
|
||||
title: this.$t('layout.logout.title'),
|
||||
content: this.$t('layout.logout.message'),
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
// 清除缓存的token
|
||||
this.$store.dispatch('user/removeToken').then(() => {
|
||||
location.replace('/login'); // 这样跳转避免再次登录重复注册动态路由
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (key === 'profile') {
|
||||
this.$router.push('/user/profile');
|
||||
} else if (key === 'password') {
|
||||
this.$emit('item-click', 'password');
|
||||
}
|
||||
},
|
||||
/* 打开设置抽屉 */
|
||||
openSetting() {
|
||||
this.$emit('item-click', 'setting');
|
||||
},
|
||||
/* 全屏切换 */
|
||||
changeFullscreen() {
|
||||
try {
|
||||
this.fullscreen = toggleFullscreen();
|
||||
} catch (e) {
|
||||
this.$message.error('您的浏览器不支持全屏模式');
|
||||
}
|
||||
},
|
||||
/* 检查全屏状态 */
|
||||
checkFullscreen() {
|
||||
this.fullscreen = isFullscreen();
|
||||
},
|
||||
/* 切换语言 */
|
||||
changeLanguage({key}) {
|
||||
this.$emit('change-language', key);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
240
src/layout/index.vue
Normal file
240
src/layout/index.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<!-- 框架布局 -->
|
||||
<template>
|
||||
<ele-pro-layout
|
||||
ref="layout"
|
||||
:i18n="i18n"
|
||||
:menus="user.menus"
|
||||
:home-title="homeTitle"
|
||||
:project-name="projectName"
|
||||
:show-content="showContent"
|
||||
v-model:show-setting="showSetting"
|
||||
:need-setting="setting.needSetting"
|
||||
:hide-footers="setting.hideFooters"
|
||||
:hide-sidebars="setting.hideSidebars"
|
||||
:repeatable-tabs="setting.repeatableTabs"
|
||||
:tabs="theme.tabs"
|
||||
:color="theme.color"
|
||||
:collapse="theme.collapse"
|
||||
:head-style="theme.headStyle"
|
||||
:side-style="theme.sideStyle"
|
||||
:layout-style="theme.layoutStyle"
|
||||
:side-menu-style="theme.sideMenuStyle"
|
||||
:fixed-body="theme.fixedBody"
|
||||
:fixed-header="theme.fixedHeader"
|
||||
:fixed-sidebar="theme.fixedSidebar"
|
||||
:body-full="theme.bodyFull"
|
||||
:show-footer="theme.showFooter"
|
||||
:colorful-icon="theme.colorfulIcon"
|
||||
:logo-auto-size="theme.logoAutoSize"
|
||||
:side-unique-open="theme.sideUniqueOpen"
|
||||
:show-tabs="theme.showTabs"
|
||||
:tab-style="theme.tabStyle"
|
||||
:dark-mode="theme.darkMode"
|
||||
:weak-mode="theme.weakMode"
|
||||
@logo-click="onLogoClick"
|
||||
@reload-page="reloadPage"
|
||||
@update-screen="updateScreen"
|
||||
@update-collapse="updateCollapse"
|
||||
@tab-add="tabAdd"
|
||||
@tab-remove="tabRemove"
|
||||
@tab-remove-all="tabRemoveAll"
|
||||
@tab-remove-left="tabRemoveLeft"
|
||||
@tab-remove-right="tabRemoveRight"
|
||||
@tab-remove-other="tabRemoveOther"
|
||||
@change-style="changeStyle"
|
||||
@change-color="changeColor"
|
||||
@change-dark-mode="changeDarkMode"
|
||||
@change-weak-mode="changeWeakMode"
|
||||
@set-home-components="setHomeComponents">
|
||||
<!-- logo图标 -->
|
||||
<template #logo>
|
||||
<img src="@/assets/logo.svg" alt="logo"/>
|
||||
</template>
|
||||
<!-- 顶栏右侧区域 -->
|
||||
<template #right>
|
||||
<ele-header-right
|
||||
ref="header"
|
||||
:show-setting="setting.needSetting"
|
||||
@change-language="changeLanguage"
|
||||
@item-click="onItemClick"/>
|
||||
</template>
|
||||
<!-- 全局页脚 -->
|
||||
<template #footer>
|
||||
<ele-footer/>
|
||||
</template>
|
||||
<!-- 修改密码弹窗 -->
|
||||
<ele-password v-model:visible="showPassword"/>
|
||||
</ele-pro-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import EleHeaderRight from './header-right';
|
||||
import ElePassword from './password';
|
||||
import EleFooter from './footer';
|
||||
import setting from '@/config/setting';
|
||||
import {
|
||||
reloadPageTab,
|
||||
addPageTab,
|
||||
removePageTab,
|
||||
removeAllPageTab,
|
||||
removeLeftPageTab,
|
||||
removeRightPageTab,
|
||||
removeOtherPageTab
|
||||
} from '@/utils/page-tab-util';
|
||||
|
||||
export default {
|
||||
name: 'EleLayout',
|
||||
components: {
|
||||
EleHeaderRight,
|
||||
ElePassword,
|
||||
EleFooter
|
||||
},
|
||||
computed: {
|
||||
// 主页标题, 移除国际化上面template中使用:home-title="setting.homeTitle"
|
||||
homeTitle() {
|
||||
return this.$t('layout.home');
|
||||
},
|
||||
...mapGetters(['theme', 'user'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 全局配置
|
||||
setting: setting,
|
||||
// 是否显示修改密码弹窗
|
||||
showPassword: false,
|
||||
// 是否显示主题设置抽屉
|
||||
showSetting: false,
|
||||
// 是否显示主体部分
|
||||
showContent: true,
|
||||
// 项目名
|
||||
projectName: process.env.VUE_APP_NAME
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// 获取用户信息
|
||||
this.getUserInfo();
|
||||
},
|
||||
methods: {
|
||||
/* 获取当前用户信息 */
|
||||
getUserInfo() {
|
||||
if (setting.userUrl) {
|
||||
this.$http.get(setting.userUrl).then((res) => {
|
||||
const result = setting.parseUser ? setting.parseUser(res.data) : res.data;
|
||||
if (result.code === 0) {
|
||||
const user = result.data;
|
||||
this.$store.dispatch('user/setUser', user);
|
||||
this.$store.dispatch('user/setRoles', user ? user.roles : null);
|
||||
this.$store.dispatch('user/setAuthorities', user ? user.authorities : null);
|
||||
} else if (result.msg) {
|
||||
this.$message.error(result.msg);
|
||||
}
|
||||
// 在用户权限信息请求完成后再渲染主体部分, 以免权限控制指令不生效
|
||||
this.showContent = true;
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
this.showContent = true;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
/* 顶栏右侧点击 */
|
||||
onItemClick(key) {
|
||||
if (key === 'password') {
|
||||
this.showPassword = true;
|
||||
} else if (key === 'setting') {
|
||||
this.showSetting = true;
|
||||
}
|
||||
},
|
||||
/* 刷新页签 */
|
||||
reloadPage() {
|
||||
reloadPageTab();
|
||||
},
|
||||
/* logo点击事件 */
|
||||
onLogoClick(isHome) {
|
||||
if (!isHome) {
|
||||
this.$router.push('/');
|
||||
}
|
||||
},
|
||||
/* 更新collapse */
|
||||
updateCollapse(value) {
|
||||
this.$store.dispatch('theme/set', {key: 'collapse', value: value});
|
||||
},
|
||||
/* 更新屏幕尺寸 */
|
||||
updateScreen() {
|
||||
this.$store.dispatch('theme/updateScreen');
|
||||
const checkFullscreen = this.$refs.header.checkFullscreen;
|
||||
checkFullscreen && checkFullscreen();
|
||||
},
|
||||
/* 切换主题风格 */
|
||||
changeStyle(value) {
|
||||
this.$store.dispatch('theme/set', value);
|
||||
},
|
||||
/* 切换主题色 */
|
||||
changeColor(value) {
|
||||
const hide = this.$message.loading({content: '正在加载主题...'});
|
||||
this.$store.dispatch('theme/setColor', value).then(() => {
|
||||
hide();
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
hide();
|
||||
this.$message.error('主题加载失败');
|
||||
});
|
||||
},
|
||||
changeDarkMode(value) {
|
||||
this.$store.dispatch('theme/setDarkMode', value);
|
||||
},
|
||||
changeWeakMode(value) {
|
||||
this.$store.dispatch('theme/setWeakMode', value);
|
||||
},
|
||||
setHomeComponents(components) {
|
||||
this.$store.dispatch('theme/setHomeComponents', components);
|
||||
},
|
||||
/* 添加tab */
|
||||
tabAdd(value) {
|
||||
addPageTab(value);
|
||||
},
|
||||
/* 移除tab */
|
||||
tabRemove(obj) {
|
||||
removePageTab(obj.name).then(({lastPath}) => {
|
||||
if (obj.active === obj.name) {
|
||||
this.$router.push(lastPath || '/');
|
||||
}
|
||||
});
|
||||
},
|
||||
/* 移除全部tab */
|
||||
tabRemoveAll(active) {
|
||||
removeAllPageTab();
|
||||
if (active !== '/') {
|
||||
this.$router.push('/');
|
||||
}
|
||||
},
|
||||
/* 移除左边tab */
|
||||
tabRemoveLeft(value) {
|
||||
removeLeftPageTab(value);
|
||||
},
|
||||
/* 移除右边tab */
|
||||
tabRemoveRight(value) {
|
||||
removeRightPageTab(value);
|
||||
},
|
||||
/* 移除其它tab */
|
||||
tabRemoveOther(value) {
|
||||
removeOtherPageTab(value);
|
||||
},
|
||||
/* 菜单路由国际化对应的名称 */
|
||||
i18n(path, key/*, menu*/) {
|
||||
// 参数三menu即原始菜单数据, 如果需要菜单标题多语言数据从接口返回可用此参数获取对应的多语言标题
|
||||
// 例如下面这样写, 接口的菜单数据为{path: '/system/user', titles: {zh: '用户管理', en: 'User'}}
|
||||
// return menu ? menu.titles[this.$i18n.locale] : null;
|
||||
const k = 'route.' + key + '._name', title = this.$t(k);
|
||||
return title === k ? null : title;
|
||||
},
|
||||
/* 切换语言 */
|
||||
changeLanguage(lang) {
|
||||
this.$i18n.locale = lang;
|
||||
this.$refs.layout.changeLanguage();
|
||||
localStorage.setItem('i18n-lang', lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
278
src/layout/notice.vue
Normal file
278
src/layout/notice.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<!-- 顶栏消息通知图标 -->
|
||||
<template>
|
||||
<a-dropdown v-model:visible="visible" :trigger="['click']">
|
||||
<a-badge :count="allNum" class="ele-notice-trigger">
|
||||
<bell-outlined style="padding: 6px;"/>
|
||||
</a-badge>
|
||||
<template #overlay>
|
||||
<div class="ant-dropdown-menu ele-notice-pop">
|
||||
<div @click.stop="">
|
||||
<a-tabs v-model:active-key="active">
|
||||
<a-tab-pane key="notice" :tab="noticeTitle" force-render>
|
||||
<a-list item-layout="horizontal" :data-source="notice">
|
||||
<template #renderItem="{item}">
|
||||
<a-list-item>
|
||||
<a-list-item-meta :title="item.title" :description="item.time">
|
||||
<template #avatar>
|
||||
<a-avatar :style="{background: item.color}">
|
||||
<template #icon>
|
||||
<component :is="item.icon"/>
|
||||
</template>
|
||||
</a-avatar>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div v-if="notice.length" class="ele-cell ele-notice-actions">
|
||||
<div class="ele-cell-content" @click="clear('notice')">清空通知</div>
|
||||
<a-divider type="vertical"/>
|
||||
<div class="ele-cell-content" @click="more('notice')">查看更多</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="message" :tab="messageTitle" force-render>
|
||||
<a-list item-layout="horizontal" :data-source="message">
|
||||
<template #renderItem="{item}">
|
||||
<a-list-item>
|
||||
<a-list-item-meta :title="item.title">
|
||||
<template #avatar>
|
||||
<a-avatar :src="item.avatar"/>
|
||||
</template>
|
||||
<template #description>
|
||||
<div>{{ item.content }}</div>
|
||||
<div>{{ item.time }}</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div v-if="message.length" class="ele-cell ele-notice-actions">
|
||||
<div class="ele-cell-content" @click="clear('message')">清空私信</div>
|
||||
<a-divider type="vertical"/>
|
||||
<div class="ele-cell-content" @click="more('message')">查看更多</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="todo" :tab="todoTitle" force-render>
|
||||
<a-list item-layout="horizontal" :data-source="todo">
|
||||
<template #renderItem="{item}">
|
||||
<a-list-item>
|
||||
<a-list-item-meta :description="item.desc">
|
||||
<template #title>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">{{ item.title }}</div>
|
||||
<a-tag :color="['', 'red', 'blue'][item.state]">
|
||||
{{ ['未开始', '即将到期', '进行中'][item.state] }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<div v-if="todo.length" class="ele-cell ele-notice-actions">
|
||||
<div class="ele-cell-content" @click="clear('todo')">清空待办</div>
|
||||
<a-divider type="vertical"/>
|
||||
<div class="ele-cell-content" @click="more('todo')">查看更多</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
BellOutlined,
|
||||
NotificationFilled,
|
||||
PushpinFilled,
|
||||
VideoCameraFilled,
|
||||
CarryOutFilled,
|
||||
BellFilled
|
||||
} from '@ant-design/icons-vue';
|
||||
|
||||
export default {
|
||||
name: 'EleNotice',
|
||||
components: {
|
||||
BellOutlined,
|
||||
NotificationFilled,
|
||||
PushpinFilled,
|
||||
VideoCameraFilled,
|
||||
CarryOutFilled,
|
||||
BellFilled
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
active: 'notice',
|
||||
notice: [
|
||||
{
|
||||
color: '#60B2FC',
|
||||
icon: 'NotificationFilled',
|
||||
title: '你收到了一封14份新周报',
|
||||
time: '2020-07-27 18:30:18'
|
||||
},
|
||||
{
|
||||
color: '#F5686F',
|
||||
icon: 'PushpinFilled',
|
||||
title: '许经理同意了你的请假申请',
|
||||
time: '2020-07-27 09:08:36'
|
||||
},
|
||||
{
|
||||
color: '#7CD734',
|
||||
icon: 'VideoCameraFilled',
|
||||
title: '陈总邀请你参加视频会议',
|
||||
time: '2020-07-26 18:30:01'
|
||||
},
|
||||
{
|
||||
color: '#FAAD14',
|
||||
icon: 'CarryOutFilled',
|
||||
title: '你推荐的刘诗雨已通过第三轮面试',
|
||||
time: '2020-07-25 16:38:46'
|
||||
},
|
||||
{
|
||||
color: '#2BCACD',
|
||||
icon: 'BellFilled',
|
||||
title: '你的6月加班奖金已发放',
|
||||
time: '2020-07-25 11:03:31'
|
||||
}
|
||||
],
|
||||
message: [
|
||||
{
|
||||
avatar: 'https://cdn.eleadmin.com/20200609/c184eef391ae48dba87e3057e70238fb.jpg',
|
||||
title: 'SunSmile 评论了你的日志',
|
||||
content: '写的不错, 以后多多向你学习~',
|
||||
time: '2020-07-27 18:30:18'
|
||||
},
|
||||
{
|
||||
avatar: 'https://cdn.eleadmin.com/20200609/948344a2a77c47a7a7b332fe12ff749a.jpg',
|
||||
title: '刘诗雨 点赞了你的日志',
|
||||
content: '写的不错, 以后多多向你学习~',
|
||||
time: '2020-07-27 09:08:36'
|
||||
},
|
||||
{
|
||||
avatar: 'https://cdn.eleadmin.com/20200609/2d98970a51b34b6b859339c96b240dcd.jpg',
|
||||
title: '酷酷的大叔 评论了你的周报',
|
||||
content: '写的不错, 以后多多向你学习~',
|
||||
time: '2020-07-26 18:30:01'
|
||||
},
|
||||
{
|
||||
avatar: 'https://cdn.eleadmin.com/20200609/f6bc05af944a4f738b54128717952107.jpg',
|
||||
title: 'Jasmine 点赞了你的周报',
|
||||
content: '写的不错, 以后多多向你学习~',
|
||||
time: '2020-07-25 11:03:31'
|
||||
}
|
||||
],
|
||||
todo: [
|
||||
{
|
||||
state: 0,
|
||||
title: '刘诗雨的请假审批',
|
||||
desc: '刘诗雨在 07-27 18:30 提交的请假申请'
|
||||
},
|
||||
{
|
||||
state: 1,
|
||||
title: '第三方代码紧急变更',
|
||||
desc: '需要在 2020-07-27 之前完成'
|
||||
},
|
||||
{
|
||||
state: 2,
|
||||
title: '信息安全考试',
|
||||
desc: '需要在 2020-07-26 18:30 前完成'
|
||||
},
|
||||
{
|
||||
state: 2,
|
||||
title: 'EleAdmin发布新版本',
|
||||
desc: '需要在 2020-07-25 11:03 前完成'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 通知标题
|
||||
noticeTitle() {
|
||||
return this.notice.length ? `通知(${this.notice.length})` : '通知';
|
||||
},
|
||||
// 私信标题
|
||||
messageTitle() {
|
||||
return this.message.length ? `私信(${this.message.length})` : '私信';
|
||||
},
|
||||
// 待办标题
|
||||
todoTitle() {
|
||||
return this.todo.length ? `待办(${this.todo.length})` : '待办';
|
||||
},
|
||||
// 所有消息数量
|
||||
allNum() {
|
||||
return this.notice.length + this.message.length + this.todo.length;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 清空消息 */
|
||||
clear(type) {
|
||||
if (type === 'notice') {
|
||||
this.notice = [];
|
||||
} else if (type === 'message') {
|
||||
this.message = [];
|
||||
} else if (type === 'todo') {
|
||||
this.todo = [];
|
||||
}
|
||||
},
|
||||
/* 查看更多 */
|
||||
more(type) {
|
||||
this.visible = false;
|
||||
if (this.$route.path !== '/user/message' || this.$route.query.type !== type) {
|
||||
this.$router.push({path: '/user/message', query: {type: type}});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.ele-notice-trigger.ant-badge {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.ele-notice-pop.ant-dropdown-menu {
|
||||
padding: 0;
|
||||
width: 336px;
|
||||
max-width: 100%;
|
||||
margin-top: 11px;
|
||||
}
|
||||
|
||||
/* 内容 */
|
||||
.ele-notice-pop .ant-tabs-nav-wrap {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ele-notice-pop .ant-list-item {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
transition: background-color .3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ele-notice-pop .ant-list-item:hover {
|
||||
background: hsla(0, 0%, 60%, .05);
|
||||
}
|
||||
|
||||
.ele-notice-pop .ant-tag {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.ele-notice-pop .ele-notice-actions {
|
||||
border-top: 1px solid hsla(0, 0%, 60%, .15);
|
||||
}
|
||||
|
||||
.ele-notice-pop .ele-notice-actions > .ele-cell-content {
|
||||
line-height: 46px;
|
||||
text-align: center;
|
||||
transition: background-color .3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ele-notice-pop .ele-notice-actions > .ele-cell-content:hover {
|
||||
background: hsla(0, 0%, 60%, .05);
|
||||
}
|
||||
</style>
|
||||
110
src/layout/password.vue
Normal file
110
src/layout/password.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<!-- 修改密码弹窗 -->
|
||||
<template>
|
||||
<a-modal
|
||||
:width="420"
|
||||
title="修改密码"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:body-style="{paddingBottom: '16px'}"
|
||||
@update:visible="onUpdateVisible"
|
||||
@cancel="onCancel"
|
||||
@ok="onOk">
|
||||
<a-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:label-col="{sm: {span: 6}}"
|
||||
:wrapper-col="{sm: {span: 18}}">
|
||||
<a-form-item label="旧密码" name="old">
|
||||
<a-input-password v-model:value="form.old" placeholder="请输入旧密码"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="新密码" name="password">
|
||||
<a-input-password v-model:value="form.password" placeholder="请输入新密码"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="确认密码" name="password2">
|
||||
<a-input-password v-model:value="form.password2" placeholder="请再次输入新密码"/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ElePassword',
|
||||
emits: ['update:visible'],
|
||||
props: {
|
||||
visible: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 表单数据
|
||||
form: {
|
||||
old: '',
|
||||
password: '',
|
||||
password2: ''
|
||||
},
|
||||
// 表单验证
|
||||
rules: {
|
||||
old: [
|
||||
{required: true, message: '请输入旧密码', type: 'string', trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{required: true, message: '请输入新密码', type: 'string', trigger: 'blur'}
|
||||
],
|
||||
password2: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
trigger: 'blur',
|
||||
validator: async (rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.reject('请再次输入新密码');
|
||||
}
|
||||
if (value === this.form.password) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject('两次输入密码不一致');
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// 按钮loading
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 保存修改 */
|
||||
onOk() {
|
||||
this.$refs.form.validate().then(() => {
|
||||
this.loading = true;
|
||||
this.$http.put('/main/password', {
|
||||
oldPsw: this.form.old,
|
||||
newPsw: this.form.password
|
||||
}).then(res => {
|
||||
this.loading = false;
|
||||
if (res.data.code === 0) {
|
||||
this.$message.success(res.data.msg);
|
||||
this.onUpdateVisible(false);
|
||||
} else {
|
||||
this.$message.error(res.data.msg);
|
||||
}
|
||||
}).catch(e => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
/* 关闭回调 */
|
||||
onCancel() {
|
||||
this.form = {};
|
||||
this.loading = false;
|
||||
this.$refs.form.resetFields();
|
||||
},
|
||||
/* 修改visible */
|
||||
onUpdateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user