修改下目录结构

This commit is contained in:
zhuoda
2022-10-24 20:10:37 +08:00
parent 692ab99e0c
commit 0996e90df0
562 changed files with 0 additions and 103096 deletions

View File

@@ -1,126 +0,0 @@
<!--
* 头像
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:02:01
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-dropdown class="header-trigger">
<div class="wrapper">
<a-avatar style="margin: 0 5px" :size="24" id="smartAdminAvatar">
{{ avatarName }}
</a-avatar>
<span class="name">{{ actualName }}</span>
</div>
<template #overlay>
<a-menu :class="['avatar-menu']">
<a-menu-item @click="onRefresh">
<span>刷新权限</span>
</a-menu-item>
<a-menu-item @click="showUpdatePwdModal">
<span>修改密码</span>
</a-menu-item>
<a-menu-item @click="onLogout">
<span>退出登录</span>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<HeaderResetPassword ref="resetPasswordRef" />
</template>
<script setup>
import { computed, ref, onMounted } from 'vue';
import { loginApi } from '/@/api/system/login/login-api';
import { useUserStore } from '/@/store/modules/system/user';
import { clearAllCoolies } from '/@/utils/cookie-util';
import { localClear } from '/@/utils/local-util';
import { smartSentry } from '/@/lib/smart-sentry';
import HeaderResetPassword from './header-reset-password-modal/index.vue';
// 头像背景颜色
const AVATAR_BACKGROUND_COLOR_ARRAY = ['#87d068', '#00B853', '#f56a00', '#1890ff'];
//监听退出登录方法
async function onLogout() {
localClear();
clearAllCoolies();
useUserStore().logout();
try {
await loginApi.logout();
} catch (e) {
smartSentry.captureError(e);
} finally {
location.reload();
}
}
// 刷新用户信息(包含用户基础信息、权限信息等等)
async function onRefresh() {
await loginApi.refresh();
location.reload();
}
// ------------------------ 修改密码 ------------------------
const resetPasswordRef = ref();
function showUpdatePwdModal() {
resetPasswordRef.value.showModal();
}
// ------------------------ 以下是 头像和姓名 相关 ------------------------
const avatarName = ref('');
const actualName = computed(() => useUserStore().actualName);
// 更新头像信息
function updateAvatar() {
if (useUserStore().actualName) {
avatarName.value = useUserStore().actualName.substr(0, 1);
const avatar = document.getElementById('smartAdminAvatar');
if (avatar) {
avatar.style.backgroundColor = AVATAR_BACKGROUND_COLOR_ARRAY[hashcode(avatarName.value) % 4];
}
}
}
/**
* 通过计算固定字符串的hash来选择颜色这也每次登录的颜色是相同的
*/
function hashcode(str) {
let hash = 1,
i,
chr;
if (str.length === 0) return hash;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
onMounted(updateAvatar);
</script>
<style lang="less" scoped>
.wrapper {
cursor: pointer;
display: flex;
align-items: center;
}
.header-trigger {
height: @header-user-height;
line-height: @header-user-height;
.avatar {
vertical-align: middle;
}
.name {
margin-left: 5px;
font-weight: 500;
}
}
</style>

View File

@@ -1,116 +0,0 @@
<!--
* 消息通知
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:17:18
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-dropdown trigger="click" v-model:visible="show">
<div @click="fetchMessage">
<a-badge count="12">
<div style="width: 26px; height: 26px">
<BellOutlined :style="{ fontSize: '18px' }" />
</div>
</a-badge>
</div>
<template #overlay>
<div>
<a-spin :spinning="loading">
<a-tabs class="dropdown-tabs" centered :tabBarStyle="{ textAlign: 'center' }" style="width: 300px">
<a-tab-pane tab="通知" key="1">
<a-list class="tab-pane" size="small">
<a-list-item>
<a-list-item-meta description="7天前">
<template #title>
<a href="#">今天洛阳天气39°c洛阳变各阳...</a>
</template>
<template #avatar>
<a-avatar src="https://zhuoda.vip/images/blog/profile-128-128.jpg" />
</template>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta description="7天前">
<template #title>
<a href="#">六月的雨 就是无情的你...</a>
</template>
<template #avatar>
<a-avatar src="https://zhuoda.vip/images/blog/profile-128-128.jpg" />
</template>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta description="7天前">
<template #title>
<a href="#">今年河南天气炎热河南变可南...</a>
</template>
<template #avatar>
<a-avatar src="https://zhuoda.vip/images/blog/profile-128-128.jpg" />
</template>
</a-list-item-meta>
</a-list-item>
</a-list>
</a-tab-pane>
<a-tab-pane tab="消息" key="2">
<a-list class="tab-pane" />
</a-tab-pane>
<a-tab-pane tab="待办" key="3">
<a-list class="tab-pane" />
</a-tab-pane>
</a-tabs>
</a-spin>
</div>
</template>
</a-dropdown>
</template>
<script setup>
import { ref } from 'vue';
import { BellOutlined } from '@ant-design/icons-vue';
defineExpose({ showMessage });
function showMessage() {
show.value = true;
}
const loading = ref(false);
const show = ref(false);
const fetchMessage = () => {
if (loading.value) {
loading.value = false;
return;
}
loading.value = true;
setTimeout(() => {
loading.value = false;
}, 700);
};
</script>
<style lang="less">
.header-notice {
display: inline-block;
transition: all 0.3s;
span {
vertical-align: initial;
}
.notice-badge {
color: inherit;
}
}
.dropdown-tabs {
background-color: @base-bg-color;
box-shadow: 0 2px 8px @shadow-color;
border-radius: 4px;
}
</style>

View File

@@ -1,85 +0,0 @@
<!--
* 修改密码
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:02:01
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal :visible="visible" title="修改密码" ok-text="确认" cancel-text="取消" @ok="updatePwd" @cancel="cancelModal">
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }">
<a-form-item label="原密码" name="oldPassword">
<a-input v-model:value.trim="form.oldPassword" type="password" placeholder="请输入原密码" />
</a-form-item>
<a-form-item label="新密码" name="newPassword" :help="tips">
<a-input v-model:value.trim="form.newPassword" type="password" placeholder="请输入新密码" />
</a-form-item>
<a-form-item label="确认密码" name="confirmPwd" :help="tips">
<a-input v-model:value.trim="form.confirmPwd" type="password" placeholder="请输入确认密码" />
</a-form-item>
</a-form>
</a-modal>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { message } from 'ant-design-vue';
import { employeeApi } from '/@/api/system/employee/employee-api';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { smartSentry } from '/@/lib/smart-sentry';
const visible = ref(false);
const formRef = ref();
const tips = '字母(不限大小写)+数字组合6-15位'; //校验规则
const reg = /(^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,15}$)/; //校验正则
const rules = {
oldPassword: [{ required: true, message: '请输入原密码' }],
newPassword: [{ type: 'string', pattern: reg, message: '密码格式错误' }],
confirmPwd: [{ type: 'string', pattern: reg, message: '请输入确认密码' }],
};
const formDefault = {
oldPassword: '',
newPassword: '',
};
let form = reactive({
...formDefault,
});
async function updatePwd() {
formRef.value
.validate()
.then(async () => {
if (form.newPassword != form.confirmPwd) {
message.error('新密码与确认密码不一致');
return;
}
SmartLoading.show();
try {
await employeeApi.updateEmployeePassword(form);
message.success('修改成功');
visible.value = false;
} catch (error) {
smartSentry.captureError(error);
} finally {
SmartLoading.hide();
}
})
.catch((error) => {
console.log('error', error);
message.error('参数验证错误,请仔细填写表单数据!');
});
}
function showModal() {
visible.value = true;
}
function cancelModal() {
visible.value = false;
}
defineExpose({ showModal });
</script>

