Your Name
2022-07-13 656696be4b70513e94f1341db8d1c2d3f43b3e6d
登录跳转首页
已修改20个文件
已删除1个文件
913 ■■■■■ 文件已修改
.env.development 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/inspectionProfiles/Project_Default.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/department/index.ts 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/menu/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/role/index.ts 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/iconSelector/index.vue 498 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/user.vue 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/backEnd.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.ts 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePreventSystem/riskLevelManage/productionDevice/components/productionDeviceDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePreventSystem/riskLevelManage/riskControlMeasure/components/riskControlMeasureDialog.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePreventSystem/riskLevelManage/safetyRiskAnalyseUnit/components/safetyRiskAnalyseUnitDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/homeMenu/homeMenu.vue 179 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/loginPage/component/accountLogin.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/department/component/deptDialog.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/department/index.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/menu/component/menuDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/component/roleDialog.vue 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/index.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.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'
.idea/inspectionProfiles/Project_Default.xml
文件已删除
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
            });
        },
    };
}
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'
            });
        }
    };
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}`,
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
            });
        },
    };
}
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>-->
src/layout/navBars/breadcrumb/user.vue
@@ -7,14 +7,20 @@
            <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="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>
                <i
                    class="iconfont"
                    :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'"
                    :title="$t('message.user.title1')"
                ></i>
            </div>
            <template #dropdown>
                <el-dropdown-menu>
@@ -63,11 +69,11 @@
            </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="/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 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>
@@ -89,6 +95,7 @@
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',
@@ -105,7 +112,7 @@
        const state = reactive({
            isScreenfull: false,
            disabledI18n: 'zh-cn',
            disabledSize: 'large',
            disabledSize: 'large'
        });
        // 设置分割样式
        const layoutUserFlexNum = computed(() => {
@@ -157,12 +164,20 @@
                        } 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') {
@@ -244,9 +259,9 @@
            onLanguageChange,
            searchRef,
            layoutUserFlexNum,
            ...toRefs(state),
            ...toRefs(state)
        };
    },
    }
});
</script>
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();
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,12 +18,10 @@
const { isRequestRoutes } = themeConfig.value;
if (isRequestRoutes) staticRoutes.splice(0, 1);
export const router = createRouter({
    history: createWebHashHistory(),
    routes: staticRoutes,
    routes: staticRoutes
});
export function formatFlatteningRoutes(arr: any) {
    if (arr.length <= 0) return false;
@@ -36,7 +32,6 @@
    }
    return arr;
}
export function formatTwoStageRoutes(arr: any) {
    if (arr.length <= 0) return false;
@@ -65,8 +60,8 @@
    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) => {
@@ -82,7 +77,7 @@
            Session.clear();
            NProgress.done();
        } else if (token && to.path === '/login') {
            next('/home');
            next('/homeMenu');
            NProgress.done();
        } else {
            const storesRoutesList = useRoutesList(pinia);
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 = '/';
            return Promise.reject(response);
            }, 2000);
        } else if (response.data.code && response.data.code === 'A0215') {
            ElMessage.error('token失效');
            Session.clear();
            window.location.href = '/';
        }
        // if(response.data.code && response.data.code !== '200'){
        return Promise.resolve(response);
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
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);
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
src/views/homeMenu/homeMenu.vue
@@ -9,7 +9,7 @@
                </div>
                <div class="userInfo">
                    <div class="avator">
                        <img src="../../assets/menu/admin.png">
                        <img src="../../assets/menu/admin.png" />
                        <div>admin</div>
                    </div>
                    <span></span>
@@ -21,29 +21,67 @@
        <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" 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" @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 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" @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-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" @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-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>
@@ -57,10 +95,17 @@
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 {
@@ -72,15 +117,18 @@
    name: 'loginIndex',
    components: {},
    setup() {
        const { t } = useI18n();
        const route = useRoute();
        const router = useRouter();
        const userInfo = useUserInfo()
        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,
            isScan: false
        });
        // 获取布局配置信息
        const getThemeConfig = computed(() => {
@@ -88,13 +136,64 @@
        });
        // 下拉菜单点击时
        const onLoginOut = () => {
            console.log('退出登录')
            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();
            router.push('/home')
            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 = () => {
@@ -108,12 +207,13 @@
        });
        return {
            logoMini,
            onLoginOut,
            loginIconTwo,
            getThemeConfig,
            renderMenu,
            ...toRefs(state),
            ...toRefs(state)
        };
    },
    }
});
</script>
@@ -122,7 +222,7 @@
    width: 100%;
    height: 100%;
    position: relative;
    background: url("../../assets/menu/bg_home1.jpg") no-repeat center;
    background: url('../../assets/menu/bg_home1.jpg') no-repeat center;
    .topPanel{
        position: absolute;
        width: 100%;
@@ -132,8 +232,8 @@
        background: #fff;
        display: flex;
        justify-content: center;
        box-shadow: 0 8px 32px rgba(0,0,0,.1);
        animation: showDown .6s 1 ease forwards;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
        animation: showDown 0.6s 1 ease forwards;
        @keyframes showDown {
            100%{
@@ -157,7 +257,7 @@
                line-height: 28px;
                &>div:last-of-type{
                    color: #006DF5;
                    color: #006df5;
                }
                span{
@@ -201,7 +301,7 @@
                    cursor: pointer;
                    &:hover{
                        color: #006DF5;
                        color: #006df5;
                    }
                }
            }
@@ -231,21 +331,21 @@
                height: 234px;
                padding: 32px;
                position: relative;
                background-image: linear-gradient(135deg,#00C0F5,#44b1ff);
                background-image: linear-gradient(135deg, #00c0f5, #44b1ff);
                overflow: hidden;
                cursor: pointer;
                transition: .3s;
                transition: 0.3s;
                border: none;
                &:hover{
                    box-shadow: 0 8px 32px rgba(20,97,234,.4);
                    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-family: 'PingFang SC';
                    font-weight: lighter;
                    color: #fff;
                    margin-bottom: 25px;
@@ -270,7 +370,6 @@
            /*    background-image: linear-gradient(135deg,#006DF5,#1450EA);*/
            /*}*/
        }
    }
}
</style>
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>
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'){
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,12 +92,25 @@
        };
        // 删除当前行
        const onTabelRowDel = (row: TableDataRow) => {
            ElMessageBox.confirm(`此操作将永久删除部门:${row.id}, 是否继续?`, '提示', {
            ElMessageBox.confirm(`此操作将永久删除部门:${row.depId}, 是否继续?`, '提示', {
                confirmButtonText: '删除',
                cancelButtonText: '取消',
                type: 'warning',
            }).then(() => {
                    ElMessage.success('删除成功');
            }).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(() => {});
        };
        // 页面加载时
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>
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 = '修改角色'
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,6 +40,9 @@
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 {
@@ -100,8 +103,21 @@
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning',
            }).then(() => {
                    ElMessage.success('删除成功');
            }).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 = () => {