整理前端代码,调整命名,调整规范,移除无用代码
This commit is contained in:
parent
6cdca2758f
commit
0db495ffac
17
.eslintrc.js
17
.eslintrc.js
@ -11,17 +11,32 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
},
|
||||
extends: ['plugin:vue/vue3-essential', 'airbnb-base', 'prettier'],
|
||||
// 配置这些自动引入的库 避免vscode报红
|
||||
extends: [
|
||||
'plugin:vue/vue3-essential',
|
||||
'airbnb-base',
|
||||
'prettier',
|
||||
// collections
|
||||
'vue-global-api/reactivity',
|
||||
'vue-global-api/lifecycle',
|
||||
'vue-global-api/component',
|
||||
// single apis
|
||||
'vue-global-api/ref',
|
||||
'vue-global-api/toRef',
|
||||
],
|
||||
extends: [],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['vue'],
|
||||
// ESLint 是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。
|
||||
rules: {
|
||||
'import/no-cycle': 0,
|
||||
'import/prefer-default-export': 0,
|
||||
'import/order': 0,
|
||||
'no-lonely-if': 0,
|
||||
'no-undef': 1,
|
||||
'no-unused-expressions': 0,
|
||||
'vue/multi-word-component-names': [
|
||||
'error',
|
||||
|
||||
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@ -1 +0,0 @@
|
||||
custom: http://doc.ruoyi.vip/ruoyi-vue/other/donate.html
|
||||
@ -1,3 +1,4 @@
|
||||
// 代码格式化
|
||||
module.exports = {
|
||||
printWidth: 120,
|
||||
tabWidth: 2,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import request from '@/utils/request';
|
||||
import { parseStrEmpty } from '@/utils/ruoyi';
|
||||
import { parseStrEmpty } from '@/utils/common';
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
|
||||
@ -20,8 +20,12 @@
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" v-if="showTip">
|
||||
请上传
|
||||
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
||||
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
||||
<template v-if="fileSize">
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
</template>
|
||||
<template v-if="fileType">
|
||||
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
|
||||
</template>
|
||||
的文件
|
||||
</div>
|
||||
<!-- 文件列表 -->
|
||||
@ -39,7 +43,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getToken } from '@/utils/token';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: [String, Object, Array],
|
||||
@ -73,28 +77,30 @@ const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
const uploadFileUrl = ref(`${import.meta.env.VITE_APP_BASE_API}/file/upload`); // 上传的图片服务器地址
|
||||
const headers = ref({ Authorization: `Bearer ${getToken()}` });
|
||||
const fileList = ref([]);
|
||||
const showTip = computed(
|
||||
() => props.isShowTip && (props.fileType || props.fileSize),
|
||||
);
|
||||
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize));
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
if (val) {
|
||||
let temp = 1;
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map((item) => {
|
||||
if (typeof item === 'string') {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
item.uid = item.uid || new Date().getTime() + temp++;
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (val) {
|
||||
let temp = 1;
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map((item) => {
|
||||
if (typeof item === 'string') {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
item.uid = item.uid || new Date().getTime() + temp++;
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
// 上传前校检格式和大小
|
||||
function handleBeforeUpload(file) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="{ 'show': show }" class="header-search">
|
||||
<div :class="{ show: show }" class="header-search">
|
||||
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
|
||||
<el-select
|
||||
ref="headerSearchSelectRef"
|
||||
@ -12,14 +12,19 @@
|
||||
class="header-search-select"
|
||||
@change="change"
|
||||
>
|
||||
<el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
|
||||
<el-option
|
||||
v-for="option in options"
|
||||
:key="option.item.path"
|
||||
:value="option.item"
|
||||
:label="option.item.title.join(' > ')"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Fuse from 'fuse.js';
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import { getNormalPath } from '@/utils/common';
|
||||
import { isHttp } from '@/utils/validate';
|
||||
|
||||
const search = ref('');
|
||||
@ -67,13 +72,16 @@ function initFuse(list) {
|
||||
distance: 100,
|
||||
maxPatternLength: 32,
|
||||
minMatchCharLength: 1,
|
||||
keys: [{
|
||||
name: 'title',
|
||||
weight: 0.7,
|
||||
}, {
|
||||
name: 'path',
|
||||
weight: 0.3,
|
||||
}],
|
||||
keys: [
|
||||
{
|
||||
name: 'title',
|
||||
weight: 0.7,
|
||||
},
|
||||
{
|
||||
name: 'path',
|
||||
weight: 0.3,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
// Filter out the routes that can be displayed in the sidebar
|
||||
@ -83,7 +91,9 @@ function generateRoutes(routes, basePath = '', prefixTitle = []) {
|
||||
|
||||
for (const r of routes) {
|
||||
// skip hidden router
|
||||
if (r.hidden) { continue; }
|
||||
if (r.hidden) {
|
||||
continue;
|
||||
}
|
||||
const p = r.path.length > 0 && r.path[0] === '/' ? r.path : `/${r.path}`;
|
||||
const data = {
|
||||
path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path,
|
||||
@ -139,7 +149,7 @@ watch(searchPool, (list) => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
<style lang="scss" scoped>
|
||||
.header-search {
|
||||
font-size: 0 !important;
|
||||
|
||||
|
||||
@ -26,27 +26,19 @@
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
</template>
|
||||
<template v-if="fileType">
|
||||
格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
|
||||
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
|
||||
</template>
|
||||
的文件
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="预览"
|
||||
width="800px"
|
||||
append-to-body
|
||||
>
|
||||
<img
|
||||
:src="dialogImageUrl"
|
||||
style="display: block; max-width: 100%; margin: 0 auto"
|
||||
/>
|
||||
<el-dialog v-model="dialogVisible" title="预览" width="800px" append-to-body>
|
||||
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getToken } from '@/utils/token';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: [String, Object, Array],
|
||||
@ -82,30 +74,32 @@ const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
const uploadImgUrl = ref(`${import.meta.env.VITE_APP_BASE_API}/file/upload`); // 上传的图片服务器地址
|
||||
const headers = ref({ Authorization: `Bearer ${getToken()}` });
|
||||
const fileList = ref([]);
|
||||
const showTip = computed(
|
||||
() => props.isShowTip && (props.fileType || props.fileSize),
|
||||
);
|
||||
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize));
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
if (val) {
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map((item) => {
|
||||
if (typeof item === 'string') {
|
||||
if (item.indexOf(baseUrl) === -1) {
|
||||
item = { name: baseUrl + item, url: baseUrl + item };
|
||||
} else {
|
||||
item = { name: item, url: item };
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (val) {
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : props.modelValue.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
fileList.value = list.map((item) => {
|
||||
if (typeof item === 'string') {
|
||||
if (item.indexOf(baseUrl) === -1) {
|
||||
item = { name: baseUrl + item, url: baseUrl + item };
|
||||
} else {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
fileList.value = [];
|
||||
return [];
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
// 删除图片
|
||||
function handleRemove(file, files) {
|
||||
@ -141,9 +135,7 @@ function handleBeforeUpload(file) {
|
||||
isImg = file.type.indexOf('image') > -1;
|
||||
}
|
||||
if (!isImg) {
|
||||
proxy.$modal.msgError(
|
||||
`文件格式不正确, 请上传${props.fileType.join('/')}图片格式文件!`,
|
||||
);
|
||||
proxy.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}图片格式文件!`);
|
||||
return false;
|
||||
}
|
||||
if (props.fileSize) {
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
// 布局设置 在src/store/modules/settings 文件夹进行设置
|
||||
export default {
|
||||
/**
|
||||
* 网页标题
|
||||
*/
|
||||
title: import.meta.env.VITE_APP_TITLE,
|
||||
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
* src\assets\styles\sidebar.scss 具体配置
|
||||
*/
|
||||
sideTheme: 'theme-dark',
|
||||
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
*/
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* v-copyText 复制文本内容
|
||||
* Copyright (c) 2022 ruoyi
|
||||
*/
|
||||
* v-copyText 复制文本内容
|
||||
* Copyright (c) 2022 ruoyi
|
||||
*/
|
||||
|
||||
export default {
|
||||
beforeMount(el, { value, arg }) {
|
||||
@ -48,7 +48,7 @@ function copyTextToClipboard(input, { target = document.body } = {}) {
|
||||
let isSuccess = false;
|
||||
try {
|
||||
isSuccess = document.execCommand('copy');
|
||||
} catch { }
|
||||
} catch {}
|
||||
|
||||
element.remove();
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import hasRole from './permission/hasRole';
|
||||
import hasPermi from './permission/hasPermi';
|
||||
import hasPermission from './permission/hasPermission';
|
||||
import copyText from './common/copyText';
|
||||
|
||||
export default function directive(app) {
|
||||
app.directive('hasRole', hasRole);
|
||||
app.directive('hasPermi', hasPermi);
|
||||
app.directive('hasPermission', hasPermission);
|
||||
app.directive('copyText', copyText);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* v-hasPermi 操作权限处理
|
||||
* v-hasPermission 操作权限处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
@ -8,13 +8,15 @@ import store from '@/store';
|
||||
export default {
|
||||
mounted(el, binding, vnode) {
|
||||
const { value } = binding;
|
||||
const all_permission = '*:*:*';
|
||||
const permissions = store.getters && store.getters.permissions;
|
||||
const allPermissions = '*:*:*';
|
||||
const currentPermissions = store.getters && store.getters.permissions;
|
||||
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const permissionFlag = value;
|
||||
|
||||
const hasPermissions = permissions.some((permission) => all_permission === permission || permissionFlag.includes(permission));
|
||||
const hasPermissions = currentPermissions.some(
|
||||
(permission) => allPermissions === permission || permissionFlag.includes(permission),
|
||||
);
|
||||
|
||||
if (!hasPermissions) {
|
||||
el.parentNode && el.parentNode.removeChild(el);
|
||||
@ -8,13 +8,13 @@ import store from '@/store';
|
||||
export default {
|
||||
mounted(el, binding, vnode) {
|
||||
const { value } = binding;
|
||||
const super_admin = 'admin';
|
||||
const superAdmin = 'admin';
|
||||
const currentRole = store.getters && store.getters.role;
|
||||
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const roleFlag = value;
|
||||
|
||||
const hasRole = super_admin === currentRole || roleFlag.includes(currentRole);
|
||||
const hasRole = superAdmin === currentRole || roleFlag.includes(currentRole);
|
||||
|
||||
if (!hasRole) {
|
||||
el.parentNode && el.parentNode.removeChild(el);
|
||||
|
||||
@ -1,10 +1,20 @@
|
||||
<template>
|
||||
<div v-if="!item.hidden">
|
||||
<template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
|
||||
<template
|
||||
v-if="
|
||||
hasOneShowingChild(item.children, item) &&
|
||||
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
|
||||
!item.alwaysShow
|
||||
"
|
||||
>
|
||||
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
|
||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
|
||||
<svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
|
||||
<template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>
|
||||
<svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" />
|
||||
<template #title
|
||||
><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{
|
||||
onlyOneChild.meta.title
|
||||
}}</span></template
|
||||
>
|
||||
</el-menu-item>
|
||||
</app-link>
|
||||
</template>
|
||||
@ -30,7 +40,7 @@
|
||||
<script setup>
|
||||
import { isExternal } from '@/utils/validate';
|
||||
import AppLink from './Link';
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import { getNormalPath } from '@/utils/common';
|
||||
|
||||
const props = defineProps({
|
||||
// route object
|
||||
|
||||
@ -14,36 +14,26 @@
|
||||
>
|
||||
{{ tag.title }}
|
||||
<span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
|
||||
<close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" />
|
||||
<close class="el-icon-close" style="width: 1em; height: 1em; vertical-align: middle" />
|
||||
</span>
|
||||
</router-link>
|
||||
</scroll-pane>
|
||||
<ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
|
||||
<li @click="refreshSelectedTag(selectedTag)">
|
||||
<refresh-right style="width: 1em; height: 1em;" /> 刷新页面
|
||||
</li>
|
||||
<li @click="refreshSelectedTag(selectedTag)"><refresh-right style="width: 1em; height: 1em" /> 刷新页面</li>
|
||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
|
||||
<close style="width: 1em; height: 1em;" /> 关闭当前
|
||||
</li>
|
||||
<li @click="closeOthersTags">
|
||||
<circle-close style="width: 1em; height: 1em;" /> 关闭其他
|
||||
</li>
|
||||
<li v-if="!isFirstView()" @click="closeLeftTags">
|
||||
<back style="width: 1em; height: 1em;" /> 关闭左侧
|
||||
</li>
|
||||
<li v-if="!isLastView()" @click="closeRightTags">
|
||||
<right style="width: 1em; height: 1em;" /> 关闭右侧
|
||||
</li>
|
||||
<li @click="closeAllTags(selectedTag)">
|
||||
<circle-close style="width: 1em; height: 1em;" /> 全部关闭
|
||||
<close style="width: 1em; height: 1em" /> 关闭当前
|
||||
</li>
|
||||
<li @click="closeOthersTags"><circle-close style="width: 1em; height: 1em" /> 关闭其他</li>
|
||||
<li v-if="!isFirstView()" @click="closeLeftTags"><back style="width: 1em; height: 1em" /> 关闭左侧</li>
|
||||
<li v-if="!isLastView()" @click="closeRightTags"><right style="width: 1em; height: 1em" /> 关闭右侧</li>
|
||||
<li @click="closeAllTags(selectedTag)"><circle-close style="width: 1em; height: 1em" /> 全部关闭</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ScrollPane from './ScrollPane';
|
||||
import { getNormalPath } from '@/utils/ruoyi';
|
||||
import { getNormalPath } from '@/utils/common';
|
||||
|
||||
const visible = ref(false);
|
||||
const top = ref(0);
|
||||
@ -180,7 +170,7 @@ function closeLeftTags() {
|
||||
});
|
||||
}
|
||||
function closeOthersTags() {
|
||||
router.push(selectedTag.value).catch(() => { });
|
||||
router.push(selectedTag.value).catch(() => {});
|
||||
proxy.$tab.closeOtherPage(selectedTag.value).then(() => {
|
||||
moveToCurrentTag();
|
||||
});
|
||||
@ -233,7 +223,7 @@ function handleScroll() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
<style lang="scss" scoped>
|
||||
.tags-view-container {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
@ -265,7 +255,7 @@ function handleScroll() {
|
||||
color: #fff;
|
||||
border-color: #42b983;
|
||||
&::before {
|
||||
content: "";
|
||||
content: '';
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
|
||||
<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||
<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
|
||||
<sidebar v-if="!sidebar.hide" class="sidebar-container" />
|
||||
<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
|
||||
<div :class="{ 'fixed-header': fixedHeader }">
|
||||
@ -16,10 +16,8 @@
|
||||
<script setup>
|
||||
import { useWindowSize } from '@vueuse/core';
|
||||
import Sidebar from './components/Sidebar/index.vue';
|
||||
import {
|
||||
AppMain, Navbar, Settings, TagsView,
|
||||
} from './components';
|
||||
import defaultSettings from '@/settings';
|
||||
import { AppMain, Navbar, Settings, TagsView } from './components';
|
||||
import defaultSettings from '@/config/defaultSettings';
|
||||
|
||||
const store = useStore();
|
||||
const theme = computed(() => store.state.settings.theme);
|
||||
@ -62,8 +60,8 @@ function setLayout() {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/assets/styles/mixin.scss";
|
||||
@import "@/assets/styles/variables.module.scss";
|
||||
@import '@/assets/styles/mixin.scss';
|
||||
@import '@/assets/styles/variables.module.scss';
|
||||
|
||||
.app-wrapper {
|
||||
@include clearfix;
|
||||
|
||||
11
src/main.js
11
src/main.js
@ -1,4 +1,4 @@
|
||||
import {createApp} from 'vue';
|
||||
import { createApp } from 'vue';
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
@ -14,17 +14,17 @@ import directive from './directive'; // directive
|
||||
|
||||
// 注册指令
|
||||
import plugins from './plugins'; // plugins
|
||||
import {download} from '@/utils/request';
|
||||
import { download } from '@/utils/request';
|
||||
|
||||
// svg图标
|
||||
import 'virtual:svg-icons-register';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import elementIcons from '@/components/SvgIcon/svgicon';
|
||||
|
||||
import './permission'; // permission control
|
||||
import './router/interceptor'; // permission control
|
||||
|
||||
import {useDict} from '@/utils/dict';
|
||||
import {parseTime, resetForm, addDateRange, addTimeRange, handleTree, selectDictLabel} from '@/utils/ruoyi';
|
||||
import { useDict } from '@/utils/dict';
|
||||
import { parseTime, resetForm, addTimeRange, handleTree, selectDictLabel } from '@/utils/common';
|
||||
|
||||
// 分页组件
|
||||
import Pagination from '@/components/Pagination';
|
||||
@ -49,7 +49,6 @@ app.config.globalProperties.download = download;
|
||||
app.config.globalProperties.parseTime = parseTime;
|
||||
app.config.globalProperties.resetForm = resetForm;
|
||||
app.config.globalProperties.handleTree = handleTree;
|
||||
app.config.globalProperties.addDateRange = addDateRange;
|
||||
app.config.globalProperties.addTimeRange = addTimeRange;
|
||||
app.config.globalProperties.selectDictLabel = selectDictLabel;
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ const sessionCache = {
|
||||
if (value != null) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
remove(key) {
|
||||
sessionStorage.removeItem(key);
|
||||
@ -59,6 +60,7 @@ const localCache = {
|
||||
if (value != null) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
remove(key) {
|
||||
localStorage.removeItem(key);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import axios from 'axios';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getToken } from '@/utils/token';
|
||||
import errorCode from '@/utils/errorCode';
|
||||
import { blobValidate } from '@/utils/ruoyi';
|
||||
import { blobValidate } from '@/utils/common';
|
||||
|
||||
const baseURL = import.meta.env.VITE_APP_BASE_API;
|
||||
|
||||
@ -26,10 +26,10 @@ export default {
|
||||
});
|
||||
},
|
||||
zip(url, name) {
|
||||
var url = baseURL + url;
|
||||
const fullURL = baseURL + url;
|
||||
axios({
|
||||
method: 'get',
|
||||
url,
|
||||
fullURL,
|
||||
responseType: 'blob',
|
||||
headers: { Authorization: `Bearer ${getToken()}` },
|
||||
}).then(async (res) => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import tab from './tab';
|
||||
import auth from './auth';
|
||||
import permissionChecker from './permissionChecker';
|
||||
import cache from './cache';
|
||||
import modal from './modal';
|
||||
import download from './download';
|
||||
@ -8,7 +8,7 @@ export default function installPlugins(app) {
|
||||
// 页签操作
|
||||
app.config.globalProperties.$tab = tab;
|
||||
// 认证对象
|
||||
app.config.globalProperties.$auth = auth;
|
||||
app.config.globalProperties.$permissionChecker = permissionChecker;
|
||||
// 缓存对象
|
||||
app.config.globalProperties.$cache = cache;
|
||||
// 模态框对象
|
||||
|
||||
@ -1,34 +1,40 @@
|
||||
import store from '@/store';
|
||||
|
||||
/**
|
||||
* 现在大部分地方直接用v-hasPermission 指令来判断
|
||||
* @param {*} permission
|
||||
* @returns
|
||||
*/
|
||||
|
||||
function authPermission(permission) {
|
||||
const all_permission = '*:*:*';
|
||||
const allPermission = '*:*:*';
|
||||
const permissions = store.getters && store.getters.permissions;
|
||||
if (permission && permission.length > 0) {
|
||||
return permissions.some((v) => all_permission === v || v === permission);
|
||||
return permissions.some((v) => allPermission === v || v === permission);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function authRole(role) {
|
||||
const super_admin = 'admin';
|
||||
const superAdmin = 'admin';
|
||||
const currentRole = store.getters && store.getters.role;
|
||||
if (role && !currentRole) {
|
||||
return super_admin === currentRole || currentRole === role;
|
||||
return superAdmin === currentRole || currentRole === role;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default {
|
||||
// 验证用户是否具备某权限
|
||||
hasPermi(permission) {
|
||||
hasPermission(permission) {
|
||||
return authPermission(permission);
|
||||
},
|
||||
// 验证用户是否含有指定权限,只需包含其中一个
|
||||
hasPermiOr(permissions) {
|
||||
hasAnyPermission(permissions) {
|
||||
return permissions.some((item) => authPermission(item));
|
||||
},
|
||||
// 验证用户是否含有指定权限,必须全部拥有
|
||||
hasPermiAnd(permissions) {
|
||||
hasPermissions(permissions) {
|
||||
return permissions.every((item) => authPermission(item));
|
||||
},
|
||||
// 验证用户是否具备某角色
|
||||
@ -36,11 +42,11 @@ export default {
|
||||
return authRole(role);
|
||||
},
|
||||
// 验证用户是否含有指定角色,只需包含其中一个
|
||||
hasRoleOr(roles) {
|
||||
hasAnyRole(roles) {
|
||||
return roles.some((item) => authRole(item));
|
||||
},
|
||||
// 验证用户是否含有指定角色,必须全部拥有
|
||||
hasRoleAnd(roles) {
|
||||
hasRoles(roles) {
|
||||
return roles.every((item) => authRole(item));
|
||||
},
|
||||
};
|
||||
@ -26,13 +26,15 @@ export default {
|
||||
closeOpenPage(obj) {
|
||||
store.dispatch('tagsView/delView', router.currentRoute.value);
|
||||
if (obj !== undefined) {
|
||||
return router.push(obj);
|
||||
router.push(obj);
|
||||
}
|
||||
},
|
||||
// 关闭指定tab页签
|
||||
closePage(obj) {
|
||||
if (obj === undefined) {
|
||||
return store.dispatch('tagsView/delView', router.currentRoute.value).then(({ lastPath }) => router.push(lastPath || '/index'));
|
||||
return store
|
||||
.dispatch('tagsView/delView', router.currentRoute.value)
|
||||
.then(({ lastPath }) => router.push(lastPath || '/index'));
|
||||
}
|
||||
return store.dispatch('tagsView/delView', obj);
|
||||
},
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { ElMessage } from 'element-plus';
|
||||
import NProgress from 'nprogress';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
import router from '.';
|
||||
import store from '../store';
|
||||
import 'nprogress/nprogress.css';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getToken } from '@/utils/token';
|
||||
import { isHttp } from '@/utils/validate';
|
||||
import { isRelogin } from '@/utils/request';
|
||||
import { isReLogin } from '@/utils/request';
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
|
||||
@ -22,26 +22,29 @@ router.beforeEach((to, from, next) => {
|
||||
next({ path: '/' });
|
||||
NProgress.done();
|
||||
} else if (!store.getters.role) {
|
||||
console.log("重复获取")
|
||||
isRelogin.show = true;
|
||||
console.log('重复获取');
|
||||
isReLogin.show = true;
|
||||
// 判断当前用户是否已拉取完user_info信息
|
||||
store.dispatch('GetInfo').then(() => {
|
||||
isRelogin.show = false;
|
||||
store.dispatch('GenerateRoutes').then((accessRoutes) => {
|
||||
// 根据roles权限生成可访问的路由表
|
||||
accessRoutes.forEach((route) => {
|
||||
if (!isHttp(route.path)) {
|
||||
router.addRoute(route); // 动态添加可访问路由表
|
||||
}
|
||||
store
|
||||
.dispatch('GetInfo')
|
||||
.then(() => {
|
||||
isReLogin.show = false;
|
||||
store.dispatch('GenerateRoutes').then((accessRoutes) => {
|
||||
// 根据roles权限生成可访问的路由表
|
||||
accessRoutes.forEach((route) => {
|
||||
if (!isHttp(route.path)) {
|
||||
router.addRoute(route); // 动态添加可访问路由表
|
||||
}
|
||||
});
|
||||
next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
store.dispatch('LogOut').then(() => {
|
||||
ElMessage.error(err);
|
||||
next({ path: '/' });
|
||||
});
|
||||
next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
|
||||
});
|
||||
}).catch((err) => {
|
||||
store.dispatch('LogOut').then(() => {
|
||||
ElMessage.error(err);
|
||||
next({ path: '/' });
|
||||
});
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
@ -1,9 +1,7 @@
|
||||
import defaultSettings from '@/settings';
|
||||
import defaultSettings from '@/config/defaultSettings';
|
||||
import { useDynamicTitle } from '@/utils/dynamicTitle';
|
||||
|
||||
const {
|
||||
sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle,
|
||||
} = defaultSettings;
|
||||
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings;
|
||||
|
||||
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '';
|
||||
const state = {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { login, logout, getLoginUserInfo } from '@/api/login';
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth';
|
||||
import { getToken, setToken, removeToken } from '@/utils/token';
|
||||
import defAva from '@/assets/images/profile.jpg';
|
||||
|
||||
const user = {
|
||||
@ -41,54 +41,61 @@ const user = {
|
||||
const { code } = userInfo;
|
||||
const { uuid } = userInfo;
|
||||
return new Promise((resolve, reject) => {
|
||||
login(username, password, code, uuid).then((res) => {
|
||||
setToken(res.token);
|
||||
commit('SET_TOKEN', res.token);
|
||||
resolve();
|
||||
}).catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
login(username, password, code, uuid)
|
||||
.then((res) => {
|
||||
setToken(res.token);
|
||||
commit('SET_TOKEN', res.token);
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 获取用户信息
|
||||
GetInfo({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getLoginUserInfo().then((res) => {
|
||||
const { user } = res;
|
||||
// console.log(user);
|
||||
const avatar = (user.avatar == '' || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
||||
// console.log("获取的key"+ res.roleKey)
|
||||
// console.log(res.permissions)
|
||||
if (res.roleKey) {
|
||||
// 验证返回的roles是否是一个非空数组
|
||||
commit('SET_ROLE', res.roleKey);
|
||||
commit('SET_PERMISSIONS', res.permissions);
|
||||
commit('SET_DICT_TYPES', res.dictTypes);
|
||||
} else {
|
||||
commit('SET_ROLE', 'ROLE_DEFAULT');
|
||||
}
|
||||
commit('SET_NAME', user.username);
|
||||
commit('SET_AVATAR', avatar);
|
||||
resolve(res);
|
||||
}).catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
getLoginUserInfo()
|
||||
.then((res) => {
|
||||
const { user } = res;
|
||||
// console.log(user);
|
||||
const avatar =
|
||||
user.avatar == '' || user.avatar == null ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
||||
// console.log("获取的key"+ res.roleKey)
|
||||
// console.log(res.permissions)
|
||||
if (res.roleKey) {
|
||||
// 验证返回的roles是否是一个非空数组
|
||||
commit('SET_ROLE', res.roleKey);
|
||||
commit('SET_PERMISSIONS', res.permissions);
|
||||
commit('SET_DICT_TYPES', res.dictTypes);
|
||||
} else {
|
||||
commit('SET_ROLE', 'ROLE_DEFAULT');
|
||||
}
|
||||
commit('SET_NAME', user.username);
|
||||
commit('SET_AVATAR', avatar);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 退出系统
|
||||
LogOut({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(state.token).then(() => {
|
||||
commit('SET_TOKEN', '');
|
||||
commit('SET_ROLE', null);
|
||||
commit('SET_PERMISSIONS', []);
|
||||
removeToken();
|
||||
resolve();
|
||||
}).catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
logout(state.token)
|
||||
.then(() => {
|
||||
commit('SET_TOKEN', '');
|
||||
commit('SET_ROLE', null);
|
||||
commit('SET_PERMISSIONS', []);
|
||||
removeToken();
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ export function parseTime(time, pattern) {
|
||||
s: date.getSeconds(),
|
||||
a: date.getDay(),
|
||||
};
|
||||
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key];
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === 'a') {
|
||||
@ -46,7 +46,7 @@ export function parseTime(time, pattern) {
|
||||
}
|
||||
return value || 0;
|
||||
});
|
||||
return time_str;
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
@ -56,40 +56,23 @@ export function resetForm(refName) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 弃用 添加日期范围
|
||||
export function addDateRange(params, dateRange, propName) {
|
||||
const search = params;
|
||||
search.params = typeof search.params === 'object'
|
||||
&& search.params !== null
|
||||
&& !Array.isArray(search.params)
|
||||
? search.params
|
||||
: {};
|
||||
dateRange = Array.isArray(dateRange) ? dateRange : [];
|
||||
if (typeof propName === 'undefined') {
|
||||
search.params.beginTime = dateRange[0];
|
||||
search.params.endTime = dateRange[1];
|
||||
} else {
|
||||
search.params[`begin${propName}`] = dateRange[0];
|
||||
search.params[`end${propName}`] = dateRange[1];
|
||||
}
|
||||
return search;
|
||||
}
|
||||
|
||||
// 添加时间查询参数
|
||||
export function addTimeRange(params, dateRange) {
|
||||
params.beginTime = dateRange[0];
|
||||
params.endTime = dateRange[1];
|
||||
const [beginTime, endTime] = dateRange;
|
||||
params.beginTime = beginTime;
|
||||
params.endTime = endTime;
|
||||
return params;
|
||||
}
|
||||
|
||||
// 回显数据字典
|
||||
export function selectDictLabel(datas, value) {
|
||||
export function selectDictLabel(dicts, value) {
|
||||
if (value === undefined) {
|
||||
return '';
|
||||
}
|
||||
const actions = [];
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value == `${value}`) {
|
||||
actions.push(datas[key].label);
|
||||
Object.keys(dicts).some((key) => {
|
||||
if (dicts[key].value === `${value}`) {
|
||||
actions.push(dicts[key].label);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -122,25 +105,9 @@ export function selectDictLabels(datas, value, separator) {
|
||||
return actions.join('').substring(0, actions.join('').length - 1);
|
||||
}
|
||||
|
||||
// 字符串格式化(%s )
|
||||
export function sprintf(str) {
|
||||
const args = arguments;
|
||||
let flag = true;
|
||||
let i = 1;
|
||||
str = str.replace(/%s/g, () => {
|
||||
const arg = args[i++];
|
||||
if (typeof arg === 'undefined') {
|
||||
flag = false;
|
||||
return '';
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
return flag ? str : '';
|
||||
}
|
||||
|
||||
// 转换字符串,undefined,null等转化为""
|
||||
export function parseStrEmpty(str) {
|
||||
if (!str || str == 'undefined' || str == 'null') {
|
||||
if (!str || str === 'undefined' || str === 'null' || str === null) {
|
||||
return '';
|
||||
}
|
||||
return str;
|
||||
@ -150,7 +117,7 @@ export function parseStrEmpty(str) {
|
||||
export function mergeRecursive(source, target) {
|
||||
for (const p in target) {
|
||||
try {
|
||||
if (target[p].constructor == Object) {
|
||||
if (target[p].constructor === Object) {
|
||||
source[p] = mergeRecursive(source[p], target[p]);
|
||||
} else {
|
||||
source[p] = target[p];
|
||||
@ -217,7 +184,7 @@ export function handleTree(data, id, parentId, children) {
|
||||
* 参数处理
|
||||
* @param {*} params 参数
|
||||
*/
|
||||
export function tansParams(params) {
|
||||
export function encodeURIParams(params) {
|
||||
let result = '';
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName];
|
||||
@ -241,7 +208,7 @@ export function tansParams(params) {
|
||||
|
||||
// 返回项目路径
|
||||
export function getNormalPath(p) {
|
||||
if (p.length === 0 || !p || p == 'undefined') {
|
||||
if (p.length === 0 || !p || p === undefined) {
|
||||
return p;
|
||||
}
|
||||
const res = p.replace('//', '/');
|
||||
@ -1,5 +1,5 @@
|
||||
import store from '@/store';
|
||||
import defaultSettings from '@/settings';
|
||||
import defaultSettings from '@/config/defaultSettings';
|
||||
|
||||
/**
|
||||
* 动态修改标题
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
import store from '@/store';
|
||||
|
||||
/**
|
||||
* 字符权限校验
|
||||
* @param {Array} value 校验值
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function checkPermi(value) {
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const permissions = store.getters && store.getters.permissions;
|
||||
const permissionDatas = value;
|
||||
const all_permission = '*:*:*';
|
||||
|
||||
const hasPermission = permissions.some((permission) => all_permission === permission || permissionDatas.includes(permission));
|
||||
|
||||
if (!hasPermission) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.error('need roles! Like checkPermi="[\'system:user:add\',\'system:user:edit\']"');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色权限校验
|
||||
* @param {Array} value 校验值
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function checkRole(value) {
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const currentRole = store.getters && store.getters.role;
|
||||
const permissionRoles = value;
|
||||
const super_admin = 'admin';
|
||||
|
||||
const hasRole = super_admin === currentRole || permissionRoles.includes(currentRole);
|
||||
|
||||
if (!hasRole) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.error('need roles! Like checkRole="[\'admin\',\'editor\']"');
|
||||
return false;
|
||||
}
|
||||
@ -1,17 +1,15 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
ElNotification, ElMessageBox, ElMessage, ElLoading,
|
||||
} from 'element-plus';
|
||||
import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus';
|
||||
import { saveAs } from 'file-saver';
|
||||
import store from '@/store';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getToken } from '@/utils/token';
|
||||
import errorCode from '@/utils/errorCode';
|
||||
import { tansParams, blobValidate } from '@/utils/ruoyi';
|
||||
import { encodeURIParams, blobValidate } from '@/utils/common';
|
||||
import cache from '@/plugins/cache';
|
||||
|
||||
let downloadLoadingInstance;
|
||||
// 是否显示重新登录
|
||||
export const isRelogin = { show: false };
|
||||
export const isReLogin = { show: false };
|
||||
|
||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
|
||||
// 创建axios实例
|
||||
@ -23,53 +21,56 @@ const service = axios.create({
|
||||
});
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use((config) => {
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false;
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
|
||||
if (getToken() && !isToken) {
|
||||
config.headers.Authorization = `Bearer ${getToken()}`; // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.method === 'get' && config.params) {
|
||||
let url = `${config.url}?${tansParams(config.params)}`;
|
||||
url = url.slice(0, -1);
|
||||
config.params = {};
|
||||
config.url = url;
|
||||
}
|
||||
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
|
||||
const requestObj = {
|
||||
url: config.url,
|
||||
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
|
||||
time: new Date().getTime(),
|
||||
};
|
||||
const sessionObj = cache.session.getJSON('sessionObj');
|
||||
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
|
||||
cache.session.setJSON('sessionObj', requestObj);
|
||||
} else {
|
||||
const s_url = sessionObj.url; // 请求地址
|
||||
const s_data = sessionObj.data; // 请求数据
|
||||
const s_time = sessionObj.time; // 请求时间
|
||||
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
|
||||
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
|
||||
const message = '数据正在处理,请勿重复提交';
|
||||
console.warn(`[${s_url}]: ${message}`);
|
||||
return Promise.reject(new Error(message));
|
||||
}
|
||||
cache.session.setJSON('sessionObj', requestObj);
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false;
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
|
||||
if (getToken() && !isToken) {
|
||||
config.headers.Authorization = `Bearer ${getToken()}`; // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
Promise.reject(error);
|
||||
});
|
||||
// get请求映射params参数
|
||||
if (config.method === 'get' && config.params) {
|
||||
let url = `${config.url}?${encodeURIParams(config.params)}`;
|
||||
url = url.slice(0, -1);
|
||||
config.params = {};
|
||||
config.url = url;
|
||||
}
|
||||
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
|
||||
const requestObj = {
|
||||
url: config.url,
|
||||
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
|
||||
time: new Date().getTime(),
|
||||
};
|
||||
const sessionObj = cache.session.getJSON('sessionObj');
|
||||
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
|
||||
cache.session.setJSON('sessionObj', requestObj);
|
||||
} else {
|
||||
const s_url = sessionObj.url; // 请求地址
|
||||
const s_data = sessionObj.data; // 请求数据
|
||||
const s_time = sessionObj.time; // 请求时间
|
||||
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
|
||||
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
|
||||
const message = '数据正在处理,请勿重复提交';
|
||||
console.warn(`[${s_url}]: ${message}`);
|
||||
return Promise.reject(new Error(message));
|
||||
}
|
||||
cache.session.setJSON('sessionObj', requestObj);
|
||||
}
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
console.log(error);
|
||||
Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
(res) => {
|
||||
// 未设置状态码则默认成功状态
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = res.data.code || 200;
|
||||
// 获取错误信息
|
||||
const msg = errorCode[code] || res.data.msg || errorCode.default;
|
||||
@ -78,29 +79,33 @@ service.interceptors.response.use(
|
||||
return res.data;
|
||||
}
|
||||
if (code === 20101) {
|
||||
if (!isRelogin.show) {
|
||||
isRelogin.show = true;
|
||||
if (!isReLogin.show) {
|
||||
isReLogin.show = true;
|
||||
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
isRelogin.show = false;
|
||||
store.dispatch('LogOut').then(() => {
|
||||
location.href = '/index';
|
||||
})
|
||||
.then(() => {
|
||||
isReLogin.show = false;
|
||||
store.dispatch('LogOut').then(() => {
|
||||
location.href = '/index';
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
isReLogin.show = false;
|
||||
});
|
||||
}).catch(() => {
|
||||
isRelogin.show = false;
|
||||
});
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。');
|
||||
} if (code === 500) {
|
||||
}
|
||||
if (code === 500) {
|
||||
ElMessage({
|
||||
message: msg,
|
||||
type: 'error',
|
||||
});
|
||||
return Promise.reject(new Error(msg));
|
||||
} if (code !== 200) {
|
||||
}
|
||||
if (code !== 200) {
|
||||
ElNotification.error({
|
||||
title: msg,
|
||||
});
|
||||
@ -130,27 +135,30 @@ service.interceptors.response.use(
|
||||
// 通用下载方法
|
||||
export function download(url, params, filename) {
|
||||
downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
|
||||
return service.post(url, params, {
|
||||
transformRequest: [(params) => tansParams(params)],
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
responseType: 'blob',
|
||||
}).then(async (data) => {
|
||||
const isLogin = await blobValidate(data);
|
||||
if (isLogin) {
|
||||
const blob = new Blob([data]);
|
||||
saveAs(blob, filename);
|
||||
} else {
|
||||
const resText = await data.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode.default;
|
||||
ElMessage.error(errMsg);
|
||||
}
|
||||
downloadLoadingInstance.close();
|
||||
}).catch((r) => {
|
||||
console.error(r);
|
||||
ElMessage.error('下载文件出现错误,请联系管理员!');
|
||||
downloadLoadingInstance.close();
|
||||
});
|
||||
return service
|
||||
.post(url, params, {
|
||||
transformRequest: [(params) => encodeURIParams(params)],
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
responseType: 'blob',
|
||||
})
|
||||
.then(async (data) => {
|
||||
const isLogin = await blobValidate(data);
|
||||
if (isLogin) {
|
||||
const blob = new Blob([data]);
|
||||
saveAs(blob, filename);
|
||||
} else {
|
||||
const resText = await data.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode.default;
|
||||
ElMessage.error(errMsg);
|
||||
}
|
||||
downloadLoadingInstance.close();
|
||||
})
|
||||
.catch((r) => {
|
||||
console.error(r);
|
||||
ElMessage.error('下载文件出现错误,请联系管理员!');
|
||||
downloadLoadingInstance.close();
|
||||
});
|
||||
}
|
||||
|
||||
export default service;
|
||||
|
||||
@ -1,16 +1,23 @@
|
||||
Math.easeInOutQuad = function (t, b, c, d) {
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return c / 2 * t * t + b;
|
||||
return (c / 2) * t * t + b;
|
||||
}
|
||||
t--;
|
||||
return -c / 2 * (t * (t - 2) - 1) + b;
|
||||
return (-c / 2) * (t * (t - 2) - 1) + b;
|
||||
};
|
||||
|
||||
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
|
||||
const requestAnimFrame = (function () {
|
||||
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); };
|
||||
}());
|
||||
return (
|
||||
window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
/**
|
||||
* Because it's so fucking difficult to detect the scrolling element, just move them all
|
||||
@ -36,8 +43,8 @@ export function scrollTo(to, duration, callback) {
|
||||
const change = to - start;
|
||||
const increment = 20;
|
||||
let currentTime = 0;
|
||||
duration = (typeof (duration) === 'undefined') ? 500 : duration;
|
||||
var animateScroll = function () {
|
||||
duration = typeof duration === 'undefined' ? 500 : duration;
|
||||
const animateScroll = function () {
|
||||
// increment the time
|
||||
currentTime += increment;
|
||||
// find the value with the quadratic in-out easing function
|
||||
@ -47,7 +54,7 @@ export function scrollTo(to, duration, callback) {
|
||||
// do the animation unless its over
|
||||
if (currentTime < duration) {
|
||||
requestAnimFrame(animateScroll);
|
||||
} else if (callback && typeof (callback) === 'function') {
|
||||
} else if (callback && typeof callback === 'function') {
|
||||
// the animation is done so lets callback
|
||||
callback();
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
|
||||
<h3 class="title">AgileBoot后台管理系统</h3>
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
|
||||
<el-input v-model="loginForm.username" type="link" size="large" auto-complete="off" placeholder="账号">
|
||||
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
@ -48,17 +48,17 @@
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:logininfor:remove']"
|
||||
v-hasPermission="['system:logininfor:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermi="['system:logininfor:remove']"
|
||||
<el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermission="['system:logininfor:remove']"
|
||||
>清空</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:logininfor:export']"
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermission="['system:logininfor:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
|
||||
@ -1,63 +1,54 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||
<el-form-item label="登录地址" prop="ipaddr">
|
||||
<el-input
|
||||
v-model="queryParams.ipaddr"
|
||||
placeholder="请输入登录地址"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="userName">
|
||||
<el-input
|
||||
v-model="queryParams.userName"
|
||||
placeholder="请输入用户名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="onlineList.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column label="序号" width="50" type="index" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会话编号" align="center" prop="tokenId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="登录名称" align="center" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="所属部门" align="center" prop="deptName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="主机" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作系统" align="center" prop="os" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="浏览器" align="center" prop="browser" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="登录时间" align="center" prop="loginTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.loginTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="Delete"
|
||||
@click="handleForceLogout(scope.row)"
|
||||
v-hasPermi="['monitor:online:forceLogout']"
|
||||
>强退</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||
<el-form-item label="登录地址" prop="ipaddr">
|
||||
<el-input v-model="queryParams.ipaddr" placeholder="请输入登录地址" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="userName">
|
||||
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="onlineList.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="序号" width="50" type="index" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="会话编号" align="center" prop="tokenId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="登录名称" align="center" prop="userName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="所属部门" align="center" prop="deptName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="主机" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作系统" align="center" prop="os" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="浏览器" align="center" prop="browser" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="登录时间" align="center" prop="loginTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.loginTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
icon="Delete"
|
||||
@click="handleForceLogout(scope.row)"
|
||||
v-hasPermission="['monitor:online:forceLogout']"
|
||||
>强退</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="pageNum" v-model:limit="pageSize" />
|
||||
</div>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="pageNum" v-model:limit="pageSize" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Online">
|
||||
@ -79,12 +70,14 @@ const queryParams = ref({
|
||||
/** 查询登录日志列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
initData(queryParams.value).then((response) => {
|
||||
onlineList.value = response.rows;
|
||||
total.value = response.total;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
initData(queryParams.value)
|
||||
.then((response) => {
|
||||
onlineList.value = response.rows;
|
||||
total.value = response.total;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
@ -98,10 +91,14 @@ function resetQuery() {
|
||||
}
|
||||
/** 强退按钮操作 */
|
||||
function handleForceLogout(row) {
|
||||
proxy.$modal.confirm(`是否确认强退名称为"${row.userName}"的用户?`).then(() => forceLogout(row.tokenId)).then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
}).catch(() => {});
|
||||
proxy.$modal
|
||||
.confirm(`是否确认强退名称为"${row.userName}"的用户?`)
|
||||
.then(() => forceLogout(row.tokenId))
|
||||
.then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
getList();
|
||||
|
||||
@ -53,17 +53,22 @@
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:operlog:remove']"
|
||||
v-hasPermission="['system:operlog:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermi="['system:operlog:remove']"
|
||||
<el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermission="['system:operlog:remove']"
|
||||
>清空</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:operlog:export']"
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermission="['system:operlog:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -117,10 +122,10 @@
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="View"
|
||||
@click="handleView(scope.row, scope.index)"
|
||||
v-hasPermi="['system:operlog:query']"
|
||||
v-hasPermission="['system:operlog:query']"
|
||||
>详细
|
||||
</el-button>
|
||||
</template>
|
||||
@ -181,10 +186,10 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Operlog">
|
||||
import {list, deleteOperationLog, cleanOperlog} from '@/api/monitor/operlog';
|
||||
import { list, deleteOperationLog, cleanOperlog } from '@/api/monitor/operlog';
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
const {sys_operation_type, sys_operation_status} = proxy.useDict('sys_operation_type', 'sys_operation_status');
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_operation_type, sys_operation_status } = proxy.useDict('sys_operation_type', 'sys_operation_status');
|
||||
|
||||
const operlogList = ref([]);
|
||||
const open = ref(false);
|
||||
@ -196,7 +201,7 @@ const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const requestModule = ref('');
|
||||
const dateRange = ref([]);
|
||||
const defaultSort = ref({prop: 'operationTime', order: 'descending'});
|
||||
const defaultSort = ref({ prop: 'operationTime', order: 'descending' });
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
@ -210,7 +215,7 @@ const data = reactive({
|
||||
},
|
||||
});
|
||||
|
||||
const {queryParams, form} = toRefs(data);
|
||||
const { queryParams, form } = toRefs(data);
|
||||
|
||||
/** 查询登录日志 */
|
||||
function getList() {
|
||||
|
||||
@ -3,13 +3,7 @@
|
||||
<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
|
||||
<h3 class="title">AgileBoot后台管理系统</h3>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="registerForm.username"
|
||||
type="text"
|
||||
size="large"
|
||||
auto-complete="off"
|
||||
placeholder="账号"
|
||||
>
|
||||
<el-input v-model="registerForm.username" link size="large" auto-complete="off" placeholder="账号">
|
||||
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
@ -34,7 +28,7 @@
|
||||
placeholder="确认密码"
|
||||
@keyup.enter="handleRegister"
|
||||
>
|
||||
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
|
||||
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code" v-if="isCaptchaOn">
|
||||
@ -49,28 +43,22 @@
|
||||
<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
|
||||
</el-input>
|
||||
<div class="register-code">
|
||||
<img :src="codeUrl" @click="getCode" class="register-code-img"/>
|
||||
<img :src="codeUrl" @click="getCode" class="register-code-img" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item style="width:100%;">
|
||||
<el-button
|
||||
:loading="loading"
|
||||
size="large"
|
||||
type="primary"
|
||||
style="width:100%;"
|
||||
@click.prevent="handleRegister"
|
||||
>
|
||||
<el-form-item style="width: 100%">
|
||||
<el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleRegister">
|
||||
<span v-if="!loading">注 册</span>
|
||||
<span v-else>注 册 中...</span>
|
||||
</el-button>
|
||||
<div style="float: right;">
|
||||
<div style="float: right">
|
||||
<router-link class="link-type" :to="'/login'">使用已有账户登录</router-link>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<div class="el-register-footer">
|
||||
<span>Copyright © 2018-2022 agileboot All Rights Reserved.</span>
|
||||
<span>Copyright © 2018-2022 Agileboot All Rights Reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -102,13 +90,19 @@ const registerRules = {
|
||||
username: [
|
||||
{ required: true, trigger: 'blur', message: '请输入您的账号' },
|
||||
{
|
||||
min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur',
|
||||
min: 2,
|
||||
max: 20,
|
||||
message: '用户账号长度必须介于 2 和 20 之间',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{ required: true, trigger: 'blur', message: '请输入您的密码' },
|
||||
{
|
||||
min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur',
|
||||
min: 5,
|
||||
max: 20,
|
||||
message: '用户密码长度必须介于 5 和 20 之间',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
confirmPassword: [
|
||||
@ -126,20 +120,24 @@ function handleRegister() {
|
||||
proxy.$refs.registerRef.validate((valid) => {
|
||||
if (valid) {
|
||||
loading.value = true;
|
||||
register(registerForm.value).then((res) => {
|
||||
const { username } = registerForm.value;
|
||||
ElMessageBox.alert(`<font color='red'>恭喜你,您的账号 ${username} 注册成功!</font>`, '系统提示', {
|
||||
dangerouslyUseHTMLString: true,
|
||||
type: 'success',
|
||||
}).then(() => {
|
||||
router.push('/login');
|
||||
}).catch(() => {});
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
if (isCaptchaOn) {
|
||||
getCode();
|
||||
}
|
||||
});
|
||||
register(registerForm.value)
|
||||
.then((res) => {
|
||||
const { username } = registerForm.value;
|
||||
ElMessageBox.alert(`<font color='red'>恭喜你,您的账号 ${username} 注册成功!</font>`, '系统提示', {
|
||||
dangerouslyUseHTMLString: true,
|
||||
type: 'success',
|
||||
})
|
||||
.then(() => {
|
||||
router.push('/login');
|
||||
})
|
||||
.catch(() => {});
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
if (isCaptchaOn) {
|
||||
getCode();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -157,13 +155,13 @@ function getCode() {
|
||||
getCode();
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
<style lang="scss" scoped>
|
||||
.register {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
background-image: url("../assets/images/login-background.jpg");
|
||||
background-image: url('../assets/images/login-background.jpg');
|
||||
background-size: cover;
|
||||
}
|
||||
.title {
|
||||
|
||||
@ -1,155 +1,137 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="参数名称" prop="configName">
|
||||
<el-input
|
||||
v-model="queryParams.configName"
|
||||
placeholder="请输入参数名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数键名" prop="configKey">
|
||||
<el-input
|
||||
v-model="queryParams.configKey"
|
||||
placeholder="请输入参数键名"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="允许修改" prop="isAllowChange">
|
||||
<el-select v-model="queryParams.isAllowChange" placeholder="允许修改" clearable>
|
||||
<el-option
|
||||
v-for="dict in sys_yes_no"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" style="width: 308px;">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="参数名称" prop="configName">
|
||||
<el-input
|
||||
v-model="queryParams.configName"
|
||||
placeholder="请输入参数名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数键名" prop="configKey">
|
||||
<el-input
|
||||
v-model="queryParams.configKey"
|
||||
placeholder="请输入参数键名"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="允许修改" prop="isAllowChange">
|
||||
<el-select v-model="queryParams.isAllowChange" placeholder="允许修改" clearable>
|
||||
<el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" style="width: 308px">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermission="['system:config:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Refresh"
|
||||
@click="handleRefreshCache"
|
||||
v-hasPermission="['system:config:remove']"
|
||||
>刷新缓存</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="参数主键" align="center" prop="configId" />
|
||||
<el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="参数键值" align="center" prop="configValue" />
|
||||
<el-table-column label="可选值" align="center" prop="configOptions" />
|
||||
<el-table-column label="允许修改" align="center" prop="isAllowChangeStr" />
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link icon="Edit" @click="handleUpdate(scope.row)" v-hasPermission="['system:config:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-form ref="configRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="参数名称" prop="configName">
|
||||
<el-input v-model="form.configName" placeholder="请输入参数名称" :disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数键名" prop="configKey">
|
||||
<el-input v-model="form.configKey" placeholder="请输入参数键名" :disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数键值" prop="configValue">
|
||||
<el-select v-if="form.configOptions.length > 0" v-model="form.configValue" placeholder="Select">
|
||||
<el-option v-for="item in form.configOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
<el-input v-else v-model="form.configValue" placeholder="请输入参数键值" />
|
||||
</el-form-item>
|
||||
<el-form-item label="允许修改" prop="isAllowChange">
|
||||
<el-radio-group v-model="form.isAllowChange" :disabled="true">
|
||||
<el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :disabled="true" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:config:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Refresh"
|
||||
@click="handleRefreshCache"
|
||||
v-hasPermi="['system:config:remove']"
|
||||
>刷新缓存</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="参数主键" align="center" prop="configId" />
|
||||
<el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="参数键值" align="center" prop="configValue" />
|
||||
<el-table-column label="可选值" align="center" prop="configOptions" />
|
||||
<el-table-column label="允许修改" align="center" prop="isAllowChangeStr"/>
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:config:edit']"
|
||||
>修改</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-form ref="configRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="参数名称" prop="configName" >
|
||||
<el-input v-model="form.configName" placeholder="请输入参数名称" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数键名" prop="configKey">
|
||||
<el-input v-model="form.configKey" placeholder="请输入参数键名" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="参数键值" prop="configValue">
|
||||
<el-select v-if="form.configOptions.length > 0" v-model="form.configValue" placeholder="Select">
|
||||
<el-option
|
||||
v-for="item in form.configOptions"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input v-else
|
||||
v-model="form.configValue" placeholder="请输入参数键值"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="允许修改" prop="isAllowChange">
|
||||
<el-radio-group v-model="form.isAllowChange" :disabled="true">
|
||||
<el-radio
|
||||
v-for="dict in sys_yes_no"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :disabled="true"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Config">
|
||||
import {
|
||||
listConfig, getConfig, updateConfig, refreshCache,
|
||||
} from '@/api/system/config';
|
||||
import { listConfig, getConfig, updateConfig, refreshCache } from '@/api/system/config';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_yes_no } = proxy.useDict('sys_yes_no');
|
||||
@ -186,12 +168,14 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询参数列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listConfig(proxy.addTimeRange(queryParams.value, dateRange.value)).then((response) => {
|
||||
configList.value = response.rows;
|
||||
total.value = response.total;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
listConfig(proxy.addTimeRange(queryParams.value, dateRange.value))
|
||||
.then((response) => {
|
||||
configList.value = response.rows;
|
||||
total.value = response.total;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
|
||||
@ -17,7 +17,9 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dept:add']">新增</el-button>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermission="['system:dept:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Sort" @click="toggleExpandAll">展开/折叠</el-button>
|
||||
@ -31,7 +33,7 @@
|
||||
:data="deptList"
|
||||
row-key="deptId"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
|
||||
<el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
|
||||
@ -47,18 +49,18 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button type="text" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']"
|
||||
<el-button link icon="Edit" @click="handleUpdate(scope.row)" v-hasPermission="['system:dept:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button type="text" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']"
|
||||
<el-button link icon="Plus" @click="handleAdd(scope.row)" v-hasPermission="['system:dept:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="scope.row.parentId != 0"
|
||||
type="text"
|
||||
link
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:dept:remove']"
|
||||
v-hasPermission="['system:dept:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
@ -74,7 +76,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="deptOptions"
|
||||
:props="{value: 'deptId', label: 'deptName', children: 'children'}"
|
||||
:props="{ value: 'deptId', label: 'deptName', children: 'children' }"
|
||||
value-key="deptId"
|
||||
placeholder="选择上级部门"
|
||||
check-strictly
|
||||
@ -126,10 +128,17 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Dept">
|
||||
import {listDept, getDept, deleteDept, addDept, updateDept, listDeptExcludeCurrentDeptItself} from '@/api/system/dept';
|
||||
import {
|
||||
listDept,
|
||||
getDept,
|
||||
deleteDept,
|
||||
addDept,
|
||||
updateDept,
|
||||
listDeptExcludeCurrentDeptItself,
|
||||
} from '@/api/system/dept';
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
const {sys_status} = proxy.useDict('sys_status');
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_status } = proxy.useDict('sys_status');
|
||||
|
||||
const deptList = ref([]);
|
||||
const open = ref(false);
|
||||
@ -147,15 +156,15 @@ const data = reactive({
|
||||
status: undefined,
|
||||
},
|
||||
rules: {
|
||||
parentId: [{required: true, message: '上级部门不能为空', trigger: 'blur'}],
|
||||
deptName: [{required: true, message: '部门名称不能为空', trigger: 'blur'}],
|
||||
orderNum: [{required: true, message: '显示排序不能为空', trigger: 'blur'}],
|
||||
email: [{type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change']}],
|
||||
phone: [{pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur'}],
|
||||
parentId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
|
||||
deptName: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
|
||||
orderNum: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }],
|
||||
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }],
|
||||
phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
|
||||
},
|
||||
});
|
||||
|
||||
const {queryParams, form, rules} = toRefs(data);
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询部门列表 */
|
||||
function getList() {
|
||||
|
||||
@ -17,7 +17,9 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:menu:add']">新增</el-button>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermission="['system:menu:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Sort" @click="toggleExpandAll">展开/折叠</el-button>
|
||||
@ -31,7 +33,7 @@
|
||||
:data="menuList"
|
||||
row-key="menuId"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column>
|
||||
<el-table-column prop="icon" label="图标" align="center" width="100">
|
||||
@ -54,13 +56,13 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button type="text" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:menu:edit']"
|
||||
<el-button link icon="Edit" @click="handleUpdate(scope.row)" v-hasPermission="['system:menu:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button type="text" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:menu:add']"
|
||||
<el-button link icon="Plus" @click="handleAdd(scope.row)" v-hasPermission="['system:menu:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button type="text" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:menu:remove']"
|
||||
<el-button link icon="Delete" @click="handleDelete(scope.row)" v-hasPermission="['system:menu:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
@ -76,7 +78,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="menuOptions"
|
||||
:props="{value: 'menuId', label: 'menuName', children: 'children'}"
|
||||
:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
|
||||
value-key="menuId"
|
||||
placeholder="选择上级菜单"
|
||||
check-strictly
|
||||
@ -178,7 +180,7 @@
|
||||
<template #label>
|
||||
<span>
|
||||
<el-tooltip
|
||||
content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
|
||||
content="控制器中定义的权限字符,如:@PreAuthorize(`@permission.has('system:config:list')`)"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon><question-filled /></el-icon>
|
||||
@ -263,12 +265,12 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Menu">
|
||||
import {addMenu, deleteMenu, getMenu, listMenu, updateMenu} from '@/api/system/menu';
|
||||
import { addMenu, deleteMenu, getMenu, listMenu, updateMenu } from '@/api/system/menu';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import IconSelect from '@/components/IconSelect';
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
const {sys_visible, sys_status} = proxy.useDict('sys_visible', 'sys_status');
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_visible, sys_status } = proxy.useDict('sys_visible', 'sys_status');
|
||||
|
||||
const menuList = ref([]);
|
||||
const open = ref(false);
|
||||
@ -288,13 +290,13 @@ const data = reactive({
|
||||
isVisible: undefined,
|
||||
},
|
||||
rules: {
|
||||
menuName: [{required: true, message: '菜单名称不能为空', trigger: 'blur'}],
|
||||
orderNum: [{required: true, message: '菜单顺序不能为空', trigger: 'blur'}],
|
||||
path: [{required: true, message: '路由地址不能为空', trigger: 'blur'}],
|
||||
menuName: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
|
||||
orderNum: [{ required: true, message: '菜单顺序不能为空', trigger: 'blur' }],
|
||||
path: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],
|
||||
},
|
||||
});
|
||||
|
||||
const {queryParams, form, rules} = toRefs(data);
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询菜单列表 */
|
||||
function getList() {
|
||||
@ -311,7 +313,7 @@ function getList() {
|
||||
function getTreeSelect() {
|
||||
menuOptions.value = [];
|
||||
listMenu().then((response) => {
|
||||
const menu = {menuId: 0, menuName: '主类目', children: []};
|
||||
const menu = { menuId: 0, menuName: '主类目', children: [] };
|
||||
menu.children = proxy.handleTree(response, 'menuId');
|
||||
menuOptions.value.push(menu);
|
||||
});
|
||||
|
||||
@ -1,180 +1,143 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input
|
||||
v-model="queryParams.noticeTitle"
|
||||
placeholder="请输入公告标题"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作人员" prop="creatorName">
|
||||
<el-input
|
||||
v-model="queryParams.creatorName"
|
||||
placeholder="请输入操作人员"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="noticeType">
|
||||
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable>
|
||||
<el-option
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input v-model="queryParams.noticeTitle" placeholder="请输入公告标题" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="操作人员" prop="creatorName">
|
||||
<el-input v-model="queryParams.creatorName" placeholder="请输入操作人员" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="noticeType">
|
||||
<el-select v-model="queryParams.noticeType" placeholder="公告类型" clearable>
|
||||
<el-option v-for="dict in sys_notice_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermission="['system:notice:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermission="['system:notice:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermission="['system:notice:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" align="center" prop="noticeId" width="100" />
|
||||
<el-table-column label="公告标题" align="center" prop="noticeTitle" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="公告类型" align="center" prop="noticeType" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_notice_type" :value="scope.row.noticeType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_notice_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建者" align="center" prop="creatorName" width="100" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link icon="Edit" @click="handleUpdate(scope.row)" v-hasPermission="['system:notice:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button link icon="Delete" @click="handleDelete(scope.row)" v-hasPermission="['system:notice:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改公告对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="780px" append-to-body>
|
||||
<el-form ref="noticeRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input v-model="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告类型" prop="noticeType">
|
||||
<el-select v-model="form.noticeType" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="dict in sys_notice_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio v-for="dict in sys_notice_status" :key="dict.value" :label="dict.value">{{
|
||||
dict.label
|
||||
}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="内容">
|
||||
<el-input :rows="6" type="textarea" placeholder="请输入内容" v-model="form.noticeContent" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Plus"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['system:notice:add']"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:notice:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:notice:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" align="center" prop="noticeId" width="100" />
|
||||
<el-table-column
|
||||
label="公告标题"
|
||||
align="center"
|
||||
prop="noticeTitle"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="公告类型" align="center" prop="noticeType" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_notice_type" :value="scope.row.noticeType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_notice_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建者" align="center" prop="creatorName" width="100" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:notice:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:notice:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改公告对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="780px" append-to-body>
|
||||
<el-form ref="noticeRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告标题" prop="noticeTitle">
|
||||
<el-input v-model="form.noticeTitle" placeholder="请输入公告标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告类型" prop="noticeType">
|
||||
<el-select v-model="form.noticeType" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="dict in sys_notice_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio
|
||||
v-for="dict in sys_notice_status"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="内容">
|
||||
<el-input
|
||||
:rows="6"
|
||||
type="textarea"
|
||||
placeholder="请输入内容"
|
||||
v-model="form.noticeContent"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Notice">
|
||||
import {
|
||||
listNotice, getNotice, deleteNotice, addNotice, updateNotice,
|
||||
} from '@/api/system/notice';
|
||||
import { listNotice, getNotice, deleteNotice, addNotice, updateNotice } from '@/api/system/notice';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_notice_status, sys_notice_type } = proxy.useDict('sys_notice_status', 'sys_notice_type');
|
||||
@ -209,12 +172,14 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询公告列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listNotice(queryParams.value).then((response) => {
|
||||
noticeList.value = response.rows;
|
||||
total.value = response.total;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
listNotice(queryParams.value)
|
||||
.then((response) => {
|
||||
noticeList.value = response.rows;
|
||||
total.value = response.total;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
@ -287,10 +252,14 @@ function submitForm() {
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const noticeIds = row.noticeId || ids.value;
|
||||
proxy.$modal.confirm(`是否确认删除公告编号为"${noticeIds}"的数据项?`).then(() => deleteNotice(noticeIds)).then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
}).catch(() => {});
|
||||
proxy.$modal
|
||||
.confirm(`是否确认删除公告编号为"${noticeIds}"的数据项?`)
|
||||
.then(() => deleteNotice(noticeIds))
|
||||
.then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
getList();
|
||||
|
||||
@ -1,161 +1,128 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="岗位编码" prop="postCode">
|
||||
<el-input
|
||||
v-model="queryParams.postCode"
|
||||
placeholder="请输入岗位编码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位名称" prop="postName">
|
||||
<el-input
|
||||
v-model="queryParams.postName"
|
||||
placeholder="请输入岗位名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
|
||||
<el-option
|
||||
v-for="dict in sys_status"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="岗位编码" prop="postCode">
|
||||
<el-input v-model="queryParams.postCode" placeholder="请输入岗位编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位名称" prop="postName">
|
||||
<el-input v-model="queryParams.postName" placeholder="请输入岗位名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="岗位状态" clearable>
|
||||
<el-option v-for="dict in sys_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermission="['system:post:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermission="['system:post:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermission="['system:post:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermission="['system:post:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="岗位编号" align="center" prop="postId" />
|
||||
<el-table-column label="岗位编码" align="center" prop="postCode" />
|
||||
<el-table-column label="岗位名称" align="center" prop="postName" />
|
||||
<el-table-column label="岗位排序" align="center" prop="postSort" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link icon="Edit" @click="handleUpdate(scope.row)" v-hasPermission="['system:post:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button link icon="Delete" @click="handleDelete(scope.row)" v-hasPermission="['system:post:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改岗位对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-form ref="postRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="岗位名称" prop="postName">
|
||||
<el-input v-model="form.postName" placeholder="请输入岗位名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位编码" prop="postCode">
|
||||
<el-input v-model="form.postCode" placeholder="请输入编码名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位顺序" prop="postSort">
|
||||
<el-input-number v-model="form.postSort" controls-position="right" :min="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio v-for="dict in sys_status" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Plus"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['system:post:add']"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:post:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:post:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['system:post:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="岗位编号" align="center" prop="postId" />
|
||||
<el-table-column label="岗位编码" align="center" prop="postCode" />
|
||||
<el-table-column label="岗位名称" align="center" prop="postName" />
|
||||
<el-table-column label="岗位排序" align="center" prop="postSort" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:post:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:post:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改岗位对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-form ref="postRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="岗位名称" prop="postName">
|
||||
<el-input v-model="form.postName" placeholder="请输入岗位名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位编码" prop="postCode">
|
||||
<el-input v-model="form.postCode" placeholder="请输入编码名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位顺序" prop="postSort">
|
||||
<el-input-number v-model="form.postSort" controls-position="right" :min="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio
|
||||
v-for="dict in sys_status"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Post">
|
||||
import {
|
||||
listPost, addPost, deletePost, getPost, updatePost,
|
||||
} from '@/api/system/post';
|
||||
import { listPost, addPost, deletePost, getPost, updatePost } from '@/api/system/post';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_status } = proxy.useDict('sys_status');
|
||||
@ -191,12 +158,14 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询岗位列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listPost(queryParams.value).then((response) => {
|
||||
postList.value = response.rows;
|
||||
total.value = response.total;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
listPost(queryParams.value)
|
||||
.then((response) => {
|
||||
postList.value = response.rows;
|
||||
total.value = response.total;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
@ -270,16 +239,24 @@ function submitForm() {
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const postIds = row.postId || ids.value;
|
||||
proxy.$modal.confirm(`是否确认删除岗位编号为"${postIds}"的数据项?`).then(() => deletePost(postIds)).then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
}).catch(() => {});
|
||||
proxy.$modal
|
||||
.confirm(`是否确认删除岗位编号为"${postIds}"的数据项?`)
|
||||
.then(() => deletePost(postIds))
|
||||
.then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
proxy.download('system/post/export', {
|
||||
...queryParams.value,
|
||||
}, `post_${new Date().getTime()}.xlsx`);
|
||||
proxy.download(
|
||||
'system/post/export',
|
||||
{
|
||||
...queryParams.value,
|
||||
},
|
||||
`post_${new Date().getTime()}.xlsx`,
|
||||
);
|
||||
}
|
||||
|
||||
getList();
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="openSelectUser" v-hasPermi="['system:role:add']"
|
||||
<el-button type="primary" plain icon="Plus" @click="openSelectUser" v-hasPermission="['system:role:add']"
|
||||
>添加用户</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -38,7 +38,7 @@
|
||||
icon="CircleClose"
|
||||
:disabled="multiple"
|
||||
@click="cancelAuthUserAll"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
v-hasPermission="['system:role:remove']"
|
||||
>批量取消授权</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -66,11 +66,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="CircleClose"
|
||||
@click="cancelAuthUser(scope.row)"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
<el-button link icon="CircleClose" @click="cancelAuthUser(scope.row)" v-hasPermission="['system:role:remove']"
|
||||
>取消授权</el-button
|
||||
>
|
||||
</template>
|
||||
@ -90,11 +86,11 @@
|
||||
|
||||
<script setup name="AuthUser">
|
||||
import selectUser from './selectUser';
|
||||
import {allocatedUserList, deleteRoleOfUser, deleteRoleOfSomeUser} from '@/api/system/role';
|
||||
import { allocatedUserList, deleteRoleOfUser, deleteRoleOfSomeUser } from '@/api/system/role';
|
||||
|
||||
const route = useRoute();
|
||||
const {proxy} = getCurrentInstance();
|
||||
const {sys_status} = proxy.useDict('sys_status');
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_status } = proxy.useDict('sys_status');
|
||||
|
||||
const userList = ref([]);
|
||||
const loading = ref(true);
|
||||
@ -125,7 +121,7 @@ function getList() {
|
||||
}
|
||||
// 返回按钮
|
||||
function handleClose() {
|
||||
const obj = {path: '/system/role'};
|
||||
const obj = { path: '/system/role' };
|
||||
proxy.$tab.closeOpenPage(obj);
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
@ -151,7 +147,7 @@ function openSelectUser() {
|
||||
function cancelAuthUser(row) {
|
||||
proxy.$modal
|
||||
.confirm(`确认要取消该用户"${row.username}"角色吗?`)
|
||||
.then(() => deleteRoleOfSomeUser({userIds: row.userId}))
|
||||
.then(() => deleteRoleOfSomeUser({ userIds: row.userId }))
|
||||
.then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('取消授权成功');
|
||||
@ -160,11 +156,11 @@ function cancelAuthUser(row) {
|
||||
}
|
||||
/** 批量取消授权按钮操作 */
|
||||
function cancelAuthUserAll(row) {
|
||||
const {roleId} = queryParams;
|
||||
const { roleId } = queryParams;
|
||||
const uIds = userIds.value.join(',');
|
||||
proxy.$modal
|
||||
.confirm('是否取消选中用户授权数据项?')
|
||||
.then(() => deleteRoleOfSomeUser({roleId, userIds: uIds}))
|
||||
.then(() => deleteRoleOfSomeUser({ roleId, userIds: uIds }))
|
||||
.then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess('取消授权成功');
|
||||
|
||||
@ -41,7 +41,9 @@
|
||||
</el-form>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:role:add']">新增</el-button>
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermission="['system:role:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@ -50,7 +52,7 @@
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
v-hasPermission="['system:role:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -61,12 +63,12 @@
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
v-hasPermission="['system:role:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:role:export']"
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermission="['system:role:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -99,34 +101,34 @@
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
v-hasPermission="['system:role:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:role:remove']"
|
||||
v-hasPermission="['system:role:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="数据权限" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="handleDataScope(scope.row)"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
v-hasPermission="['system:role:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="分配用户" placement="top" v-if="scope.row.roleId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="User"
|
||||
@click="handleAuthUser(scope.row)"
|
||||
v-hasPermi="['system:role:edit']"
|
||||
v-hasPermission="['system:role:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
@ -182,7 +184,7 @@
|
||||
node-key="menuId"
|
||||
:check-strictly="!form.menuCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="{label: 'label', children: 'children'}"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
></el-tree>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
@ -233,7 +235,7 @@
|
||||
node-key="id"
|
||||
:check-strictly="!form.deptCheckStrictly"
|
||||
empty-text="加载中,请稍候"
|
||||
:props="{label: 'label', children: 'children'}"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
></el-tree>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -248,13 +250,21 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Role">
|
||||
import {addRole, changeRoleStatus, changeDataScope, deleteRole, getRole, listRole, updateRole} from '@/api/system/role';
|
||||
import {getMenuSelectTreeByRole, getMenuSelectTree} from '@/api/system/menu';
|
||||
import {getDeptSelectTree, getDeptTreeSelectByRole} from '@/api/system/dept';
|
||||
import {
|
||||
addRole,
|
||||
changeRoleStatus,
|
||||
changeDataScope,
|
||||
deleteRole,
|
||||
getRole,
|
||||
listRole,
|
||||
updateRole,
|
||||
} from '@/api/system/role';
|
||||
import { getMenuSelectTreeByRole, getMenuSelectTree } from '@/api/system/menu';
|
||||
import { getDeptSelectTree, getDeptTreeSelectByRole } from '@/api/system/dept';
|
||||
|
||||
const router = useRouter();
|
||||
const {proxy} = getCurrentInstance();
|
||||
const {sys_status} = proxy.useDict('sys_status');
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_status } = proxy.useDict('sys_status');
|
||||
|
||||
const roleList = ref([]);
|
||||
const open = ref(false);
|
||||
@ -278,11 +288,11 @@ const deptRef = ref(null);
|
||||
|
||||
/** 数据范围选项 */
|
||||
const dataScopeOptions = ref([
|
||||
{value: '1', label: '全部数据权限'},
|
||||
{value: '2', label: '自定数据权限'},
|
||||
{value: '3', label: '本部门数据权限'},
|
||||
{value: '4', label: '本部门及以下数据权限'},
|
||||
{value: '5', label: '仅本人数据权限'},
|
||||
{ value: '1', label: '全部数据权限' },
|
||||
{ value: '2', label: '自定数据权限' },
|
||||
{ value: '3', label: '本部门数据权限' },
|
||||
{ value: '4', label: '本部门及以下数据权限' },
|
||||
{ value: '5', label: '仅本人数据权限' },
|
||||
]);
|
||||
|
||||
const data = reactive({
|
||||
@ -295,13 +305,13 @@ const data = reactive({
|
||||
status: undefined,
|
||||
},
|
||||
rules: {
|
||||
roleName: [{required: true, message: '角色名称不能为空', trigger: 'blur'}],
|
||||
roleKey: [{required: true, message: '权限字符不能为空', trigger: 'blur'}],
|
||||
roleSort: [{required: true, message: '角色顺序不能为空', trigger: 'blur'}],
|
||||
roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
|
||||
roleKey: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
|
||||
roleSort: [{ required: true, message: '角色顺序不能为空', trigger: 'blur' }],
|
||||
},
|
||||
});
|
||||
|
||||
const {queryParams, form, rules} = toRefs(data);
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询角色列表 */
|
||||
function getList() {
|
||||
@ -440,7 +450,7 @@ function handleUpdate(row) {
|
||||
open.value = true;
|
||||
nextTick(() => {
|
||||
roleMenu.then((res) => {
|
||||
const {checkedKeys} = res;
|
||||
const { checkedKeys } = res;
|
||||
checkedKeys.forEach((v) => {
|
||||
nextTick(() => {
|
||||
menuRef.value.setChecked(v, true, false);
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<div class="head-container">
|
||||
<el-tree
|
||||
:data="deptOptions"
|
||||
:props="{label: 'label', children: 'children'}"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="deptTreeRef"
|
||||
@ -69,7 +69,7 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:user:add']"
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermission="['system:user:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -80,7 +80,7 @@
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['system:user:edit']"
|
||||
v-hasPermission="['system:user:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -91,17 +91,22 @@
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['system:user:remove']"
|
||||
v-hasPermission="['system:user:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:import']"
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermission="['system:user:import']"
|
||||
>导入</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']"
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermission="['system:user:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
@ -162,34 +167,34 @@
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top" v-if="scope.row.userId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['system:user:edit']"
|
||||
v-hasPermission="['system:user:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top" v-if="scope.row.userId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['system:user:remove']"
|
||||
v-hasPermission="['system:user:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="重置密码" placement="top" v-if="scope.row.userId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="Key"
|
||||
@click="handleResetPwd(scope.row)"
|
||||
v-hasPermi="['system:user:resetPwd']"
|
||||
v-hasPermission="['system:user:resetPwd']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="分配角色" placement="top" v-if="scope.row.userId !== 1">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
icon="CircleCheck"
|
||||
@click="handleAuthRole(scope.row)"
|
||||
v-hasPermi="['system:user:edit']"
|
||||
v-hasPermission="['system:user:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
@ -219,7 +224,7 @@
|
||||
<el-tree-select
|
||||
v-model="form.deptId"
|
||||
:data="deptOptions"
|
||||
:props="{value: 'id', label: 'label', children: 'children'}"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
value-key="id"
|
||||
placeholder="请选择归属部门"
|
||||
check-strictly
|
||||
@ -363,13 +368,13 @@
|
||||
</template>
|
||||
|
||||
<script setup name="User">
|
||||
import {getToken} from '@/utils/auth';
|
||||
import {getDeptSelectTree} from '@/api/system/dept';
|
||||
import {changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser} from '@/api/system/user';
|
||||
import { getToken } from '@/utils/token';
|
||||
import { getDeptSelectTree } from '@/api/system/dept';
|
||||
import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser } from '@/api/system/user';
|
||||
|
||||
const router = useRouter();
|
||||
const {proxy} = getCurrentInstance();
|
||||
const {sys_status, sys_user_sex} = proxy.useDict('sys_status', 'sys_user_sex');
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_status, sys_user_sex } = proxy.useDict('sys_status', 'sys_user_sex');
|
||||
|
||||
const userList = ref([]);
|
||||
const open = ref(false);
|
||||
@ -397,19 +402,19 @@ const upload = reactive({
|
||||
// 是否更新已经存在的用户数据
|
||||
updateSupport: 0,
|
||||
// 设置上传的请求头部
|
||||
headers: {Authorization: `Bearer ${getToken()}`},
|
||||
headers: { Authorization: `Bearer ${getToken()}` },
|
||||
// 上传的地址
|
||||
url: `${import.meta.env.VITE_APP_BASE_API}/system/user/importData`,
|
||||
});
|
||||
// 列显隐信息
|
||||
const columns = ref([
|
||||
{key: 0, label: '用户编号', visible: true},
|
||||
{key: 1, label: '用户名称', visible: true},
|
||||
{key: 2, label: '用户昵称', visible: true},
|
||||
{key: 3, label: '部门', visible: true},
|
||||
{key: 4, label: '手机号码', visible: true},
|
||||
{key: 5, label: '状态', visible: true},
|
||||
{key: 6, label: '创建时间', visible: true},
|
||||
{ key: 0, label: '用户编号', visible: true },
|
||||
{ key: 1, label: '用户名称', visible: true },
|
||||
{ key: 2, label: '用户昵称', visible: true },
|
||||
{ key: 3, label: '部门', visible: true },
|
||||
{ key: 4, label: '手机号码', visible: true },
|
||||
{ key: 5, label: '状态', visible: true },
|
||||
{ key: 6, label: '创建时间', visible: true },
|
||||
]);
|
||||
|
||||
const data = reactive({
|
||||
@ -424,7 +429,7 @@ const data = reactive({
|
||||
},
|
||||
rules: {
|
||||
username: [
|
||||
{required: true, message: '用户名称不能为空', trigger: 'blur'},
|
||||
{ required: true, message: '用户名称不能为空', trigger: 'blur' },
|
||||
{
|
||||
min: 2,
|
||||
max: 20,
|
||||
@ -432,9 +437,9 @@ const data = reactive({
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
nickName: [{required: true, message: '用户昵称不能为空', trigger: 'blur'}],
|
||||
nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
|
||||
password: [
|
||||
{required: true, message: '用户密码不能为空', trigger: 'blur'},
|
||||
{ required: true, message: '用户密码不能为空', trigger: 'blur' },
|
||||
{
|
||||
min: 5,
|
||||
max: 20,
|
||||
@ -442,12 +447,12 @@ const data = reactive({
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
email: [{type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change']}],
|
||||
phoneNumber: [{pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur'}],
|
||||
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }],
|
||||
phoneNumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
|
||||
},
|
||||
});
|
||||
|
||||
const {queryParams, form, rules} = toRefs(data);
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 通过条件过滤节点 */
|
||||
const filterNode = (value, data) => {
|
||||
@ -542,7 +547,7 @@ function handleCommand(command, row) {
|
||||
}
|
||||
/** 跳转角色分配 */
|
||||
function handleAuthRole(row) {
|
||||
const {userId} = row;
|
||||
const { userId } = row;
|
||||
router.push(`/system/user-auth/role/${userId}`);
|
||||
}
|
||||
/** 重置密码按钮操作 */
|
||||
@ -555,7 +560,7 @@ function handleResetPwd(row) {
|
||||
inputPattern: /^.{5,20}$/,
|
||||
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
|
||||
})
|
||||
.then(({value}) => {
|
||||
.then(({ value }) => {
|
||||
resetUserPwd(row.userId, value).then((response) => {
|
||||
proxy.$modal.msgSuccess(`修改成功,新密码是:${value}`);
|
||||
});
|
||||
@ -589,7 +594,7 @@ const handleFileSuccess = (response, file, fileList) => {
|
||||
proxy.$alert(
|
||||
`<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>${response.msg}</div>`,
|
||||
'导入结果',
|
||||
{dangerouslyUseHTMLString: true},
|
||||
{ dangerouslyUseHTMLString: true },
|
||||
);
|
||||
getList();
|
||||
};
|
||||
|
||||
@ -1,23 +1,24 @@
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import path from 'path';
|
||||
import createVitePlugins from './vite/plugins';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({mode, command}) => {
|
||||
export default defineConfig(({ mode, command }) => {
|
||||
const env = loadEnv(mode, process.cwd());
|
||||
const {VITE_APP_ENV} = env;
|
||||
const { VITE_APP_ENV } = env;
|
||||
return {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
|
||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。
|
||||
// 例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||
base: VITE_APP_ENV === 'production' ? '/' : '/',
|
||||
plugins: createVitePlugins(env, command === 'build'),
|
||||
resolve: {
|
||||
// https://cn.vitejs.dev/config/#resolve-alias
|
||||
alias: {
|
||||
// 设置路径
|
||||
// 设置路径别名
|
||||
'~': path.resolve(__dirname, './'),
|
||||
// 设置别名
|
||||
// 设置路径别名
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
},
|
||||
// https://cn.vitejs.dev/config/#resolve-extensions
|
||||
@ -31,8 +32,10 @@ export default defineConfig(({mode, command}) => {
|
||||
proxy: {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
'/dev-api': {
|
||||
// 后端地址
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
// 将/dev-api路径去掉
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, ''),
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
import autoImport from 'unplugin-auto-import/vite'
|
||||
import autoImport from 'unplugin-auto-import/vite';
|
||||
|
||||
// 自动导入插件
|
||||
// 配置完成之后使用ref reactive watch 等无须import 导入 ,可以直接使用
|
||||
export default function createAutoImport() {
|
||||
return autoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
{
|
||||
'vuex': ['useStore']
|
||||
}
|
||||
],
|
||||
dts: false
|
||||
})
|
||||
return autoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
{
|
||||
vuex: ['useStore'],
|
||||
},
|
||||
],
|
||||
// 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
|
||||
dts: false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,28 +1,29 @@
|
||||
import compression from 'vite-plugin-compression'
|
||||
import compression from 'vite-plugin-compression';
|
||||
|
||||
// 根据env.production或其他环境的配置文件中的VITE_BUILD_COMPRESS参数 来设定使用哪种压缩方式
|
||||
export default function createCompression(env) {
|
||||
const { VITE_BUILD_COMPRESS } = env
|
||||
const plugin = []
|
||||
if (VITE_BUILD_COMPRESS) {
|
||||
const compressList = VITE_BUILD_COMPRESS.split(',')
|
||||
if (compressList.includes('gzip')) {
|
||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||
plugin.push(
|
||||
compression({
|
||||
ext: '.gz',
|
||||
deleteOriginFile: false
|
||||
})
|
||||
)
|
||||
}
|
||||
if (compressList.includes('brotli')) {
|
||||
plugin.push(
|
||||
compression({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile: false
|
||||
})
|
||||
)
|
||||
}
|
||||
const { VITE_BUILD_COMPRESS } = env;
|
||||
const plugin = [];
|
||||
if (VITE_BUILD_COMPRESS) {
|
||||
const compressList = VITE_BUILD_COMPRESS.split(',');
|
||||
if (compressList.includes('gzip')) {
|
||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||
plugin.push(
|
||||
compression({
|
||||
ext: '.gz',
|
||||
deleteOriginFile: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return plugin
|
||||
if (compressList.includes('brotli')) {
|
||||
plugin.push(
|
||||
compression({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
|
||||
import createAutoImport from './auto-import'
|
||||
import createSvgIcon from './svg-icon'
|
||||
import createCompression from './compression'
|
||||
import createSetupExtend from './setup-extend'
|
||||
import createAutoImport from './auto-import';
|
||||
import createSvgIcon from './svg-icon';
|
||||
import createCompression from './compression';
|
||||
import createSetupExtend from './setup-extend';
|
||||
|
||||
// 加载插件入口
|
||||
export default function createVitePlugins(viteEnv, isBuild = false) {
|
||||
const vitePlugins = [vue()]
|
||||
vitePlugins.push(createAutoImport())
|
||||
vitePlugins.push(createSetupExtend())
|
||||
vitePlugins.push(createSvgIcon(isBuild))
|
||||
isBuild && vitePlugins.push(...createCompression(viteEnv))
|
||||
return vitePlugins
|
||||
const vitePlugins = [vue()];
|
||||
vitePlugins.push(createAutoImport());
|
||||
vitePlugins.push(createSetupExtend());
|
||||
vitePlugins.push(createSvgIcon(isBuild));
|
||||
isBuild && vitePlugins.push(...createCompression(viteEnv));
|
||||
return vitePlugins;
|
||||
}
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
import setupExtend from 'vite-plugin-vue-setup-extend'
|
||||
import setupExtend from 'vite-plugin-vue-setup-extend';
|
||||
|
||||
// 在使用 Vue3.2 的 setup 语法糖后,无法优雅的定义组件的 name 值,
|
||||
// 虽然 vite 会根据组件的文件名自动生成组件名,但是需要自定义的组件名时,就很不方便。
|
||||
// <script setup name="Logininfor">
|
||||
// 就可以这样自定义组件名
|
||||
export default function createSetupExtend() {
|
||||
return setupExtend()
|
||||
return setupExtend();
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import svgIcon from 'vite-plugin-svg-icons'
|
||||
import path from 'path'
|
||||
import svgIcon from 'vite-plugin-svg-icons';
|
||||
import path from 'path';
|
||||
|
||||
// 当你使用该插件的时候,指定好存放svg的文件夹。再按照指定的方式去访问svg图片。就可以再不产生http请求的情况下渲染出svg图片。
|
||||
// 使用方式如下
|
||||
// <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg>
|
||||
export default function createSvgIcon(isBuild) {
|
||||
return svgIcon({
|
||||
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
|
||||
symbolId: 'icon-[dir]-[name]',
|
||||
svgoOptions: isBuild
|
||||
})
|
||||
return svgIcon({
|
||||
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
|
||||
symbolId: 'icon-[dir]-[name]',
|
||||
svgoOptions: isBuild,
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user