View File

@@ -1,201 +0,0 @@
<!--
* 设置模块
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:18:20
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-drawer :title="$t('setting.title')" placement="right" :visible="visible" @close="close">
<a-form layout="horizontal" :label-col="{ span: 8 }">
<a-form-item label="语言/Language">
<a-select v-model:value="formState.language" @change="changeLanguage" style="width: 120px">
<a-select-option v-for="item in i18nList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="菜单布局">
<a-radio-group @change="changeLayout" button-style="solid" v-model:value="formState.layout">
<a-radio-button v-for="item in $smartEnumPlugin.getValueDescList('LAYOUT_ENUM')" :key="item.value" :value="item.value">
{{ item.desc }}
</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="菜单宽度" v-if="formState.layout === LAYOUT_ENUM.SIDE.value">
<a-input-number @change="changeSideMenuWidth" v-model:value="formState.sideMenuWidth" :min="1" />
像素px
</a-form-item>
<a-form-item label="菜单主题">
<a-radio-group v-model:value="formState.sideMenuTheme" button-style="solid" @change="changeMenuTheme">
<a-radio-button value="dark">Dark</a-radio-button>
<a-radio-button value="light">Light</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="面包屑">
<a-switch @change="changeBreadCrumbFlag" v-model:checked="formState.breadCrumbFlag" checked-children="显示" un-checked-children="隐藏" />
</a-form-item>
<a-form-item label="标签页">
<a-switch @change="changePageTagFlag" v-model:checked="formState.pageTagFlag" checked-children="显示" un-checked-children="隐藏" />
</a-form-item>
<a-form-item label="页脚">
<a-switch @change="changeFooterFlag" v-model:checked="formState.footerFlag" checked-children="显示" un-checked-children="隐藏" />
</a-form-item>
<a-form-item label="帮助文档">
<a-switch @change="changeHelpDocFlag" v-model:checked="formState.helpDocFlag" checked-children="显示" un-checked-children="隐藏" />
</a-form-item>
</a-form>
<div class="footer">
<a-button style="margin-right: 8px" type="primary" @click="copy">复制配置信息</a-button>
<a-button type="block" danger @click="reset">恢复默认配置 </a-button>
</div>
</a-drawer>
</template>
<script setup>
import { ref, reactive, h } from 'vue';
import { i18nList } from '/@/i18n/index';
import { useI18n } from 'vue-i18n';
import localStorageKeyConst from '/@/constants/local-storage-key-const';
import { LAYOUT_ENUM } from '/@/constants/layout-const';
import { localRead, localSave } from '/@/utils/local-util';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { Modal } from 'ant-design-vue';
import { appDefaultConfig } from '/@/config/app-config';
// ----------------- modal 显示与隐藏 -----------------
const visible = ref(false);
defineExpose({
show,
});
function close() {
visible.value = false;
}
function show() {
visible.value = true;
}
// ----------------- 配置信息操作 -----------------
function copy() {
let content = JSON.stringify(formState, null, 2);
// 创建元素用于复制
const aux = document.createElement('input');
// 设置元素内容
aux.setAttribute('value', content);
// 将元素插入页面进行调用
document.body.appendChild(aux);
// 复制内容
aux.select();
// 将内容复制到剪贴板
document.execCommand('copy');
// 删除创建元素
document.body.removeChild(aux);
Modal.success({
title: '复制成功',
content: h('div', {}, [h('p', '可以直接修改 /src/config/app-config.js 文件保存此配置')]),
});
}
function reset() {
for (const k in appDefaultConfig) {
formState[k] = appDefaultConfig[k];
}
appConfigStore.reset();
}
// ----------------- 表单数据实时保存到localstorage -----------------
const appConfigStore = useAppConfigStore();
useAppConfigStore().$subscribe((mutation, state) => {
localSave(localStorageKeyConst.APP_CONFIG, JSON.stringify(state));
});
// ----------------- 表单 -----------------
let formValue = {
// i18n 语言选择
language: appConfigStore.language,
// 布局: side 或者 side-expand
layout: appConfigStore.layout,
// 侧边菜单宽度
sideMenuWidth: appConfigStore.sideMenuWidth,
// 菜单主题
sideMenuTheme: appConfigStore.sideMenuTheme,
// 标签页
pageTagFlag: appConfigStore.pageTagFlag,
// 面包屑
breadCrumbFlag: appConfigStore.breadCrumbFlag,
// 页脚
footerFlag: appConfigStore.footerFlag,
// 帮助文档
helpDocFlag: appConfigStore.helpDocFlag,
};
let formState = reactive({ ...formValue });
const { locale } = useI18n();
function changeLanguage(languageValue) {
locale.value = languageValue;
appConfigStore.$patch({
language: languageValue,
});
}
function changeLayout(e) {
appConfigStore.$patch({
layout: e.target.value,
});
}
function changeSideMenuWidth(value) {
appConfigStore.$patch({
sideMenuWidth: value,
});
}
function changeMenuTheme(e) {
appConfigStore.$patch({
sideMenuTheme: e.target.value,
});
}
function changeBreadCrumbFlag(e) {
appConfigStore.$patch({
breadCrumbFlag: e,
});
}
function changePageTagFlag(e) {
appConfigStore.$patch({
pageTagFlag: e,
});
}
function changeFooterFlag(e) {
appConfigStore.$patch({
footerFlag: e,
});
}
function changeHelpDocFlag(e) {
appConfigStore.$patch({
helpDocFlag: e,
});
}
</script>
<style lang="less" scoped>
.footer {
position: absolute;
right: 0;
bottom: 0;
width: 100%;
border-top: 1px solid #e9e9e9;
padding: 10px 16px;
background: #fff;
text-align: left;
z-index: 1;
}
</style>

