| | |
| | | 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' |
| | |
| | | |
| | | export function departmentApi() { |
| | | return { |
| | | // v1 |
| | | // v2 |
| | | getDepartmentList: () => { |
| | | return request({ |
| | | url: `/department/list`, |
| | | method: 'post' |
| | | }); |
| | | }, |
| | | // v1 |
| | | // v2 |
| | | addDepartment: (data: object) => { |
| | | return request({ |
| | | url: `/department/add`, |
| | |
| | | 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 |
| | | }); |
| | | }, |
| | | }; |
| | | } |
| | |
| | | }); |
| | | }, |
| | | // v1 |
| | | signOut: (params: object) => { |
| | | signOut: () => { |
| | | return request({ |
| | | url: '/user/signOut', |
| | | method: 'post', |
| | | data: params |
| | | url: '/auth/logout', |
| | | method: 'post' |
| | | }); |
| | | } |
| | | }; |
| | |
| | | */ |
| | | export function useMenuApi() { |
| | | return { |
| | | // v1 |
| | | // v2 |
| | | getMenuAdmin: (value?: string) => { |
| | | return request({ |
| | | url: `/auth/menu?projectId= ${value}`, |
| | |
| | | |
| | | export function useRoleApi() { |
| | | return { |
| | | // v1 |
| | | // v2 |
| | | getRoleList: () => { |
| | | return request({ |
| | | url: `/role/list`, |
| | | method: 'post' |
| | | }); |
| | | }, |
| | | // v1 |
| | | // v2 |
| | | addRole: (data: object) => { |
| | | return request({ |
| | | url: `/role/add`, |
| | |
| | | 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 |
| | | }); |
| | | }, |
| | | }; |
| | | } |
| | |
| | | <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>--> |
| | |
| | | <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"> |
| | |
| | | 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> |
| | |
| | | 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(); |
| | |
| | | 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); |
| | |
| | | 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(); |
| | | }); |
| | | |
| | | // 导出路由 |
| | |
| | | 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); |
| | |
| | | <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 |
| | |
| | | }; |
| | | |
| | | const changeClassifyTwoList = () => { |
| | | debugger; |
| | | state.riskControlMeasureForm.classify2 = null; |
| | | state.classifyTwoList = []; |
| | | state.classifyTwoList = state.classifyTwoListAll.filter((item: any) => item.parentId === state.riskControlMeasureForm.classify1); |
| | |
| | | <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 |
| | |
| | | <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"> |
| | |
| | | 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> |
| | |
| | | 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> |
| | |
| | | <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> |
| | |
| | | <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> |
| | |
| | | |
| | | // 定义接口来定义对象的类型 |
| | | interface TableDataRow { |
| | | struct: Array<string>; |
| | | name:string, |
| | | info:string, |
| | | parentId:string, |
| | |
| | | title:string; |
| | | isShowDialog: boolean; |
| | | departmentForm: { |
| | | struct: Array<string>; |
| | | name:string, |
| | | info:string, |
| | | parentId:string |
| | | depName:string, |
| | | depInfo:string, |
| | | parentDepId:string |
| | | }; |
| | | deptData: Array<TableDataRow>; |
| | | } |
| | |
| | | title:'', |
| | | isShowDialog: false, |
| | | departmentForm: { |
| | | name:'', |
| | | parentId:'', |
| | | info:'', |
| | | struct:[] |
| | | depName:'', |
| | | parentDepId:'', |
| | | depInfo:'', |
| | | }, |
| | | deptData: [], // 部门数据 |
| | | }); |
| | |
| | | if(type === '新增'){ |
| | | state.title = '新增部门' |
| | | state.departmentForm = { |
| | | name:'', |
| | | parentId:'', |
| | | info:'', |
| | | struct:[] |
| | | depName:'', |
| | | parentDepId:'', |
| | | depInfo:'', |
| | | } |
| | | }else{ |
| | | state.title = '修改部门' |
| | |
| | | }; |
| | | // 新增 |
| | | 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'){ |
| | |
| | | <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> |
| | |
| | | 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 { |
| | |
| | | status: boolean; |
| | | parentId: number; |
| | | info: string; |
| | | id: number; |
| | | depId: number; |
| | | children?: TableDataRow[]; |
| | | } |
| | | interface TableDataState { |
| | |
| | | }; |
| | | // 删除当前行 |
| | | 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(() => { |
| | |
| | | </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> |
| | |
| | | <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> |
| | |
| | | <script lang="ts"> |
| | | import { ElMessage } from 'element-plus'; |
| | | import { reactive, toRefs, defineComponent } from 'vue'; |
| | | import {departmentApi} from "/@/api/department"; |
| | | import {useRoleApi} from "/@/api/role"; |
| | | |
| | | // 定义接口来定义对象的类型 |
| | |
| | | buttonName:string, |
| | | isShowRoleDialog: boolean; |
| | | roleForm: { |
| | | name: string; |
| | | code: string; |
| | | info: string; |
| | | roleName: string; |
| | | roleCode: string; |
| | | roleInfo: string; |
| | | }; |
| | | menuData: Array<MenuDataTree>; |
| | | menuProps: { |
| | |
| | | title:'', |
| | | buttonName:'', |
| | | roleForm: { |
| | | name: '', // 角色名称 |
| | | code: '', // 角色标识 |
| | | info: '', // 排序 |
| | | roleName: '', // 角色名称 |
| | | roleCode: '', // 角色标识 |
| | | roleInfo: '', // 排序 |
| | | }, |
| | | menuData: [], |
| | | menuProps: { |
| | |
| | | state.title = '新增角色' |
| | | state.buttonName = '新增' |
| | | state.roleForm = { |
| | | name:'', |
| | | code:'', |
| | | info:'', |
| | | roleName:'', |
| | | roleCode:'', |
| | | roleInfo:'', |
| | | } |
| | | }else{ |
| | | state.title = '修改角色' |
| | |
| | | </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> |
| | |
| | | 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; |
| | |
| | | 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() |