ZaiZai hai 1 ano
pai
achega
b016de4887

+ 6 - 0
src/api/modules/other.js

@@ -56,3 +56,9 @@ export const getContractInfo = (form, msg = true) => HcApi({
     method: 'get',
     params: form,
 }, msg)
+
+//获取图标文件
+export const getRemixicon = () => HcApi({
+    url: 'plugins/remixicon/remixicon.css?time=' + new Date().getTime(),
+    method: 'get',
+}, false)

+ 0 - 64
src/api/request/avue.js

@@ -1,64 +0,0 @@
-//Avue的请求封装
-import axios from 'axios'
-import { Base64 } from 'js-base64'
-import website from '~src/config/index'
-import { getToken } from '~src/api/auth'
-import { toSerialize } from 'js-fast-way'
-import router from '~src/router/index'
-
-//默认超时时间
-axios.defaults.timeout = 0
-//返回其他状态码
-axios.defaults.validateStatus = function (status) {
-    return status >= 200 && status <= 500
-}
-//跨域请求,允许保存cookie
-axios.defaults.withCredentials = true
-
-//http request拦截
-axios.interceptors.request.use(config => {
-    const meta = (config['meta'] || {})
-    const isToken = meta['isToken'] === false
-    config.headers['Authorization'] = `Basic ${Base64.encode(`${website?.clientId}:${website?.clientSecret}`)}`
-    //让每个请求携带token
-    const token = getToken()
-    if (token && !isToken) {
-        config.headers[website?.tokenHeader] = 'bearer ' + token
-    }
-    //headers中配置text请求
-    if (config['text'] === true) {
-        config.headers['Content-Type'] = 'text/plain'
-    }
-    //headers中配置serialize为true开启序列化
-    if (config.method === 'post' && meta['isSerialize'] === true) {
-        config.data = toSerialize(config.data)
-    }
-    config.metadata = { startTime: new Date() }
-    return config
-}, error => {
-    return Promise.reject(error)
-})
-
-//http response 拦截
-axios.interceptors.response.use(res => {
-    //响应时间
-    res.config.metadata.endTime = new Date()
-    //获取状态码
-    const status = res.data.code || res.status;
-    const message = res.data.msg || res.data.error_description || '未知错误';
-    //如果是401则跳转到登录页面
-    if (status === 401) {
-        window.$message?.error('身份失效,请重新登录!')
-        router.push({ path: '/login' }).then()
-    }
-    // 如果请求为非200否者默认统一处理
-    if (status !== 200) {
-        window.$message?.error(message)
-        return Promise.reject(new Error(message))
-    }
-    return res;
-}, error => {
-    return Promise.reject(new Error(error))
-})
-
-export default axios

+ 2 - 0
src/components/index.js

@@ -1,5 +1,6 @@
 import { vAuthBtn } from './auth-btn/index'
 import HcCharts from './echarts/echarts.vue'
+import HcMenuIcon from './menu-icon/menu-icon.vue'
 import HcSearchInput from './search-input/search-input.vue'
 
 //注册全局组件
@@ -8,5 +9,6 @@ export const setupComponents = (App) => {
     App.directive('auth-btn', vAuthBtn)
     //自定义组件
     App.component('HcCharts', HcCharts)
+    App.component('HcMenuIcon', HcMenuIcon)
     App.component('HcSearchInput', HcSearchInput)
 }

+ 101 - 0
src/components/menu-icon/menu-icon.vue