View File

@@ -1,108 +0,0 @@
<!--
* 头部一整行
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:18:20
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-space :size="10">
<div class="setting">
<a-input-search
@click="search"
style="margin-right: 30px; width: 250px"
placeholder="1024创新实验室、小镇程序员"
enter-button="搜索"
size="small"
/>
<!---消息通知--->
<HeaderMessage ref="headerMessage" />
<!---国际化--->
<!-- <a-button type="text" @click="showSetting" class="operate-icon">
<template #icon><switcher-outlined /></template>
i18n
</a-button> -->
<!---设置--->
<a-button type="text" @click="showSetting" class="operate-icon">
<template #icon><setting-outlined /></template>
</a-button>
</div>
<!---头像信息--->
<div class="user-space-item">
<HeaderAvatar />
</div>
<!---帮助文档--->
<div class="user-space-item" @click="showHelpDoc">
<question-circle-two-tone style="font-size: 18px; margin-right: 5px; margin-top: 5px" />
<span>帮助文档</span>
</div>
<HeaderSetting ref="headerSetting" />
</a-space>
</template>
<script setup>
import HeaderAvatar from './header-avatar.vue';
import HeaderSetting from './header-setting.vue';
import HeaderMessage from './header-message.vue';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { ref } from 'vue';
// 设置
const headerSetting = ref();
function showSetting() {
headerSetting.value.show();
}
//消息通知
const headerMessage = ref();
function showMessage() {
headerMessage.value.showMessage();
}
//帮助文档
function showHelpDoc() {
useAppConfigStore().showHelpDoc();
}
//搜索
function search(){
window.open("https://1024lab.net");
}
</script>
<style lang="less" scoped>
.user-space-item {
height: 100%;
color: inherit;
padding: 0 12px;
cursor: pointer;
align-self: center;
a {
color: inherit;
i {
font-size: 16px;
}
}
}
.user-space-item:hover {
color: @primary-color;
background: @hover-bg-color;
}
.setting {
height: @header-user-height;
line-height: @header-user-height;
vertical-align: middle;
display: flex;
align-items: center;
}
.operate-icon {
margin-left: 20px;
}
</style>