From 656696be4b70513e94f1341db8d1c2d3f43b3e6d Mon Sep 17 00:00:00 2001 From: Your Name <123456> Date: 星期三, 13 七月 2022 09:18:47 +0800 Subject: [PATCH] 登录跳转首页 --- src/views/system/role/index.vue | 32 src/layout/navBars/breadcrumb/user.vue | 561 ++++++++-------- src/api/role/index.ts | 16 src/utils/request.ts | 10 src/views/system/department/component/deptDialog.vue | 36 src/router/backEnd.ts | 2 src/views/system/department/index.vue | 30 src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue | 1 .env.development | 2 /dev/null | 6 src/components/iconSelector/index.vue | 498 +++++++------- src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue | 2 src/views/system/role/component/roleDialog.vue | 25 src/api/department/index.ts | 16 src/api/menu/index.ts | 2 src/views/loginPage/component/accountLogin.vue | 1 src/router/index.ts | 135 +-- src/views/homeMenu/homeMenu.vue | 573 ++++++++++------- src/api/login/index.ts | 7 src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue | 2 src/views/system/menu/component/menuDialog.vue | 2 21 files changed, 1,052 insertions(+), 907 deletions(-) diff --git a/.env.development b/.env.development index ea1c589..0c99294 100644 --- a/.env.development +++ b/.env.development @@ -2,6 +2,6 @@ ENV = 'development' # 本地环境接口地址 -VITE_API_URL = 'http://192.168.0.14:8008' +VITE_API_URL = 'http://192.168.0.35:8008' # VITE_API_URL = 'http://192.168.0.8:8008' diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ -<component name="InspectionProjectProfileManager"> - <profile version="1.0"> - <option name="myName" value="Project Default" /> - <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> - </profile> -</component> \ No newline at end of file diff --git a/src/api/department/index.ts b/src/api/department/index.ts index 6f43002..3733527 100644 --- a/src/api/department/index.ts +++ b/src/api/department/index.ts @@ -2,14 +2,14 @@ export function departmentApi() { return { - // v1 + // v2 getDepartmentList: () => { return request({ url: `/department/list`, method: 'post' }); }, - // v1 + // v2 addDepartment: (data: object) => { return request({ url: `/department/add`, @@ -17,13 +17,21 @@ data: data }); }, - // v1 + // v2 modDepartment: (data: object) => { return request({ url: `/department/mod`, method: 'post', data: data }); - } + }, + // v1 + deleteDepartment: (value?: object) => { + return request({ + url: `/department/del`, + method: 'post', + data: value + }); + }, }; } diff --git a/src/api/login/index.ts b/src/api/login/index.ts index 0d27058..0cd50c5 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -16,11 +16,10 @@ }); }, // v1 - signOut: (params: object) => { + signOut: () => { return request({ - url: '/user/signOut', - method: 'post', - data: params + url: '/auth/logout', + method: 'post' }); } }; diff --git a/src/api/menu/index.ts b/src/api/menu/index.ts index d92bc29..ddfda6c 100644 --- a/src/api/menu/index.ts +++ b/src/api/menu/index.ts @@ -8,7 +8,7 @@ */ export function useMenuApi() { return { - // v1 + // v2 getMenuAdmin: (value?: string) => { return request({ url: `/auth/menu?projectId= ${value}`, diff --git a/src/api/role/index.ts b/src/api/role/index.ts index e0b9151..3b85d45 100644 --- a/src/api/role/index.ts +++ b/src/api/role/index.ts @@ -2,14 +2,14 @@ export function useRoleApi() { return { - // v1 + // v2 getRoleList: () => { return request({ url: `/role/list`, method: 'post' }); }, - // v1 + // v2 addRole: (data: object) => { return request({ url: `/role/add`, @@ -17,13 +17,21 @@ data: data }); }, - // v1 + // v2 modRole: (data: object) => { return request({ url: `/role/mod`, method: 'post', data: data }); - } + }, + // v2 + deleteRole: (value?: object) => { + return request({ + url: `/role/del`, + method: 'post', + data: value + }); + }, }; } diff --git a/src/components/iconSelector/index.vue b/src/components/iconSelector/index.vue index 07de786..3010e16 100644 --- a/src/components/iconSelector/index.vue +++ b/src/components/iconSelector/index.vue @@ -1,252 +1,252 @@ -<template> - <div class="icon-selector w100 h100"> - <el-popover - placement="bottom" - :width="fontIconWidth" - trigger="click" - transition="el-zoom-in-top" - popper-class="icon-selector-popper" - @show="onPopoverShow" - > - <template #reference> - <el-input - v-model="fontIconSearch" - :placeholder="fontIconPlaceholder" - :clearable="clearable" - :disabled="disabled" - :size="size" - ref="inputWidthRef" - @clear="onClearFontIcon" - @focus="onIconFocus" - @blur="onIconBlur" - > - <template #prepend> - <SvgIcon - :name="fontIconPrefix === '' ? prepend : fontIconPrefix" - class="font14" - v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1" - /> - <i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i> - </template> - </el-input> - </template> - <template #default> - <div class="icon-selector-warp"> - <div class="icon-selector-warp-title flex"> - <div class="flex-auto">{{ title }}</div> - <div class="icon-selector-warp-title-tab" v-if="type === 'all'"> - <span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span> - <span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span> - <span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span> - </div> - </div> - <div class="icon-selector-warp-row"> - <el-scrollbar ref="selectorScrollbarRef"> - <el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0"> - <el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k"> - <div class="icon-selector-warp-item" :class="{ 'icon-selector-active': fontIconPrefix === v }"> - <div class="flex-margin"> - <div class="icon-selector-warp-item-value"> - <SvgIcon :name="v" /> - </div> - </div> - </div> - </el-col> - </el-row> - <el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty> - </el-scrollbar> - </div> - </div> - </template> - </el-popover> - </div> -</template> +<!--<template>--> +<!-- <div class="icon-selector w100 h100">--> +<!-- <el-popover--> +<!-- placement="bottom"--> +<!-- :width="fontIconWidth"--> +<!-- trigger="click"--> +<!-- transition="el-zoom-in-top"--> +<!-- popper-class="icon-selector-popper"--> +<!-- @show="onPopoverShow"--> +<!-- >--> +<!-- <template #reference>--> +<!-- <el-input--> +<!-- v-model="fontIconSearch"--> +<!-- :placeholder="fontIconPlaceholder"--> +<!-- :clearable="clearable"--> +<!-- :disabled="disabled"--> +<!-- :size="size"--> +<!-- ref="inputWidthRef"--> +<!-- @clear="onClearFontIcon"--> +<!-- @focus="onIconFocus"--> +<!-- @blur="onIconBlur"--> +<!-- >--> +<!-- <template #prepend>--> +<!-- <SvgIcon--> +<!-- :name="fontIconPrefix === '' ? prepend : fontIconPrefix"--> +<!-- class="font14"--> +<!-- v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1"--> +<!-- />--> +<!-- <i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i>--> +<!-- </template>--> +<!-- </el-input>--> +<!-- </template>--> +<!-- <template #default>--> +<!-- <div class="icon-selector-warp">--> +<!-- <div class="icon-selector-warp-title flex">--> +<!-- <div class="flex-auto">{{ title }}</div>--> +<!-- <div class="icon-selector-warp-title-tab" v-if="type === 'all'">--> +<!-- <span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span>--> +<!-- <span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span>--> +<!-- <span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span>--> +<!-- </div>--> +<!-- </div>--> +<!-- <div class="icon-selector-warp-row">--> +<!-- <el-scrollbar ref="selectorScrollbarRef">--> +<!-- <el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">--> +<!-- <el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">--> +<!-- <div class="icon-selector-warp-item" :class="{ 'icon-selector-active': fontIconPrefix === v }">--> +<!-- <div class="flex-margin">--> +<!-- <div class="icon-selector-warp-item-value">--> +<!-- <SvgIcon :name="v" />--> +<!-- </div>--> +<!-- </div>--> +<!-- </div>--> +<!-- </el-col>--> +<!-- </el-row>--> +<!-- <el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>--> +<!-- </el-scrollbar>--> +<!-- </div>--> +<!-- </div>--> +<!-- </template>--> +<!-- </el-popover>--> +<!-- </div>--> +<!--</template>--> -<script lang="ts"> -import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue'; -import initIconfont from '/@/utils/getStyleSheets'; +<!--<script lang="ts">--> +<!--import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';--> +<!--import initIconfont from '/@/utils/getStyleSheets';--> -export default defineComponent({ - name: 'iconSelector', - emits: ['update:modelValue', 'get', 'clear'], - props: { - // 输入框前置内容 - prepend: { - type: String, - default: () => 'ele-Pointer', - }, - // 输入框占位文本 - placeholder: { - type: String, - default: () => '请输入内容搜索图标或者选择图标', - }, - // 输入框占位文本 - size: { - type: String, - default: () => 'default', - }, - // 弹窗标题 - title: { - type: String, - default: () => '请选择图标', - }, - // icon 图标类型 - type: { - type: String, - default: () => 'ele', - }, - // 禁用 - disabled: { - type: Boolean, - default: () => false, - }, - // 是否可清空 - clearable: { - type: Boolean, - default: () => true, - }, - // 自定义空状态描述文字 - emptyDescription: { - type: String, - default: () => '无相关图标', - }, - // 双向绑定值,默认为 modelValue, - // 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5 - // 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A - modelValue: String, - }, - setup(props, { emit }) { - const inputWidthRef = ref(); - const selectorScrollbarRef = ref(); - const state = reactive({ - fontIconPrefix: '', - fontIconWidth: 0, - fontIconSearch: '', - fontIconTabsIndex: 0, - fontIconSheetsList: [], - fontIconPlaceholder: '', - fontIconType: 'ali', - fontIconShow: true, - }); - // 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值 - const onIconFocus = () => { - if (!props.modelValue) return false; - state.fontIconSearch = ''; - state.fontIconPlaceholder = props.modelValue; - }; - // 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值 - const onIconBlur = () => { - setTimeout(() => { - const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch); - if (icon.length <= 0) state.fontIconSearch = ''; - }, 300); - }; - // 处理 icon 双向绑定数值回显 - const initModeValueEcho = () => { - if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder); - (<string | undefined>state.fontIconPlaceholder) = props.modelValue; - (<string | undefined>state.fontIconPrefix) = props.modelValue; - }; - // 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题 - const initFontIconTypeEcho = () => { - if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali'); - else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele'); - else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe'); - else onIconChange('ali'); - }; - // 图标搜索及图标数据显示 - const fontIconSheetsFilterList = computed(() => { - if (!state.fontIconSearch) return state.fontIconSheetsList; - let search = state.fontIconSearch.trim().toLowerCase(); - return state.fontIconSheetsList.filter((item: any) => { - if (item.toLowerCase().indexOf(search) !== -1) return item; - }); - }); - // 获取 input 的宽度 - const getInputWidth = () => { - nextTick(() => { - state.fontIconWidth = inputWidthRef.value.$el.offsetWidth; - }); - }; - // 监听页面宽度改变 - const initResize = () => { - window.addEventListener('resize', () => { - getInputWidth(); - }); - }; - // 初始化数据 - const initFontIconData = async (type: string) => { - state.fontIconSheetsList = []; - if (type === 'ali') { - await initIconfont.ali().then((res: any) => { - // 阿里字体图标使用 `iconfont xxx` - state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`); - }); - } else if (type === 'ele') { - await initIconfont.ele().then((res: any) => { - state.fontIconSheetsList = res; - }); - } else if (type === 'awe') { - await initIconfont.awe().then((res: any) => { - // fontawesome字体图标使用 `fa xxx` - state.fontIconSheetsList = res.map((i: string) => `fa ${i}`); - }); - } - // 初始化 input 的 placeholder - // 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81 - state.fontIconPlaceholder = props.placeholder; - // 初始化双向绑定回显 - initModeValueEcho(); - }; - // 图标点击切换 - const onIconChange = (type: string) => { - state.fontIconType = type; - initFontIconData(type); - }; - // 获取当前点击的 icon 图标 - const onColClick = (v: any) => { - state.fontIconPlaceholder = v; - state.fontIconPrefix = v; - emit('get', state.fontIconPrefix); - emit('update:modelValue', state.fontIconPrefix); - }; - // 清空当前点击的 icon 图标 - const onClearFontIcon = () => { - state.fontIconPrefix = ''; - emit('clear', state.fontIconPrefix); - emit('update:modelValue', state.fontIconPrefix); - }; - // 监听 Popover 打开,用于双向绑定值回显 - const onPopoverShow = () => { - initModeValueEcho(); - initFontIconTypeEcho(); - }; - // 页面加载时 - onMounted(() => { - initModeValueEcho(); - initResize(); - getInputWidth(); - }); +<!--export default defineComponent({--> +<!-- name: 'iconSelector',--> +<!-- emits: ['update:modelValue', 'get', 'clear'],--> +<!-- props: {--> +<!-- // 输入框前置内容--> +<!-- prepend: {--> +<!-- type: String,--> +<!-- default: () => 'ele-Pointer',--> +<!-- },--> +<!-- // 输入框占位文本--> +<!-- placeholder: {--> +<!-- type: String,--> +<!-- default: () => '请输入内容搜索图标或者选择图标',--> +<!-- },--> +<!-- // 输入框占位文本--> +<!-- size: {--> +<!-- type: String,--> +<!-- default: () => 'default',--> +<!-- },--> +<!-- // 弹窗标题--> +<!-- title: {--> +<!-- type: String,--> +<!-- default: () => '请选择图标',--> +<!-- },--> +<!-- // icon 图标类型--> +<!-- type: {--> +<!-- type: String,--> +<!-- default: () => 'ele',--> +<!-- },--> +<!-- // 禁用--> +<!-- disabled: {--> +<!-- type: Boolean,--> +<!-- default: () => false,--> +<!-- },--> +<!-- // 是否可清空--> +<!-- clearable: {--> +<!-- type: Boolean,--> +<!-- default: () => true,--> +<!-- },--> +<!-- // 自定义空状态描述文字--> +<!-- emptyDescription: {--> +<!-- type: String,--> +<!-- default: () => '无相关图标',--> +<!-- },--> +<!-- // 双向绑定值,默认为 modelValue,--> +<!-- // 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5--> +<!-- // 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A--> +<!-- modelValue: String,--> +<!-- },--> +<!-- setup(props, { emit }) {--> +<!-- const inputWidthRef = ref();--> +<!-- const selectorScrollbarRef = ref();--> +<!-- const state = reactive({--> +<!-- fontIconPrefix: '',--> +<!-- fontIconWidth: 0,--> +<!-- fontIconSearch: '',--> +<!-- fontIconTabsIndex: 0,--> +<!-- fontIconSheetsList: [],--> +<!-- fontIconPlaceholder: '',--> +<!-- fontIconType: 'ali',--> +<!-- fontIconShow: true,--> +<!-- });--> +<!-- // 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值--> +<!-- const onIconFocus = () => {--> +<!-- if (!props.modelValue) return false;--> +<!-- state.fontIconSearch = '';--> +<!-- state.fontIconPlaceholder = props.modelValue;--> +<!-- };--> +<!-- // 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值--> +<!-- const onIconBlur = () => {--> +<!-- setTimeout(() => {--> +<!-- const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch);--> +<!-- if (icon.length <= 0) state.fontIconSearch = '';--> +<!-- }, 300);--> +<!-- };--> +<!-- // 处理 icon 双向绑定数值回显--> +<!-- const initModeValueEcho = () => {--> +<!-- if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);--> +<!-- (<string | undefined>state.fontIconPlaceholder) = props.modelValue;--> +<!-- (<string | undefined>state.fontIconPrefix) = props.modelValue;--> +<!-- };--> +<!-- // 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题--> +<!-- const initFontIconTypeEcho = () => {--> +<!-- if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali');--> +<!-- else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele');--> +<!-- else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe');--> +<!-- else onIconChange('ali');--> +<!-- };--> +<!-- // 图标搜索及图标数据显示--> +<!-- const fontIconSheetsFilterList = computed(() => {--> +<!-- if (!state.fontIconSearch) return state.fontIconSheetsList;--> +<!-- let search = state.fontIconSearch.trim().toLowerCase();--> +<!-- return state.fontIconSheetsList.filter((item: any) => {--> +<!-- if (item.toLowerCase().indexOf(search) !== -1) return item;--> +<!-- });--> +<!-- });--> +<!-- // 获取 input 的宽度--> +<!-- const getInputWidth = () => {--> +<!-- nextTick(() => {--> +<!-- state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;--> +<!-- });--> +<!-- };--> +<!-- // 监听页面宽度改变--> +<!-- const initResize = () => {--> +<!-- window.addEventListener('resize', () => {--> +<!-- getInputWidth();--> +<!-- });--> +<!-- };--> +<!-- // 初始化数据--> +<!-- const initFontIconData = async (type: string) => {--> +<!-- state.fontIconSheetsList = [];--> +<!-- if (type === 'ali') {--> +<!-- await initIconfont.ali().then((res: any) => {--> +<!-- // 阿里字体图标使用 `iconfont xxx`--> +<!-- state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`);--> +<!-- });--> +<!-- } else if (type === 'ele') {--> +<!-- await initIconfont.ele().then((res: any) => {--> +<!-- state.fontIconSheetsList = res;--> +<!-- });--> +<!-- } else if (type === 'awe') {--> +<!-- await initIconfont.awe().then((res: any) => {--> +<!-- // fontawesome字体图标使用 `fa xxx`--> +<!-- state.fontIconSheetsList = res.map((i: string) => `fa ${i}`);--> +<!-- });--> +<!-- }--> +<!-- // 初始化 input 的 placeholder--> +<!-- // 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81--> +<!-- state.fontIconPlaceholder = props.placeholder;--> +<!-- // 初始化双向绑定回显--> +<!-- initModeValueEcho();--> +<!-- };--> +<!-- // 图标点击切换--> +<!-- const onIconChange = (type: string) => {--> +<!-- state.fontIconType = type;--> +<!-- initFontIconData(type);--> +<!-- };--> +<!-- // 获取当前点击的 icon 图标--> +<!-- const onColClick = (v: any) => {--> +<!-- state.fontIconPlaceholder = v;--> +<!-- state.fontIconPrefix = v;--> +<!-- emit('get', state.fontIconPrefix);--> +<!-- emit('update:modelValue', state.fontIconPrefix);--> +<!-- };--> +<!-- // 清空当前点击的 icon 图标--> +<!-- const onClearFontIcon = () => {--> +<!-- state.fontIconPrefix = '';--> +<!-- emit('clear', state.fontIconPrefix);--> +<!-- emit('update:modelValue', state.fontIconPrefix);--> +<!-- };--> +<!-- // 监听 Popover 打开,用于双向绑定值回显--> +<!-- const onPopoverShow = () => {--> +<!-- initModeValueEcho();--> +<!-- initFontIconTypeEcho();--> +<!-- };--> +<!-- // 页面加载时--> +<!-- onMounted(() => {--> +<!-- initModeValueEcho();--> +<!-- initResize();--> +<!-- getInputWidth();--> +<!-- });--> - // 监听双向绑定 modelValue 的变化 - watch( - () => props.modelValue, - () => { - initModeValueEcho(); - } - ); - return { - inputWidthRef, - selectorScrollbarRef, - fontIconSheetsFilterList, - onColClick, - onIconChange, - onClearFontIcon, - onIconFocus, - onIconBlur, - onPopoverShow, - ...toRefs(state), - }; - }, -}); -</script> +<!-- // 监听双向绑定 modelValue 的变化--> +<!-- watch(--> +<!-- () => props.modelValue,--> +<!-- () => {--> +<!-- initModeValueEcho();--> +<!-- }--> +<!-- );--> +<!-- return {--> +<!-- inputWidthRef,--> +<!-- selectorScrollbarRef,--> +<!-- fontIconSheetsFilterList,--> +<!-- onColClick,--> +<!-- onIconChange,--> +<!-- onClearFontIcon,--> +<!-- onIconFocus,--> +<!-- onIconBlur,--> +<!-- onPopoverShow,--> +<!-- ...toRefs(state),--> +<!-- };--> +<!-- },--> +<!--});--> +<!--</script>--> diff --git a/src/layout/navBars/breadcrumb/user.vue b/src/layout/navBars/breadcrumb/user.vue index ca35a27..e0e0ba4 100644 --- a/src/layout/navBars/breadcrumb/user.vue +++ b/src/layout/navBars/breadcrumb/user.vue @@ -1,79 +1,85 @@ <template> - <div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }"> - <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange"> - <div class="layout-navbars-breadcrumb-user-icon"> - <i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i> - </div> - <template #dropdown> - <el-dropdown-menu> - <el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item> - <el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{ $t('message.user.dropdownDefault') }}</el-dropdown-item> - <el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item> - </el-dropdown-menu> - </template> - </el-dropdown> - <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange"> - <div class="layout-navbars-breadcrumb-user-icon"> - <i class="iconfont" :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'" :title="$t('message.user.title1')"></i> - </div> - <template #dropdown> - <el-dropdown-menu> - <el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item> - <el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item> - <el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item> - </el-dropdown-menu> - </template> - </el-dropdown> - <div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick"> - <el-icon :title="$t('message.user.title2')"> - <ele-Search /> - </el-icon> - </div> - <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick"> - <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i> - </div> - <div class="layout-navbars-breadcrumb-user-icon"> - <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false"> - <template #reference> - <el-badge :is-dot="true"> - <el-icon :title="$t('message.user.title4')"> - <ele-Bell /> - </el-icon> - </el-badge> - </template> - <template #default> - <UserNews /> - </template> - </el-popover> - </div> - <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick"> - <i - class="iconfont" - :title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')" - :class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'" - ></i> - </div> - <el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick"> - <span class="layout-navbars-breadcrumb-user-link"> - <img :src="userInfos.photo" class="layout-navbars-breadcrumb-user-link-photo mr5" /> - {{ userInfos.userName }} - <el-icon class="el-icon--right"> - <ele-ArrowDown /> - </el-icon> - </span> - <template #dropdown> - <el-dropdown-menu> - <el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item> - <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item> - <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item> - <el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item> - <el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item> - <el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item> - </el-dropdown-menu> - </template> - </el-dropdown> - <Search ref="searchRef" /> - </div> + <div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }"> + <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange"> + <div class="layout-navbars-breadcrumb-user-icon"> + <i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i> + </div> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item> + <el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{ + $t('message.user.dropdownDefault') + }}</el-dropdown-item> + <el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange"> + <div class="layout-navbars-breadcrumb-user-icon"> + <i + class="iconfont" + :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'" + :title="$t('message.user.title1')" + ></i> + </div> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item> + <el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item> + <el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + <div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick"> + <el-icon :title="$t('message.user.title2')"> + <ele-Search /> + </el-icon> + </div> + <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick"> + <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i> + </div> + <div class="layout-navbars-breadcrumb-user-icon"> + <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false"> + <template #reference> + <el-badge :is-dot="true"> + <el-icon :title="$t('message.user.title4')"> + <ele-Bell /> + </el-icon> + </el-badge> + </template> + <template #default> + <UserNews /> + </template> + </el-popover> + </div> + <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick"> + <i + class="iconfont" + :title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')" + :class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'" + ></i> + </div> + <el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick"> + <span class="layout-navbars-breadcrumb-user-link"> + <img :src="userInfos.photo" class="layout-navbars-breadcrumb-user-link-photo mr5" /> + {{ userInfos.userName }} + <el-icon class="el-icon--right"> + <ele-ArrowDown /> + </el-icon> + </span> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item command="/homeMenu">{{ $t('message.user.dropdown1') }}</el-dropdown-item> + <!-- <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>--> + <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item> + <!-- <el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>--> + <!-- <el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>--> + <el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + <Search ref="searchRef" /> + </div> </template> <script lang="ts"> @@ -89,210 +95,219 @@ import { Session, Local } from '/@/utils/storage'; import UserNews from '/@/layout/navBars/breadcrumb/userNews.vue'; import Search from '/@/layout/navBars/breadcrumb/search.vue'; +import { useLoginApi } from '/@/api/login'; export default defineComponent({ - name: 'layoutBreadcrumbUser', - components: { UserNews, Search }, - setup() { - const { t } = useI18n(); - const { proxy } = <any>getCurrentInstance(); - const router = useRouter(); - const stores = useUserInfo(); - const storesThemeConfig = useThemeConfig(); - const { userInfos } = storeToRefs(stores); - const { themeConfig } = storeToRefs(storesThemeConfig); - const searchRef = ref(); - const state = reactive({ - isScreenfull: false, - disabledI18n: 'zh-cn', - disabledSize: 'large', - }); - // 设置分割样式 - const layoutUserFlexNum = computed(() => { - let num: string | number = ''; - const { layout, isClassicSplitMenu } = themeConfig.value; - const layoutArr: string[] = ['defaults', 'columns']; - if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1'; - else num = ''; - return num; - }); - // 全屏点击时 - const onScreenfullClick = () => { - if (!screenfull.isEnabled) { - ElMessage.warning('暂不不支持全屏'); - return false; - } - screenfull.toggle(); - screenfull.on('change', () => { - if (screenfull.isFullscreen) state.isScreenfull = true; - else state.isScreenfull = false; - }); - }; - // 布局配置 icon 点击时 - const onLayoutSetingClick = () => { - proxy.mittBus.emit('openSetingsDrawer'); - }; - // 下拉菜单点击时 - const onHandleCommandClick = (path: string) => { - if (path === 'logOut') { - ElMessageBox({ - closeOnClickModal: false, - closeOnPressEscape: false, - title: t('message.user.logOutTitle'), - message: t('message.user.logOutMessage'), - showCancelButton: true, - confirmButtonText: t('message.user.logOutConfirm'), - cancelButtonText: t('message.user.logOutCancel'), - buttonSize: 'default', - beforeClose: (action, instance, done) => { - if (action === 'confirm') { - instance.confirmButtonLoading = true; - instance.confirmButtonText = t('message.user.logOutExit'); - setTimeout(() => { - done(); - setTimeout(() => { - instance.confirmButtonLoading = false; - }, 300); - }, 700); - } else { - done(); - } - }, - }) - .then(async () => { - Session.clear(); // 清除缓存/token等 - // 使用 reload 时,不需要调用 resetRoute() 重置路由 - window.location.reload(); - }) - .catch(() => {}); - } else if (path === 'wareHouse') { - window.open('https://gitee.com/lyt-top/vue-next-admin'); - } else { - router.push(path); - } - }; - // 菜单搜索点击 - const onSearchClick = () => { - searchRef.value.openSearch(); - }; - // 组件大小改变 - const onComponentSizeChange = (size: string) => { - Local.remove('themeConfig'); - themeConfig.value.globalComponentSize = size; - Local.set('themeConfig', themeConfig.value); - initComponentSize(); - window.location.reload(); - }; - // 语言切换 - const onLanguageChange = (lang: string) => { - Local.remove('themeConfig'); - themeConfig.value.globalI18n = lang; - Local.set('themeConfig', themeConfig.value); - proxy.$i18n.locale = lang; - initI18n(); - other.useTitle(); - }; - // 设置 element plus 组件的国际化 - const setI18nConfig = (locale: string) => { - proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]); - }; - // 初始化言语国际化 - const initI18n = () => { - switch (Local.get('themeConfig').globalI18n) { - case 'zh-cn': - state.disabledI18n = 'zh-cn'; - setI18nConfig('zh-cn'); - break; - case 'en': - state.disabledI18n = 'en'; - setI18nConfig('en'); - break; - case 'zh-tw': - state.disabledI18n = 'zh-tw'; - setI18nConfig('zh-tw'); - break; - } - }; - // 初始化全局组件大小 - const initComponentSize = () => { - switch (Local.get('themeConfig').globalComponentSize) { - case 'large': - state.disabledSize = 'large'; - break; - case 'default': - state.disabledSize = 'default'; - break; - case 'small': - state.disabledSize = 'small'; - break; - } - }; - // 页面加载时 - onMounted(() => { - if (Local.get('themeConfig')) { - initI18n(); - initComponentSize(); - } - }); - return { - userInfos, - onLayoutSetingClick, - onHandleCommandClick, - onScreenfullClick, - onSearchClick, - onComponentSizeChange, - onLanguageChange, - searchRef, - layoutUserFlexNum, - ...toRefs(state), - }; - }, + name: 'layoutBreadcrumbUser', + components: { UserNews, Search }, + setup() { + const { t } = useI18n(); + const { proxy } = <any>getCurrentInstance(); + const router = useRouter(); + const stores = useUserInfo(); + const storesThemeConfig = useThemeConfig(); + const { userInfos } = storeToRefs(stores); + const { themeConfig } = storeToRefs(storesThemeConfig); + const searchRef = ref(); + const state = reactive({ + isScreenfull: false, + disabledI18n: 'zh-cn', + disabledSize: 'large' + }); + // 设置分割样式 + const layoutUserFlexNum = computed(() => { + let num: string | number = ''; + const { layout, isClassicSplitMenu } = themeConfig.value; + const layoutArr: string[] = ['defaults', 'columns']; + if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1'; + else num = ''; + return num; + }); + // 全屏点击时 + const onScreenfullClick = () => { + if (!screenfull.isEnabled) { + ElMessage.warning('暂不不支持全屏'); + return false; + } + screenfull.toggle(); + screenfull.on('change', () => { + if (screenfull.isFullscreen) state.isScreenfull = true; + else state.isScreenfull = false; + }); + }; + // 布局配置 icon 点击时 + const onLayoutSetingClick = () => { + proxy.mittBus.emit('openSetingsDrawer'); + }; + // 下拉菜单点击时 + const onHandleCommandClick = (path: string) => { + if (path === 'logOut') { + ElMessageBox({ + closeOnClickModal: false, + closeOnPressEscape: false, + title: t('message.user.logOutTitle'), + message: t('message.user.logOutMessage'), + showCancelButton: true, + confirmButtonText: t('message.user.logOutConfirm'), + cancelButtonText: t('message.user.logOutCancel'), + buttonSize: 'default', + beforeClose: (action, instance, done) => { + if (action === 'confirm') { + instance.confirmButtonLoading = true; + instance.confirmButtonText = t('message.user.logOutExit'); + setTimeout(() => { + done(); + setTimeout(() => { + instance.confirmButtonLoading = false; + }, 300); + }, 700); + } else { + done(); + } + } + }) + .then(async () => { + let res = await useLoginApi().signOut(); + if (res.data.code === '200') { + Session.clear(); // 清除缓存/token等 + // 使用 reload 时,不需要调用 resetRoute() 重置路由 + window.location.reload(); + } else { + ElMessage({ + type: 'warning', + message: res.data.msg + }); + } + }) + .catch(() => {}); + } else if (path === 'wareHouse') { + window.open('https://gitee.com/lyt-top/vue-next-admin'); + } else { + router.push(path); + } + }; + // 菜单搜索点击 + const onSearchClick = () => { + searchRef.value.openSearch(); + }; + // 组件大小改变 + const onComponentSizeChange = (size: string) => { + Local.remove('themeConfig'); + themeConfig.value.globalComponentSize = size; + Local.set('themeConfig', themeConfig.value); + initComponentSize(); + window.location.reload(); + }; + // 语言切换 + const onLanguageChange = (lang: string) => { + Local.remove('themeConfig'); + themeConfig.value.globalI18n = lang; + Local.set('themeConfig', themeConfig.value); + proxy.$i18n.locale = lang; + initI18n(); + other.useTitle(); + }; + // 设置 element plus 组件的国际化 + const setI18nConfig = (locale: string) => { + proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]); + }; + // 初始化言语国际化 + const initI18n = () => { + switch (Local.get('themeConfig').globalI18n) { + case 'zh-cn': + state.disabledI18n = 'zh-cn'; + setI18nConfig('zh-cn'); + break; + case 'en': + state.disabledI18n = 'en'; + setI18nConfig('en'); + break; + case 'zh-tw': + state.disabledI18n = 'zh-tw'; + setI18nConfig('zh-tw'); + break; + } + }; + // 初始化全局组件大小 + const initComponentSize = () => { + switch (Local.get('themeConfig').globalComponentSize) { + case 'large': + state.disabledSize = 'large'; + break; + case 'default': + state.disabledSize = 'default'; + break; + case 'small': + state.disabledSize = 'small'; + break; + } + }; + // 页面加载时 + onMounted(() => { + if (Local.get('themeConfig')) { + initI18n(); + initComponentSize(); + } + }); + return { + userInfos, + onLayoutSetingClick, + onHandleCommandClick, + onScreenfullClick, + onSearchClick, + onComponentSizeChange, + onLanguageChange, + searchRef, + layoutUserFlexNum, + ...toRefs(state) + }; + } }); </script> <style scoped lang="scss"> .layout-navbars-breadcrumb-user { - display: flex; - align-items: center; - justify-content: flex-end; - &-link { - height: 100%; - display: flex; - align-items: center; - white-space: nowrap; - &-photo { - width: 25px; - height: 25px; - border-radius: 100%; - } - } - &-icon { - padding: 0 10px; - cursor: pointer; - color: var(--next-bg-topBarColor); - height: 50px; - line-height: 50px; - display: flex; - align-items: center; - &:hover { - background: var(--next-color-user-hover); - i { - display: inline-block; - animation: logoAnimation 0.3s ease-in-out; - } - } - } - ::v-deep(.el-dropdown) { - color: var(--next-bg-topBarColor); - } - ::v-deep(.el-badge) { - height: 40px; - line-height: 40px; - display: flex; - align-items: center; - } - ::v-deep(.el-badge__content.is-fixed) { - top: 12px; - } + display: flex; + align-items: center; + justify-content: flex-end; + &-link { + height: 100%; + display: flex; + align-items: center; + white-space: nowrap; + &-photo { + width: 25px; + height: 25px; + border-radius: 100%; + } + } + &-icon { + padding: 0 10px; + cursor: pointer; + color: var(--next-bg-topBarColor); + height: 50px; + line-height: 50px; + display: flex; + align-items: center; + &:hover { + background: var(--next-color-user-hover); + i { + display: inline-block; + animation: logoAnimation 0.3s ease-in-out; + } + } + } + ::v-deep(.el-dropdown) { + color: var(--next-bg-topBarColor); + } + ::v-deep(.el-badge) { + height: 40px; + line-height: 40px; + display: flex; + align-items: center; + } + ::v-deep(.el-badge__content.is-fixed) { + top: 12px; + } } </style> diff --git a/src/router/backEnd.ts b/src/router/backEnd.ts index c109d30..cf08c07 100644 --- a/src/router/backEnd.ts +++ b/src/router/backEnd.ts @@ -30,7 +30,7 @@ if (window.nextLoading === undefined) NextLoading.start(); if (!Session.get('token')) return false; const res = await getBackEndControlRoutes(Session.get('projectId') === null ? '' : Session.get('projectId')); - useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data.data))); + await useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data.data))); dynamicRoutes[0].children = await backEndComponent(res.data.data); await setAddRoute(); await setFilterMenuAndCacheTagsViewRoutes(); diff --git a/src/router/index.ts b/src/router/index.ts index 112fa0f..5fe7e90 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -10,9 +10,7 @@ import { staticRoutes } from '/@/router/route'; import { initFrontEndControlRoutes } from '/@/router/frontEnd'; import { initBackEndControlRoutes } from '/@/router/backEnd'; -import {useUserInfo} from "/@/stores/userInfo"; - - +import { useUserInfo } from '/@/stores/userInfo'; // 读取 `/src/stores/themeConfig.ts` 是否开启后端控制路由配置 const storesThemeConfig = useThemeConfig(pinia); @@ -20,89 +18,86 @@ const { isRequestRoutes } = themeConfig.value; if (isRequestRoutes) staticRoutes.splice(0, 1); - export const router = createRouter({ - history: createWebHashHistory(), - routes: staticRoutes, + history: createWebHashHistory(), + routes: staticRoutes }); - export function formatFlatteningRoutes(arr: any) { - if (arr.length <= 0) return false; - for (let i = 0; i < arr.length; i++) { - if (arr[i].children) { - arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1)); - } - } - return arr; + if (arr.length <= 0) return false; + for (let i = 0; i < arr.length; i++) { + if (arr[i].children) { + arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1)); + } + } + return arr; } - export function formatTwoStageRoutes(arr: any) { - if (arr.length <= 0) return false; - const newArr: any = []; - const cacheList: Array<string> = []; - arr.forEach((v: any) => { - if (v.path === '/') { - newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] }); - } else { - // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用 - // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G - if (v.path.indexOf('/:') > -1) { - v.meta['isDynamic'] = true; - v.meta['isDynamicPath'] = v.path; - } - newArr[0].children.push({ ...v }); - // 存 name 值,keep-alive 中 include 使用,实现路由的缓存 - // 路径:/@/layout/routerView/parent.vue - if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) { - cacheList.push(v.name); - const stores = useKeepALiveNames(pinia); - stores.setCacheKeepAlive(cacheList); - } - } - }); - return newArr; + if (arr.length <= 0) return false; + const newArr: any = []; + const cacheList: Array<string> = []; + arr.forEach((v: any) => { + if (v.path === '/') { + newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] }); + } else { + // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用 + // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G + if (v.path.indexOf('/:') > -1) { + v.meta['isDynamic'] = true; + v.meta['isDynamicPath'] = v.path; + } + newArr[0].children.push({ ...v }); + // 存 name 值,keep-alive 中 include 使用,实现路由的缓存 + // 路径:/@/layout/routerView/parent.vue + if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) { + cacheList.push(v.name); + const stores = useKeepALiveNames(pinia); + stores.setCacheKeepAlive(cacheList); + } + } + }); + return newArr; } -// isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts` -if (!isRequestRoutes) initFrontEndControlRoutes(); +// // isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts` +// if (!isRequestRoutes) initFrontEndControlRoutes(); // 路由加载前 router.beforeEach(async (to, from, next) => { - NProgress.configure({ showSpinner: false }); - if (to.meta.title) NProgress.start(); - const token = Session.get('token'); - if (to.path === '/login' && !token) { - next(); - NProgress.done(); - } else { - if (!token) { - next(`/login?redirect=${to.path}¶ms=${JSON.stringify(to.query ? to.query : to.params)}`); - Session.clear(); - NProgress.done(); - } else if (token && to.path === '/login') { - next('/home'); - NProgress.done(); - } else { - const storesRoutesList = useRoutesList(pinia); - const { routesList } = storeToRefs(storesRoutesList); - if (routesList.value.length === 0) { - // 后端控制路由:路由数据初始化,防止刷新时丢失 - await initBackEndControlRoutes(); - // 动态添加路由:防止非首页刷新时跳转回首页的问题 - // 确保 addRoute() 时动态添加的路由已经被完全加载上去 - next({ ...to, replace: true }); - } else { - next(); - } - } - } + NProgress.configure({ showSpinner: false }); + if (to.meta.title) NProgress.start(); + const token = Session.get('token'); + if (to.path === '/login' && !token) { + next(); + NProgress.done(); + } else { + if (!token) { + next(`/login?redirect=${to.path}¶ms=${JSON.stringify(to.query ? to.query : to.params)}`); + Session.clear(); + NProgress.done(); + } else if (token && to.path === '/login') { + next('/homeMenu'); + NProgress.done(); + } else { + const storesRoutesList = useRoutesList(pinia); + const { routesList } = storeToRefs(storesRoutesList); + if (routesList.value.length === 0) { + // 后端控制路由:路由数据初始化,防止刷新时丢失 + await initBackEndControlRoutes(); + // 动态添加路由:防止非首页刷新时跳转回首页的问题 + // 确保 addRoute() 时动态添加的路由已经被完全加载上去 + next({ ...to, replace: true }); + } else { + next(); + } + } + } }); // 路由加载后 router.afterEach(() => { - NProgress.done(); + NProgress.done(); }); // 导出路由 diff --git a/src/utils/request.ts b/src/utils/request.ts index c1b68b5..f8844cb 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -44,10 +44,16 @@ service.interceptors.response.use( (response) => { // 对响应数据做点什么 - if (response.data.code && (response.data.code === 'A0215' || response.data.code === 'A0214' || response.data.code === 'A0213')) { + if (response.data.code && response.data.code === 'A0213') { + ElMessage.error('用户uid不存在'); + setTimeout(() => { + Session.clear(); + window.location.href = '/'; + }, 2000); + } else if (response.data.code && response.data.code === 'A0215') { + ElMessage.error('token失效'); Session.clear(); window.location.href = '/'; - return Promise.reject(response); } // if(response.data.code && response.data.code !== '200'){ return Promise.resolve(response); diff --git a/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue b/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue index 5fa3450..fc3be6a 100644 --- a/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue +++ b/src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue @@ -23,7 +23,7 @@ <el-form-item label="所属部门" prop="depId"> <el-cascader :options="departmentList" - :props="{ emitPath: false, checkStrictly: true, value: 'id', label: 'name' }" + :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }" placeholder="请选择部门" clearable filterable diff --git a/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue b/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue index 71b95a8..85ea901 100644 --- a/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue +++ b/src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue @@ -194,7 +194,6 @@ }; const changeClassifyTwoList = () => { - debugger; state.riskControlMeasureForm.classify2 = null; state.classifyTwoList = []; state.classifyTwoList = state.classifyTwoListAll.filter((item: any) => item.parentId === state.riskControlMeasureForm.classify1); diff --git a/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue b/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue index 117e9b5..9437517 100644 --- a/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue +++ b/src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue @@ -49,7 +49,7 @@ <el-cascader @change="achieveUserList" :options="departmentList" - :props="{ emitPath: false, checkStrictly: true, value: 'id', label: 'name' }" + :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }" placeholder="请选择部门" clearable filterable diff --git a/src/views/homeMenu/homeMenu.vue b/src/views/homeMenu/homeMenu.vue index c16e22d..0e7d3d1 100644 --- a/src/views/homeMenu/homeMenu.vue +++ b/src/views/homeMenu/homeMenu.vue @@ -1,53 +1,91 @@ <template> - <div class="login-container"> - <div class="topPanel"> - <div class="topPanelCont"> - <div class="topTit"> - <div>新疆国泰新华</div> - <span></span> - <div>安全风险预警监测系统</div> - </div> - <div class="userInfo"> - <div class="avator"> - <img src="../../assets/menu/admin.png"> - <div>admin</div> - </div> - <span></span> - <div class="loginOut" @click="onLoginOut">退出登录</div> - </div> - </div> - </div> + <div class="login-container"> + <div class="topPanel"> + <div class="topPanelCont"> + <div class="topTit"> + <div>新疆国泰新华</div> + <span></span> + <div>安全风险预警监测系统</div> + </div> + <div class="userInfo"> + <div class="avator"> + <img src="../../assets/menu/admin.png" /> + <div>admin</div> + </div> + <span></span> + <div class="loginOut" @click="onLoginOut">退出登录</div> + </div> + </div> + </div> - <div class="menuGrid"> - <div class="gridCont"> - <el-row :gutter="20"> - <el-col :span="6"><div class="grid-content" @click="renderMenu('2')"><div class="itemTit">双重预防系统</div><img class="iconImg" src="../../assets/menu/icon4.png"><img class="bgImg" src="../../assets/menu/card4.png"></div></el-col> - <el-col :span="6"><div class="grid-content" @click="renderMenu('3')"><div class="itemTit">特殊作业系统</div><img class="iconImg" src="../../assets/menu/icon7.png"><img class="bgImg" src="../../assets/menu/card7.png"></div></el-col> - <el-col :span="6"><div class="grid-content" @click="renderMenu('4')"><div class="itemTit">智能巡检系统</div><img class="iconImg" src="../../assets/menu/icon8.png"><img class="bgImg" src="../../assets/menu/card8.png"></div></el-col> - <el-col :span="6"> - <div class="grid-content" @click="renderMenu('5')"> - <div class="itemTit">安全风险综合 - <br>预警预报平台 - </div> - <img class="iconImg" src="../../assets/menu/icon1.png"> - <img class="bgImg" src="../../assets/menu/card1.png"> - </div> - </el-col> - </el-row> - <el-row :gutter="20"> - <el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('6')"><div class="itemTit">应急管理系统</div><img class="iconImg" src="../../assets/menu/icon5.png"><img class="bgImg" src="../../assets/menu/card5.png"></div></el-col> - <el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('7')"><div class="itemTit">目标责任管理系统</div><img class="iconImg" src="../../assets/menu/icon2.png"><img class="bgImg" src="../../assets/menu/card2.png"></div></el-col> - <el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('8')"><div class="itemTit">事故管理系统</div><img class="iconImg" src="../../assets/menu/icon6.png"><img class="bgImg" src="../../assets/menu/card6.png"></div></el-col> - <el-col :span="6"><div class="grid-content grid-content-2" @click="renderMenu('9')"><div class="itemTit">设备综合管控系统</div><img class="iconImg" src="../../assets/menu/icon9.png"><img class="bgImg" src="../../assets/menu/card9.png"></div></el-col> - </el-row> - <el-row :gutter="20"> - <el-col :span="6"><div class="grid-content grid-content-3" @click="renderMenu('10')"><div class="itemTit">安全知识图谱系统</div><img class="iconImg" src="../../assets/menu/icon3.png"><img class="bgImg" src="../../assets/menu/card3.png"></div></el-col> - <el-col :span="9"><div class="grid-content grid-content-3" @click="renderMenu('11')"><div class="itemTit">危险化学品全生命周期安全<br>管理系统</div><img class="iconImg" src="../../assets/menu/icon10.png"><img class="bgImg" src="../../assets/menu/card10.png"></div></el-col> - <el-col :span="9"><div class="grid-content grid-content-3" @click="renderMenu('1')"><div class="itemTit">基础数据权限管理系统</div><img class="iconImg" src="../../assets/menu/icon11.png"><img class="bgImg" src="../../assets/menu/card11.png"></div></el-col> - </el-row> - </div> - </div> - </div> + <div class="menuGrid"> + <div class="gridCont"> + <el-row :gutter="20"> + <el-col :span="6" + ><div class="grid-content" v-throttle @click="renderMenu('2')"> + <div class="itemTit">双重预防系统</div> + <img class="iconImg" src="../../assets/menu/icon4.png" /><img class="bgImg" src="../../assets/menu/card4.png" /></div + ></el-col> + <el-col :span="6" + ><div class="grid-content" v-throttle @click="renderMenu('3')"> + <div class="itemTit">特殊作业系统</div> + <img class="iconImg" src="../../assets/menu/icon7.png" /><img class="bgImg" src="../../assets/menu/card7.png" /></div + ></el-col> + <el-col :span="6" + ><div class="grid-content" v-throttle @click="renderMenu('4')"> + <div class="itemTit">智能巡检系统</div> + <img class="iconImg" src="../../assets/menu/icon8.png" /><img class="bgImg" src="../../assets/menu/card8.png" /></div + ></el-col> + <el-col :span="6"> + <div class="grid-content" v-throttle @click="renderMenu('5')"> + <div class="itemTit">安全风险综合 <br />预警预报平台</div> + <img class="iconImg" src="../../assets/menu/icon1.png" /> + <img class="bgImg" src="../../assets/menu/card1.png" /> + </div> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="6" + ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('6')"> + <div class="itemTit">应急管理系统</div> + <img class="iconImg" src="../../assets/menu/icon5.png" /><img class="bgImg" src="../../assets/menu/card5.png" /></div + ></el-col> + <el-col :span="6" + ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('7')"> + <div class="itemTit">目标责任管理系统</div> + <img class="iconImg" src="../../assets/menu/icon2.png" /><img class="bgImg" src="../../assets/menu/card2.png" /></div + ></el-col> + <el-col :span="6" + ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('8')"> + <div class="itemTit">事故管理系统</div> + <img class="iconImg" src="../../assets/menu/icon6.png" /><img class="bgImg" src="../../assets/menu/card6.png" /></div + ></el-col> + <el-col :span="6" + ><div class="grid-content grid-content-2" v-throttle @click="renderMenu('9')"> + <div class="itemTit">设备综合管控系统</div> + <img class="iconImg" src="../../assets/menu/icon9.png" /><img class="bgImg" src="../../assets/menu/card9.png" /></div + ></el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="6" + ><div class="grid-content grid-content-3" v-throttle @click="renderMenu('10')"> + <div class="itemTit">安全知识图谱系统</div> + <img class="iconImg" src="../../assets/menu/icon3.png" /><img class="bgImg" src="../../assets/menu/card3.png" /></div + ></el-col> + <el-col :span="9" + ><div class="grid-content grid-content-3" v-throttle @click="renderMenu('11')"> + <div class="itemTit">危险化学品全生命周期安全<br />管理系统</div> + <img class="iconImg" src="../../assets/menu/icon10.png" /><img class="bgImg" src="../../assets/menu/card10.png" /></div + ></el-col> + <el-col :span="9" + ><div class="grid-content grid-content-3" v-throttle @click="renderMenu('1')"> + <div class="itemTit">基础数据权限管理系统</div> + <img class="iconImg" src="../../assets/menu/icon11.png" /><img class="bgImg" src="../../assets/menu/card11.png" /></div + ></el-col> + </el-row> + </div> + </div> + </div> </template> <script lang="ts"> @@ -57,220 +95,281 @@ import logoMini from '/@/assets/logo-mini.svg'; import loginIconTwo from '/@/assets/login-icon-two.svg'; import { NextLoading } from '/@/utils/loading'; -import {Session} from "/@/utils/storage"; -import {useRoute, useRouter} from "vue-router"; -import {initBackEndControlRoutes} from "/@/router/backEnd"; -import {useUserInfo} from "/@/stores/userInfo"; +import { Session } from '/@/utils/storage'; +import { useRoute, useRouter } from 'vue-router'; +import { initBackEndControlRoutes } from '/@/router/backEnd'; +import { useUserInfo } from '/@/stores/userInfo'; +import { useRoutesList } from '/@/stores/routesList'; +import pinia from '/@/stores'; +import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'; +import { ElMessage } from 'element-plus'; +import { ElMessageBox } from 'element-plus/es'; +import { useLoginApi } from '/@/api/login'; +import { useI18n } from 'vue-i18n'; // 定义接口来定义对象的类型 interface LoginState { - tabsActiveName: string; - isScan: boolean; + tabsActiveName: string; + isScan: boolean; } export default defineComponent({ - name: 'loginIndex', - components: {}, - setup() { - const route = useRoute(); - const router = useRouter(); - const userInfo = useUserInfo() - const { userInfos } = storeToRefs(userInfo); - const storesThemeConfig = useThemeConfig(); - const { themeConfig } = storeToRefs(storesThemeConfig); - const state = reactive<LoginState>({ - tabsActiveName: 'account', - isScan: false, - }); - // 获取布局配置信息 - const getThemeConfig = computed(() => { - return themeConfig.value; - }); - // 下拉菜单点击时 - const onLoginOut = () => { - console.log('退出登录') - }; - const renderMenu = async (value: string) => { - Session.set('projectId',value) - userInfos.value.projectId = value - await initBackEndControlRoutes(); - router.push('/home') - }; - // //点击进入特殊作业 - // const toSpecialWorkSys = () => { - // router.push('/layoutPage'); - // }; - // 页面加载时 - onMounted(() => { - NextLoading.done(); - // loginBg(); - // loginApp() - }); - return { - logoMini, - loginIconTwo, - getThemeConfig, - renderMenu, - ...toRefs(state), - }; - }, + name: 'loginIndex', + components: {}, + setup() { + const { t } = useI18n(); + const route = useRoute(); + const router = useRouter(); + const userInfo = useUserInfo(); + const { userInfos } = storeToRefs(userInfo); + const routeToStore = useRoutesList(pinia); + const { routesList } = storeToRefs(routeToStore); + const storesThemeConfig = useThemeConfig(); + const { themeConfig } = storeToRefs(storesThemeConfig); + const state = reactive<LoginState>({ + tabsActiveName: 'account', + isScan: false + }); + // 获取布局配置信息 + const getThemeConfig = computed(() => { + return themeConfig.value; + }); + // 下拉菜单点击时 + const onLoginOut = () => { + ElMessageBox({ + closeOnClickModal: false, + closeOnPressEscape: false, + title: t('message.user.logOutTitle'), + message: t('message.user.logOutMessage'), + showCancelButton: true, + confirmButtonText: t('message.user.logOutConfirm'), + cancelButtonText: t('message.user.logOutCancel'), + buttonSize: 'default', + beforeClose: (action, instance, done) => { + if (action === 'confirm') { + instance.confirmButtonLoading = true; + instance.confirmButtonText = t('message.user.logOutExit'); + setTimeout(() => { + done(); + setTimeout(() => { + instance.confirmButtonLoading = false; + }, 300); + }, 700); + } else { + done(); + } + } + }) + .then(async () => { + let res = await useLoginApi().signOut(); + if (res.data.code === '200') { + Session.clear(); // 清除缓存/token等 + // 使用 reload 时,不需要调用 resetRoute() 重置路由 + window.location.reload(); + } else { + ElMessage({ + type: 'warning', + message: res.data.msg + }); + } + }) + .catch(() => {}); + }; + const renderMenu = async (value: string) => { + Session.set('projectId', value); + userInfos.value.projectId = value; + await initBackEndControlRoutes().then(() => { + let linkToMenu = [...routesList.value]; + if (linkToMenu && linkToMenu.length > 1) { + router.push(linkToFirstMenu(JSON.parse(JSON.stringify(linkToMenu))[1])); + } else { + ElMessage({ type: 'warning', message: '你没有该项目的权限' }); + } + }); + }; + const linkToFirstMenu: any = (value: any) => { + let returnMenu = value; + if (returnMenu.children?.length > 0) { + return linkToFirstMenu(returnMenu.children[0]); + } else { + return returnMenu.path; + } + }; + // //点击进入特殊作业 + // const toSpecialWorkSys = () => { + // router.push('/layoutPage'); + // }; + // 页面加载时 + onMounted(() => { + NextLoading.done(); + // loginBg(); + // loginApp() + }); + return { + logoMini, + onLoginOut, + loginIconTwo, + getThemeConfig, + renderMenu, + ...toRefs(state) + }; + } }); </script> <style scoped lang="scss"> .login-container { - width: 100%; - height: 100%; - position: relative; - background: url("../../assets/menu/bg_home1.jpg") no-repeat center; - .topPanel{ - position: absolute; - width: 100%; - top: -100px; - left: 0; - height:100px; - background: #fff; - display: flex; - justify-content: center; - box-shadow: 0 8px 32px rgba(0,0,0,.1); - animation: showDown .6s 1 ease forwards; + width: 100%; + height: 100%; + position: relative; + background: url('../../assets/menu/bg_home1.jpg') no-repeat center; + .topPanel { + position: absolute; + width: 100%; + top: -100px; + left: 0; + height: 100px; + background: #fff; + display: flex; + justify-content: center; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + animation: showDown 0.6s 1 ease forwards; - @keyframes showDown { - 100%{ - position: absolute; - top: 0; - } - } - .topPanelCont{ - width: 1200px; - height: 100%; - display: flex; - align-items: center; - justify-content: space-between; + @keyframes showDown { + 100% { + position: absolute; + top: 0; + } + } + .topPanelCont { + width: 1200px; + height: 100%; + display: flex; + align-items: center; + justify-content: space-between; - .topTit{ - font-size: 24px; - font-weight: bold; - display: flex; - align-items: center; - color: #333; - line-height: 28px; + .topTit { + font-size: 24px; + font-weight: bold; + display: flex; + align-items: center; + color: #333; + line-height: 28px; - &>div:last-of-type{ - color: #006DF5; - } + & > div:last-of-type { + color: #006df5; + } - span{ - width: 1px; - height: 28px; - background: #999; - margin: 0 15px; - } - } + span { + width: 1px; + height: 28px; + background: #999; + margin: 0 15px; + } + } - .userInfo{ - display: flex; - align-items: center; + .userInfo { + display: flex; + align-items: center; - .avator{ - display: flex; - justify-content: right; + .avator { + display: flex; + justify-content: right; - img{ - width: 20px; - height: 20px; - border-radius: 10px; - } - div{ - font-size: 15px; - color: #333333; - line-height: 20px; - margin-left: 6px; - } - } - span{ - width: 1px; - height: 20px; - background: #999; - margin: 0 15px; - } - .loginOut{ - font-size: 15px; - color: #333; - line-height: 20px; - cursor: pointer; + img { + width: 20px; + height: 20px; + border-radius: 10px; + } + div { + font-size: 15px; + color: #333333; + line-height: 20px; + margin-left: 6px; + } + } + span { + width: 1px; + height: 20px; + background: #999; + margin: 0 15px; + } + .loginOut { + font-size: 15px; + color: #333; + line-height: 20px; + cursor: pointer; - &:hover{ - color: #006DF5; - } - } - } - } - } + &:hover { + color: #006df5; + } + } + } + } + } - .menuGrid{ - width: 100%; - position: absolute; - top: 150px; - display: flex; - justify-content: center; - .gridCont{ - width: 1200px; - .el-row { - margin-bottom: 20px; - } - .el-row:last-child { - margin-bottom: 0; - } - .el-col { - border-radius: 8px; - } + .menuGrid { + width: 100%; + position: absolute; + top: 150px; + display: flex; + justify-content: center; + .gridCont { + width: 1200px; + .el-row { + margin-bottom: 20px; + } + .el-row:last-child { + margin-bottom: 0; + } + .el-col { + border-radius: 8px; + } - .grid-content { - border-radius: 10px; - height: 234px; - padding: 32px; - position: relative; - background-image: linear-gradient(135deg,#00C0F5,#44b1ff); - overflow: hidden; - cursor: pointer; - transition: .3s; - border: none; + .grid-content { + border-radius: 10px; + height: 234px; + padding: 32px; + position: relative; + background-image: linear-gradient(135deg, #00c0f5, #44b1ff); + overflow: hidden; + cursor: pointer; + transition: 0.3s; + border: none; - &:hover{ - box-shadow: 0 8px 32px rgba(20,97,234,.4); - } + &:hover { + box-shadow: 0 8px 32px rgba(20, 97, 234, 0.4); + } - .itemTit{ - font-size: 24px; - line-height: 36px; - height: 40%; - font-family: "PingFang SC"; - font-weight: lighter; - color: #fff; - margin-bottom: 25px; - } - .iconImg{ - width: 80px; - height: 80px; - } + .itemTit { + font-size: 24px; + line-height: 36px; + height: 40%; + font-family: 'PingFang SC'; + font-weight: lighter; + color: #fff; + margin-bottom: 25px; + } + .iconImg { + width: 80px; + height: 80px; + } - .bgImg{ - position: absolute; - right: 0; - bottom: 0; - } - } + .bgImg { + position: absolute; + right: 0; + bottom: 0; + } + } - /*.grid-content-2{*/ - /* background-image: linear-gradient(135deg,#0098F5,#1461EA);*/ - /*}*/ + /*.grid-content-2{*/ + /* background-image: linear-gradient(135deg,#0098F5,#1461EA);*/ + /*}*/ - /*.grid-content-3{*/ - /* background-image: linear-gradient(135deg,#006DF5,#1450EA);*/ - /*}*/ - } - - } + /*.grid-content-3{*/ + /* background-image: linear-gradient(135deg,#006DF5,#1450EA);*/ + /*}*/ + } + } } </style> diff --git a/src/views/loginPage/component/accountLogin.vue b/src/views/loginPage/component/accountLogin.vue index 60dca23..2508742 100644 --- a/src/views/loginPage/component/accountLogin.vue +++ b/src/views/loginPage/component/accountLogin.vue @@ -14,6 +14,7 @@ v-model="ruleForm.password" autocomplete="off" size="large" + @keyup.enter.native="onSignIn" > <template #prefix> <el-icon class="el-input__icon" style="margin-right: 20px"><img src="../../../assets/loginPage/login_icon_password.png" style="width: 24px;height: 24px"></el-icon> diff --git a/src/views/system/department/component/deptDialog.vue b/src/views/system/department/component/deptDialog.vue index b1df6b5..e3757f2 100644 --- a/src/views/system/department/component/deptDialog.vue +++ b/src/views/system/department/component/deptDialog.vue @@ -7,23 +7,23 @@ <el-form-item label="上级部门"> <el-cascader :options="deptData" - :props="{ checkStrictly: true, value: 'id', label: 'name' }" + :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }" placeholder="请选择部门" clearable class="w100" - v-model="departmentForm.struct" + v-model="departmentForm.parentDepId" > </el-cascader> </el-form-item> </el-col> <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20"> <el-form-item label="部门名称"> - <el-input v-model="departmentForm.name" placeholder="请输入部门名称" clearable></el-input> + <el-input v-model="departmentForm.depName" placeholder="请输入部门名称" clearable></el-input> </el-form-item> </el-col> <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20"> <el-form-item label="部门描述"> - <el-input v-model="departmentForm.info" type="textarea" placeholder="请输入部门描述" maxlength="150"></el-input> + <el-input v-model="departmentForm.depInfo" type="textarea" placeholder="请输入部门描述" maxlength="150"></el-input> </el-form-item> </el-col> </el-row> @@ -31,7 +31,7 @@ <template #footer> <span class="dialog-footer"> <el-button @click="onCancel" size="default">取 消</el-button> - <el-button type="primary" @click="onSubmit" size="default">新 增</el-button> + <el-button type="primary" @click="onSubmit" size="default">确 定</el-button> </span> </template> </el-dialog> @@ -45,7 +45,6 @@ // 定义接口来定义对象的类型 interface TableDataRow { - struct: Array<string>; name:string, info:string, parentId:string, @@ -55,10 +54,9 @@ title:string; isShowDialog: boolean; departmentForm: { - struct: Array<string>; - name:string, - info:string, - parentId:string + depName:string, + depInfo:string, + parentDepId:string }; deptData: Array<TableDataRow>; } @@ -70,10 +68,9 @@ title:'', isShowDialog: false, departmentForm: { - name:'', - parentId:'', - info:'', - struct:[] + depName:'', + parentDepId:'', + depInfo:'', }, deptData: [], // 部门数据 }); @@ -84,10 +81,9 @@ if(type === '新增'){ state.title = '新增部门' state.departmentForm = { - name:'', - parentId:'', - info:'', - struct:[] + depName:'', + parentDepId:'', + depInfo:'', } }else{ state.title = '修改部门' @@ -104,10 +100,6 @@ }; // 新增 const onSubmit = async () => { - if(state.departmentForm.struct && state.departmentForm.struct !== []){ - let departmentId = JSON.parse(JSON.stringify(state.departmentForm.struct)) - state.departmentForm.parentId = departmentId[departmentId.length - 1] - } if(state.title === '新增部门'){ let res = await departmentApi().addDepartment(state.departmentForm) if(res.data.code === '200'){ diff --git a/src/views/system/department/index.vue b/src/views/system/department/index.vue index ca69129..28464ce 100644 --- a/src/views/system/department/index.vue +++ b/src/views/system/department/index.vue @@ -19,11 +19,11 @@ <el-table :data="tableData.data" style="width: 100%" - row-key="id" + row-key="depId" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" > - <el-table-column prop="name" label="部门名称" show-overflow-tooltip> </el-table-column> - <el-table-column prop="info" label="部门描述" show-overflow-tooltip></el-table-column> + <el-table-column prop="depName" label="部门名称" show-overflow-tooltip> </el-table-column> + <el-table-column prop="depInfo" label="部门描述" show-overflow-tooltip></el-table-column> <el-table-column label="操作" show-overflow-tooltip width="140"> <template #default="scope"> <el-button size="small" text type="primary" @click="onOpenDeptDialog('新增','')">新增</el-button> @@ -42,6 +42,7 @@ import { ElMessageBox, ElMessage } from 'element-plus'; import deptDialog from '/@/views/system/department/component/deptDialog.vue'; import {departmentApi} from "/@/api/department"; +import {useRoleApi} from "/@/api/role"; // 定义接口来定义对象的类型 interface TableDataRow { @@ -49,7 +50,7 @@ status: boolean; parentId: number; info: string; - id: number; + depId: number; children?: TableDataRow[]; } interface TableDataState { @@ -91,13 +92,26 @@ }; // 删除当前行 const onTabelRowDel = (row: TableDataRow) => { - ElMessageBox.confirm(`此操作将永久删除部门:${row.id}, 是否继续?`, '提示', { + ElMessageBox.confirm(`此操作将永久删除部门:${row.depId}, 是否继续?`, '提示', { confirmButtonText: '删除', cancelButtonText: '取消', type: 'warning', - }).then(() => { - ElMessage.success('删除成功'); - }).catch(() => {}); + }).then(async () => { + let res = await departmentApi().deleteDepartment({depId:row.depId}) + if(res.data.code ==='200'){ + ElMessage({ + type:'success', + duration:2000, + message:'删除成功' + }) + await initTableData() + }else{ + ElMessage({ + type:'warning', + message:res.data.msg + }) + } + }).catch(() => {}); }; // 页面加载时 onMounted(() => { diff --git a/src/views/system/menu/component/menuDialog.vue b/src/views/system/menu/component/menuDialog.vue index c5bb3fd..f223f93 100644 --- a/src/views/system/menu/component/menuDialog.vue +++ b/src/views/system/menu/component/menuDialog.vue @@ -38,7 +38,7 @@ </el-col> <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20"> <el-form-item label="菜单图标"> - <input placeholder="请输入菜单图标" v-model="ruleForm.meta.icon" type="all" /> + <el-input placeholder="请输入菜单图标" v-model="ruleForm.meta.icon" type="all" /> <!-- <IconSelector placeholder="请输入菜单图标" v-model="ruleForm.meta.icon" type="all" />--> </el-form-item> </el-col> diff --git a/src/views/system/role/component/roleDialog.vue b/src/views/system/role/component/roleDialog.vue index 9470bf4..d3b7c04 100644 --- a/src/views/system/role/component/roleDialog.vue +++ b/src/views/system/role/component/roleDialog.vue @@ -5,17 +5,17 @@ <el-row :gutter="35"> <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20"> <el-form-item label="角色名称"> - <el-input v-model="roleForm.name" placeholder="请输入角色名称" clearable></el-input> + <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" clearable></el-input> </el-form-item> </el-col> <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20"> <el-form-item label="角色标识"> - <el-input v-model="roleForm.code" placeholder="请输入角色标识" clearable></el-input> + <el-input v-model="roleForm.roleCode" placeholder="请输入角色标识" clearable></el-input> </el-form-item> </el-col> <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20"> <el-form-item label="角色描述"> - <el-input v-model="roleForm.info" type="textarea" placeholder="请输入角色描述" maxlength="150"></el-input> + <el-input v-model="roleForm.roleInfo" type="textarea" placeholder="请输入角色描述" maxlength="150"></el-input> </el-form-item> </el-col> </el-row> @@ -33,7 +33,6 @@ <script lang="ts"> import { ElMessage } from 'element-plus'; import { reactive, toRefs, defineComponent } from 'vue'; -import {departmentApi} from "/@/api/department"; import {useRoleApi} from "/@/api/role"; // 定义接口来定义对象的类型 @@ -47,9 +46,9 @@ buttonName:string, isShowRoleDialog: boolean; roleForm: { - name: string; - code: string; - info: string; + roleName: string; + roleCode: string; + roleInfo: string; }; menuData: Array<MenuDataTree>; menuProps: { @@ -66,9 +65,9 @@ title:'', buttonName:'', roleForm: { - name: '', // 角色名称 - code: '', // 角色标识 - info: '', // 排序 + roleName: '', // 角色名称 + roleCode: '', // 角色标识 + roleInfo: '', // 排序 }, menuData: [], menuProps: { @@ -83,9 +82,9 @@ state.title = '新增角色' state.buttonName = '新增' state.roleForm = { - name:'', - code:'', - info:'', + roleName:'', + roleCode:'', + roleInfo:'', } }else{ state.title = '修改角色' diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index b05db16..93922e3 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -18,15 +18,15 @@ </div> <el-table :data="tableData.data" style="width: 100%"> <el-table-column type="index" label="序号" width="60" /> - <el-table-column prop="name" label="角色名称" show-overflow-tooltip></el-table-column> - <el-table-column prop="code" label="角色标识" show-overflow-tooltip></el-table-column> - <el-table-column prop="info" label="角色描述" show-overflow-tooltip></el-table-column> + <el-table-column prop="roleName" label="角色名称" show-overflow-tooltip></el-table-column> + <el-table-column prop="roleCode" label="角色标识" show-overflow-tooltip></el-table-column> + <el-table-column prop="roleInfo" label="角色描述" show-overflow-tooltip></el-table-column> <el-table-column prop="createTime" label="创建时间" show-overflow-tooltip></el-table-column> <el-table-column label="操作" width="150"> <template #default="scope"> <el-button size="small" text type="primary" @click="onOpenDialogRef('新增','')">新增</el-button> <el-button size="small" text type="primary" @click="onOpenDialogRef('修改',scope.row)">修改</el-button> - <el-button size="small" text type="primary" @click="onTabelRowDel(scope.row)">删除</el-button> + <el-button size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button> </template> </el-table-column> </el-table> @@ -40,10 +40,13 @@ import { ElMessageBox, ElMessage } from 'element-plus'; import roleDialog from '/@/views/system/role/component/roleDialog.vue'; import {useRoleApi} from "/@/api/role"; +import {useMenuApi} from "/@/api/menu"; +import {Session} from "/@/utils/storage"; +import {initBackEndControlRoutes} from "/@/router/backEnd"; // 定义接口来定义对象的类型 interface TableData { - roleName: string; + roleName: string; roleSign: string; describe: string; sort: number; @@ -100,9 +103,22 @@ confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', - }).then(() => { - ElMessage.success('删除成功'); - }).catch(() => {}); + }).then(async () => { + let res = await useRoleApi().deleteRole({roleId:row.roleId}) + if(res.data.code ==='200'){ + ElMessage({ + type:'success', + duration:2000, + message:'删除成功' + }) + await initRoleTableData() + }else{ + ElMessage({ + type:'warning', + message:res.data.msg + }) + } + }).catch(() => {}); }; const handleSearch = () => { initRoleTableData() -- Gitblit v1.9.2