@@ -0,0 +1,101 @@
+<template>
+    <hc-new-dialog v-model="isShow" is-table :footer="false" widths="1200px" title="图标选择" @close="menuIconClose">
+        <el-scrollbar class="hc-menu-icon-box">
+            <div class="hc-menu-icon">
+                <el-row :gutter="10">
+                    <el-col v-for="item in icons" :key="item" :span="4">
+                        <div class="icon-item" @click="iconClick(item)">
+                            <div class="icon">
+                                <hc-icon :name="item" />
+                            </div>
+                            <div class="name">{{ item }}</div>
+                        </div>
+                    </el-col>
+                </el-row>
+            </div>
+        </el-scrollbar>
+    </hc-new-dialog>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue'
+import { getRemixicon } from '~api/other'
+
+//事件
+const emit = defineEmits(['finish', 'close'])
+
+defineOptions({
+    name: 'HcMenuIcon',
+})
+
+//双向绑定
+// eslint-disable-next-line no-undef
+const isShow = defineModel('modelValue', {
+    default: false,
+})
+
+//渲染完成
+onMounted(() => {
+    initIcon()
+})
+
+//初始化图标
+const icons = ref([])
+const initIcon = async () => {
+    const { res } = await getRemixicon()
+    const regex = /ri-(.*?)-line/g
+    let matches = [], match
+    while ((match = regex.exec(res))) {
+        matches.push(match[1])
+    }
+    icons.value = matches
+}
+
+//点击图标
+const iconClick = (item) => {
+    emit('finish', item)
+}
+
+//关闭
+const menuIconClose = () => {
+    isShow.value = false
+    emit('close')
+}
+</script>
+
+<style lang="scss">
+.hc-menu-icon-box {
+    .el-scrollbar__bar.is-vertical {
+        right: -8px;
+    }
+    .hc-menu-icon {
+        overflow: hidden;
+        .icon-item {
+            width: 100%;
+            text-align: center;
+            background-color: rgba(0,0,0,.02);
+            border-radius: 3px;
+            padding: 10px 0;
+            margin-right: 10px;
+            margin-top: 10px;
+            cursor: pointer;
+            transition: all 0.6s ease;
+            .icon {
+                font-size: 24px;
+                color: #1A1A1A;
+            }
+            .name {
+                font-weight: normal;
+                padding: 10px 0 5px 0;
+                color: #8c8c8c;
+                font-size: 14px;
+                line-height: 12px;
+                opacity: 0.8;
+            }
+            &:hover {
+                background-color: rgba(0,0,0,.06);
+            }
+        }
+    }
+}
+</style>

+ 19 - 5
src/views/system/menu.vue

@@ -39,22 +39,26 @@
                 <el-row :gutter="20">
                     <el-col :span="8">
                         <el-form-item label="菜单名称:" prop="name">
-                            <el-input v-model="formModel.name" />
+                            <el-input v-model="formModel.name" clearable />
                         </el-form-item>
                     </el-col>
                     <el-col :span="8">
                         <el-form-item label="路由地址:" prop="path">
-                            <el-input v-model="formModel.path" />
+                            <el-input v-model="formModel.path" clearable />
                         </el-form-item>
                     </el-col>
                     <el-col :span="8">
                         <el-form-item label="菜单编号:" prop="code">
-                            <el-input v-model="formModel.code" />
+                            <el-input v-model="formModel.code" clearable />
                         </el-form-item>
                     </el-col>
                     <el-col :span="8">
                         <el-form-item label="菜单图标:">
-                            <el-input v-model="formModel.source" />
+                            <el-input v-model="formModel.source" clearable>
+                                <template #append>
+                                    <el-button @click="isIconShow = true">选择图标</el-button>
+                                </template>
+                            </el-input>
                         </el-form-item>
                     </el-col>
                     <el-col :span="8">
@@ -66,12 +70,15 @@
                     </el-col>
                     <el-col :span="8">
                         <el-form-item label="上级菜单:">
-                            <el-tree-select v-model="formModel.parentId" placeholder="选择上级菜单" :data="levelMenu" filterable check-strictly block :render-after-expand="false" />
+                            <el-tree-select v-model="formModel.parentId" placeholder="选择上级菜单" clearable :data="levelMenu" filterable check-strictly block :render-after-expand="false" />
                         </el-form-item>
                     </el-col>
                 </el-row>
             </el-form>
         </hc-new-dialog>
+
+        <!-- 图标选择 -->
+        <hc-menu-icon v-model="isIconShow" @finish="menuIconFinish" />
     </hc-new-card>
 </template>
 
@@ -183,6 +190,13 @@ const formRules = {
     },
 }
 
+//图标选择
+const isIconShow = ref(false)
+const menuIconFinish = (icon) => {
+    formModel.value.source = icon
+    isIconShow.value = false
+}
+
 //新增菜单
 const addClick = () => {
     formModel.value = {}