功能变化: 修复部分bug
This commit is contained in:
@@ -51,10 +51,8 @@ export async function initBackEndControlRoutes() {
|
|||||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO
|
// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO
|
||||||
if (res.data.length <= 0) return Promise.resolve(true);
|
if (res.data.length <= 0) return Promise.resolve(true);
|
||||||
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||||
// const {frameIn,frameOut} = handleMenu(res.data)
|
const {frameIn,frameOut} = handleMenu(res.data)
|
||||||
// dynamicRoutes[0].children = await backEndComponent(frameIn);
|
dynamicRoutes[0].children = await backEndComponent(frameIn);
|
||||||
const {frameInRoutes,frameOutRoutes} = await useFrontendMenuStore().getRouter()
|
|
||||||
dynamicRoutes[0].children = toRaw(frameInRoutes)
|
|
||||||
// 添加动态路由
|
// 添加动态路由
|
||||||
await setAddRoute();
|
await setAddRoute();
|
||||||
// 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
// 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
@@ -96,8 +94,6 @@ export function setFilterMenuAndCacheTagsViewRoutes() {
|
|||||||
*/
|
*/
|
||||||
export function setCacheTagsViewRoutes() {
|
export function setCacheTagsViewRoutes() {
|
||||||
const storesTagsView = useTagsViewRoutes(pinia);
|
const storesTagsView = useTagsViewRoutes(pinia);
|
||||||
// console.log("formatFlatteningRoutes(dynamicRoutes)",formatFlatteningRoutes(dynamicRoutes))
|
|
||||||
// console.log("2222",formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children)
|
|
||||||
storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children);
|
storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +117,6 @@ export function setFilterRouteEnd() {
|
|||||||
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
* @link 参考:https://next.router.vuejs.org/zh/api/#addroute
|
||||||
*/
|
*/
|
||||||
export async function setAddRoute() {
|
export async function setAddRoute() {
|
||||||
// console.log("啦啦啦啦啦",setFilterRouteEnd())
|
|
||||||
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
|
||||||
router.addRoute(route);
|
router.addRoute(route);
|
||||||
});
|
});
|
||||||
@@ -168,26 +163,24 @@ export function backEndComponent(routes: any) {
|
|||||||
}
|
}
|
||||||
if(item.is_link){
|
if(item.is_link){
|
||||||
// 对外链接的处理
|
// 对外链接的处理
|
||||||
item.meta.isIframe = !item.is_iframe
|
|
||||||
if(item.is_iframe){
|
if(item.is_iframe){
|
||||||
item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/link')
|
|
||||||
}else {
|
|
||||||
item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/iframes')
|
item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/iframes')
|
||||||
|
}else {
|
||||||
|
item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/link')
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(item.is_iframe){
|
if(item.is_iframe){
|
||||||
const iframeRoute:RouteRecordRaw = {
|
// const iframeRoute:RouteRecordRaw = {
|
||||||
...item
|
// ...item
|
||||||
}
|
// }
|
||||||
router.addRoute(iframeRoute)
|
// router.addRoute(iframeRoute)
|
||||||
item.meta.isLink = item.path
|
item.meta.isLink = item.link_url
|
||||||
item.path = `${item.path}Link`
|
// item.path = `${item.path}Link`
|
||||||
item.name = `${item.name}Link`
|
// item.name = `${item.name}Link`
|
||||||
item.meta.isIframe = !item.is_iframe
|
// item.meta.isIframe = item.is_iframe
|
||||||
item.meta.isKeepAlive = false
|
// item.meta.isKeepAlive = false
|
||||||
item.meta.isIframeOpen = true
|
// item.meta.isIframeOpen = true
|
||||||
item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/link.vue')
|
item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/link.vue')
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item.children && backEndComponent(item.children);
|
item.children && backEndComponent(item.children);
|
||||||
|
|||||||
@@ -117,11 +117,9 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
if (isRequestRoutes) {
|
if (isRequestRoutes) {
|
||||||
// 后端控制路由:路由数据初始化,防止刷新时丢失
|
// 后端控制路由:路由数据初始化,防止刷新时丢失
|
||||||
await initBackEndControlRoutes();
|
await initBackEndControlRoutes();
|
||||||
// await setRouters()
|
|
||||||
// 解决刷新时,一直跳 404 页面问题,关联问题 No match found for location with path 'xxx'
|
// 解决刷新时,一直跳 404 页面问题,关联问题 No match found for location with path 'xxx'
|
||||||
// to.query 防止页面刷新时,普通路由带参数时,参数丢失。动态路由(xxx/:id/:name")isDynamic 无需处理
|
// to.query 防止页面刷新时,普通路由带参数时,参数丢失。动态路由(xxx/:id/:name")isDynamic 无需处理
|
||||||
// console.log("所有路由",router.getRoutes())
|
|
||||||
// console.log(to.path)
|
|
||||||
next({ path: to.path, query: to.query });
|
next({ path: to.path, query: to.query });
|
||||||
} else {
|
} else {
|
||||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP
|
||||||
|
|||||||
@@ -88,12 +88,12 @@ export const staticRoutes: Array<RouteRecordRaw> = [
|
|||||||
title: '登录',
|
title: '登录',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// path: '/demo',
|
path: '/demo',
|
||||||
// name: 'demo',
|
name: 'demo',
|
||||||
// component: () => import('/@/views/system/demo/index.vue'),
|
component: () => import('/@/views/system/demo/index.vue'),
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'message.router.personal'
|
title: 'message.router.personal'
|
||||||
// },
|
},
|
||||||
// }
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {getBaseURL} from '/@/utils/baseUrl';
|
|||||||
import ui from '@fast-crud/ui-element';
|
import ui from '@fast-crud/ui-element';
|
||||||
import {request} from '/@/utils/service';
|
import {request} from '/@/utils/service';
|
||||||
//扩展包
|
//扩展包
|
||||||
import {FsExtendsEditor, FsExtendsUploader} from '@fast-crud/fast-extends';
|
import {FsExtendsEditor, FsExtendsUploader,FsCropperUploader} from '@fast-crud/fast-extends';
|
||||||
import '@fast-crud/fast-extends/dist/style.css';
|
import '@fast-crud/fast-extends/dist/style.css';
|
||||||
import {successNotification} from '/@/utils/message';
|
import {successNotification} from '/@/utils/message';
|
||||||
import XEUtils from "xe-utils";
|
import XEUtils from "xe-utils";
|
||||||
@@ -114,8 +114,13 @@ export default {
|
|||||||
...ret.data
|
...ret.data
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
valueBuilder(context){
|
||||||
|
const {row,key} = context
|
||||||
|
return getBaseURL(row[key])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setLogger({level: 'error'});
|
setLogger({level: 'error'});
|
||||||
// 设置自动染色
|
// 设置自动染色
|
||||||
const dictComponentList = ['dict-cascader', 'dict-checkbox', 'dict-radio', 'dict-select', 'dict-switch', 'dict-tree'];
|
const dictComponentList = ['dict-cascader', 'dict-checkbox', 'dict-radio', 'dict-select', 'dict-switch', 'dict-tree'];
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
|
|||||||
/**
|
/**
|
||||||
* 处理crud警告:Invalid prop: type check failed for prop "name". Expected String with value "2", got Number with value 2.
|
* 处理crud警告:Invalid prop: type check failed for prop "name". Expected String with value "2", got Number with value 2.
|
||||||
*/
|
*/
|
||||||
res.data.forEach((item: any) => {
|
// res.data.forEach((item: any) => {
|
||||||
item.dept = String(item.dept);
|
// item.dept = String(item.dept);
|
||||||
if (item.role && Array.isArray(item.role) && item.role.length > 0) {
|
// if (item.role && Array.isArray(item.role) && item.role.length > 0) {
|
||||||
item.role = item.role.map((r: number) => String(r));
|
// item.role = item.role.map((r: number) => String(r));
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
const editRequest = async ({ form, row }: EditReq) => {
|
const editRequest = async ({ form, row }: EditReq) => {
|
||||||
@@ -218,13 +218,6 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
|
|||||||
url: '/api/system/dept/all_dept/',
|
url: '/api/system/dept/all_dept/',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
label: 'name',
|
label: 'name',
|
||||||
getData: async ({ url }: { url: string }) => {
|
|
||||||
return request({
|
|
||||||
url: url,
|
|
||||||
}).then((ret: any) => {
|
|
||||||
return ret.data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
column: {
|
column: {
|
||||||
minWidth: 150, //最小列宽
|
minWidth: 150, //最小列宽
|
||||||
@@ -264,17 +257,6 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
|
|||||||
url: '/api/system/role/',
|
url: '/api/system/role/',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
label: 'name',
|
label: 'name',
|
||||||
getData: async ({ url }: { url: string }) => {
|
|
||||||
return request({
|
|
||||||
url: url,
|
|
||||||
params: {
|
|
||||||
page: 1,
|
|
||||||
limit: 10,
|
|
||||||
},
|
|
||||||
}).then((ret: any) => {
|
|
||||||
return ret.data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
column: {
|
column: {
|
||||||
minWidth: 100, //最小列宽
|
minWidth: 100, //最小列宽
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<img
|
<img
|
||||||
src="https://img-blog.csdnimg.cn/9eb1d85a417f4ed1ba7107f149ce3da1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_16,color_FFFFFF,t_70,g_se,x_16"
|
src="./img404.png"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
BIN
web/src/views/system/error/img404.png
Normal file
BIN
web/src/views/system/error/img404.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -62,7 +62,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item v-if="!menuFormData.is_catalog" required label="框外显示">
|
<el-form-item v-if="!menuFormData.is_catalog && menuFormData.is_link" required label="是否内嵌">
|
||||||
<el-switch v-model="menuFormData.is_iframe" width="60" inline-prompt active-text="是" inactive-text="否" />
|
<el-switch v-model="menuFormData.is_iframe" width="60" inline-prompt active-text="是" inactive-text="否" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
@@ -151,6 +151,10 @@ export const createCrudOptions = function ({
|
|||||||
placeholder: '输入权限标识',
|
placeholder: '输入权限标识',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
valueBuilder(context){
|
||||||
|
const {row,key} = context
|
||||||
|
return row[key]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
title: '排序',
|
title: '排序',
|
||||||
|
|||||||
@@ -1,59 +1,69 @@
|
|||||||
<template>
|
<template>
|
||||||
<fs-page>
|
<fs-page>
|
||||||
<el-row class="mx-2">
|
<el-row class="mx-2">
|
||||||
<el-col xs="24" :sm="8" :md="6" :lg="4" :xl="4" class="p-1">
|
<el-col xs="24" :sm="8" :md="6" :lg="4" :xl="4" class="p-1">
|
||||||
<el-card :body-style="{ height: '100%' }">
|
<el-card :body-style="{ height: '100%' }">
|
||||||
<p class="font-mono font-black text-center text-xl pb-5">
|
<p class="font-mono font-black text-center text-xl pb-5">
|
||||||
部门列表
|
部门列表
|
||||||
<el-tooltip effect="dark" :content="content" placement="right">
|
<el-tooltip effect="dark" :content="content" placement="right">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<QuestionFilled />
|
<QuestionFilled/>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</p>
|
</p>
|
||||||
<el-input v-model="filterText" :placeholder="placeholder" />
|
<el-input v-model="filterText" :placeholder="placeholder"/>
|
||||||
<el-tree ref="treeRef" class="font-mono font-bold leading-6 text-7xl" :data="data" :props="treeProps"
|
<el-tree ref="treeRef" class="font-mono font-bold leading-6 text-7xl" :data="data" :props="treeProps"
|
||||||
:filter-node-method="filterNode" icon="ArrowRightBold" :indent="12" @node-click="onTreeNodeClick">
|
:filter-node-method="filterNode" icon="ArrowRightBold" :indent="38" highlight-current @node-click="onTreeNodeClick">
|
||||||
<template #default="{ node, data }">
|
<template #default="{ node, data }">
|
||||||
<span class="text-center font-black font-normal">{{ node.label }}</span>
|
<element-tree-line :node="node" :showLabelLine="false" :indent="32">
|
||||||
</template>
|
<span v-if="data.status" class="text-center font-black font-normal">
|
||||||
</el-tree>
|
<SvgIcon name="iconfont icon-shouye" color="var(--el-color-primary)"/> {{ node.label }}
|
||||||
</el-card>
|
</span>
|
||||||
</el-col>
|
<span v-else color="var(--el-color-primary)"> <SvgIcon name="iconfont icon-shouye"/> {{
|
||||||
<el-col xs="24" :sm="16" :md="18" :lg="20" :xl="20" class="p-1">
|
node.label
|
||||||
<el-card :body-style="{ height: '100%' }">
|
}} </span>
|
||||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
</element-tree-line>
|
||||||
<template #actionbar-right>
|
</template>
|
||||||
<importExcel api="api/system/user/">导入 </importExcel>
|
</el-tree>
|
||||||
</template>
|
</el-card>
|
||||||
</fs-crud>
|
</el-col>
|
||||||
</el-card>
|
<el-col xs="24" :sm="16" :md="18" :lg="20" :xl="20" class="p-1">
|
||||||
</el-col>
|
<el-card :body-style="{ height: '100%' }">
|
||||||
</el-row>
|
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||||
|
<template #actionbar-right>
|
||||||
|
<importExcel api="api/system/user/">导入</importExcel>
|
||||||
|
</template>
|
||||||
|
</fs-crud>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
</fs-page>
|
</fs-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="user">
|
<script lang="ts" setup name="user">
|
||||||
import { useExpose, useCrud } from '@fast-crud/fast-crud';
|
import {useExpose, useCrud} from '@fast-crud/fast-crud';
|
||||||
import { createCrudOptions } from './crud';
|
import {createCrudOptions} from './crud';
|
||||||
import * as api from './api';
|
import * as api from './api';
|
||||||
import { ElTree } from 'element-plus';
|
import {ElTree} from 'element-plus';
|
||||||
import { ref, onMounted, watch, toRaw } from 'vue';
|
import {ref, onMounted, watch, toRaw, h} from 'vue';
|
||||||
import XEUtils from 'xe-utils';
|
import XEUtils from 'xe-utils';
|
||||||
|
import {getElementLabelLine} from 'element-tree-line';
|
||||||
import importExcel from '/@/components/importExcel/index.vue'
|
import importExcel from '/@/components/importExcel/index.vue'
|
||||||
|
|
||||||
|
const ElementTreeLine = getElementLabelLine(h);
|
||||||
|
|
||||||
interface Tree {
|
interface Tree {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
status: boolean;
|
status: boolean;
|
||||||
children?: Tree[];
|
children?: Tree[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface APIResponseData {
|
interface APIResponseData {
|
||||||
code?: number;
|
code?: number;
|
||||||
data: [];
|
data: [];
|
||||||
msg?: string;
|
msg?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
@@ -62,18 +72,18 @@ const filterText = ref('');
|
|||||||
const treeRef = ref<InstanceType<typeof ElTree>>();
|
const treeRef = ref<InstanceType<typeof ElTree>>();
|
||||||
|
|
||||||
const treeProps = {
|
const treeProps = {
|
||||||
children: 'children',
|
children: 'children',
|
||||||
label: 'name',
|
label: 'name',
|
||||||
icon: 'icon',
|
icon: 'icon',
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(filterText, (val) => {
|
watch(filterText, (val) => {
|
||||||
treeRef.value!.filter(val);
|
treeRef.value!.filter(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
const filterNode = (value: string, data: Tree) => {
|
const filterNode = (value: string, data: Tree) => {
|
||||||
if (!value) return true;
|
if (!value) return true;
|
||||||
return toRaw(data).name.indexOf(value) !== -1;
|
return toRaw(data).name.indexOf(value) !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = ref([]);
|
let data = ref([]);
|
||||||
@@ -83,27 +93,27 @@ const content = `
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
api.GetDept({}).then((ret: APIResponseData) => {
|
api.GetDept({}).then((ret: APIResponseData) => {
|
||||||
const responseData = ret.data;
|
const responseData = ret.data;
|
||||||
const result = XEUtils.toArrayTree(responseData, {
|
const result = XEUtils.toArrayTree(responseData, {
|
||||||
parentKey: 'parent',
|
parentKey: 'parent',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
strict: true,
|
strict: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
data.value = result;
|
data.value = result;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//树形点击事件
|
//树形点击事件
|
||||||
const onTreeNodeClick = (node: any) => {
|
const onTreeNodeClick = (node: any) => {
|
||||||
const { id } = node;
|
const {id} = node;
|
||||||
crudExpose.doSearch({ form: { dept: id } });
|
crudExpose.doSearch({form: {dept: id}});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getData();
|
getData();
|
||||||
});
|
});
|
||||||
|
|
||||||
// crud组件的ref
|
// crud组件的ref
|
||||||
@@ -111,32 +121,32 @@ const crudRef = ref();
|
|||||||
// crud 配置的ref
|
// crud 配置的ref
|
||||||
const crudBinding = ref();
|
const crudBinding = ref();
|
||||||
// 暴露的方法
|
// 暴露的方法
|
||||||
const { crudExpose } = useExpose({ crudRef, crudBinding });
|
const {crudExpose} = useExpose({crudRef, crudBinding});
|
||||||
// 你的crud配置
|
// 你的crud配置
|
||||||
const { crudOptions } = createCrudOptions({ crudExpose });
|
const {crudOptions} = createCrudOptions({crudExpose});
|
||||||
// 初始化crud配置
|
// 初始化crud配置
|
||||||
const { resetCrudOptions } = useCrud({ crudExpose, crudOptions });
|
const {resetCrudOptions} = useCrud({crudExpose, crudOptions});
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
crudExpose.doRefresh();
|
crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-row {
|
.el-row {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.el-col {
|
.el-col {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-card {
|
.el-card {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-normal {
|
.font-normal {
|
||||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
|
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user