From 1e4a145667f460778560defccab1137b84139985 Mon Sep 17 00:00:00 2001
From: yinbangzhong <zhongbangyin@126.com>
Date: 星期一, 29 七月 2024 14:10:16 +0800
Subject: [PATCH] 权限资源
---
src/locale/en-US.ts | 2
src/views/authority/resource/locale/en-US.ts | 5
src/views/authority/resource/locale/zh-CN.ts | 4
src/locale/zh-CN.ts | 2
src/api/authority.ts | 43 +++++++
src/api/user.ts | 3
src/router/routes/modules/authority.ts | 10 +
src/views/authority/organization/index.vue | 6 +
src/views/authority/resource/index.vue | 248 +++++++++++++++++++++++++++++++++++++++++
9 files changed, 322 insertions(+), 1 deletions(-)
diff --git a/src/api/authority.ts b/src/api/authority.ts
index 0e4e193..e322a2e 100644
--- a/src/api/authority.ts
+++ b/src/api/authority.ts
@@ -25,6 +25,26 @@
parentName: string;
}
+export interface Resource {
+ "menuId": string;
+ "createTime": string;
+ "updateTime": string;
+ "menuName": string;
+ "component": string;
+ "description": string;
+ "icon": string;
+ "orderNum": string;
+ "target": string;
+ "parentId": string;
+ "parentName":string;
+ "children": any;
+ "syesourcetype": string;
+ "status": string;
+ "path": string;
+ "perms": string;
+ "menuType": string;
+}
+
export interface Result<T> {
code: number;
msg: string;
@@ -77,4 +97,27 @@
export function OrganizationById(id) {
return axios.get<Result<Organization>>("/base/system/dept/" + id);
+}
+
+
+export function ResourceList(key: string) {
+ return axios.get<Result<Resource[]>>("/base/system/menu/treeselect");
+}
+
+
+export function ResourceAdd(resource) {
+ return axios.post("/base/system/menu", { resource });
+}
+
+export function ResourceDelete(id) {
+ return axios.delete("/base/system/menu/" + id);
+}
+
+export function ResourceUpdate(resource) {
+ return axios.put("/base/system/menu", { resource });
+}
+
+
+export function ResourceById(id) {
+ return axios.get<Result<Resource>>("/base/system/menu/" + id);
}
\ No newline at end of file
diff --git a/src/api/user.ts b/src/api/user.ts
index d77dd4a..498bf1b 100644
--- a/src/api/user.ts
+++ b/src/api/user.ts
@@ -11,7 +11,8 @@
token: string;
}
export function login(data: LoginData) {
- return axios.post<LoginRes>('/v1/user/login', data);
+ // return axios.post<LoginRes>('/v1/user/login', data);
+ return axios.post<LoginRes>('/base/login', data);
}
export function logout() {
diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts
index 27a2b4d..a367da7 100644
--- a/src/locale/en-US.ts
+++ b/src/locale/en-US.ts
@@ -5,6 +5,7 @@
import localeUser from '@/views/authority/users/locale/en-US';
import localeOrganization from '@/views/authority/organization/locale/en-US';
+import localeResource from '@/views/authority/resource/locale/en-US';
import localeMonitor from '@/views/dashboard/monitor/locale/en-US';
@@ -57,6 +58,7 @@
...localeUser,
...localeOrganization,
+ ...localeResource,
...localeMonitor,
...localeSearchTable,
diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts
index 02747ec..727b363 100644
--- a/src/locale/zh-CN.ts
+++ b/src/locale/zh-CN.ts
@@ -5,6 +5,7 @@
import localeUser from '@/views/authority/users/locale/zh-CN';
import localeOrganization from '@/views/authority/organization/locale/zh-CN';
+import localeResource from '@/views/authority/resource/locale/zh-CN';
import localeMonitor from '@/views/dashboard/monitor/locale/zh-CN';
@@ -60,6 +61,7 @@
...localeUser,
...localeOrganization,
+ ...localeResource,
...localeMonitor,
...localeSearchTable,
diff --git a/src/router/routes/modules/authority.ts b/src/router/routes/modules/authority.ts
index de853c3..64a81e7 100644
--- a/src/router/routes/modules/authority.ts
+++ b/src/router/routes/modules/authority.ts
@@ -32,6 +32,16 @@
roles: ['*'],
},
},
+ {
+ path: 'resource',
+ name: 'resource',
+ component: () => import('@/views/authority/resource/index.vue'),
+ meta: {
+ locale: 'menu.resource.title',
+ requiresAuth: true,
+ roles: ['*'],
+ },
+ },
],
};
diff --git a/src/views/authority/organization/index.vue b/src/views/authority/organization/index.vue
index 8da1c6c..5088a73 100644
--- a/src/views/authority/organization/index.vue
+++ b/src/views/authority/organization/index.vue
@@ -194,6 +194,12 @@
}
};
+const handleCancel = (type) => {
+ if (type == 1) {
+ visible.value = false;
+ }
+};
+
const OrganizationData = async (key) => {
await OrganizationList(key).then((res) => {
treeData.value = [...res.rows];
diff --git a/src/views/authority/resource/index.vue b/src/views/authority/resource/index.vue
new file mode 100644
index 0000000..38f1e06
--- /dev/null
+++ b/src/views/authority/resource/index.vue
@@ -0,0 +1,248 @@
+<template>
+ <div class="container">
+ <authheader :items="menuTips"></authheader>
+ <a-row :gutter="20">
+ <a-col :span="8">
+ <a-card :title="$t('menu.resource.title')" :bordered="false"
+ :style="{ width: '100%',height: '900px', 'overflow-y': 'auto' }">
+ <a-tree
+ class="tree-demo"
+ draggable
+ blockNode
+ :data="treeData"
+ :show-line="showLine"
+ :fieldNames="{
+ key:'menuId',
+ title:'menuName',
+ children:'children',
+ }"
+ @drop="onDrop"
+ @select="showDetail"
+ >
+ <template #extra="nodeData">
+ <IconPlus
+ style="position: absolute; right: 60px; font-size: 12px; top: 10px; color: #3370ff;"
+ @click="() => onIconClick(nodeData)"
+ />
+ <IconDelete style="position: absolute; right: 40px; font-size: 12px; top: 10px; color: #3370ff;"
+ @click="() => onIconClickDelete(nodeData)" />
+ </template>
+ </a-tree>
+
+ </a-card>
+ </a-col>
+ <a-col :span="16">
+ <a-card :title="$t('menu.resource.detail')" :bordered="false" :style="{ width: '100%' }">
+ <a-form :model="resourceform" layout="horizontal">
+ <a-form-item field="parentName" label="涓婄骇璧勬簮" disabled>
+ <a-input v-model="resourceform.parentName" />
+ </a-form-item>
+ <a-form-item field="status" label="璧勬簮鐘舵��">
+ <a-switch checked-value="0" unchecked-value="1" v-model="resourceform.status"></a-switch>
+ </a-form-item>
+ <a-form-item field="menuName" label="璧勬簮鍚嶇О">
+ <a-input v-model="resourceform.menuName" />
+ </a-form-item>
+ <a-form-item field="menuType" label="璧勬簮绫诲瀷">
+ <a-select v-model="resourceform.menuType" :options="options" :field-names="fieldNames"
+ :style="{width:'320px'}"
+ placeholder="璇烽�夋嫨" />
+
+ </a-form-item>
+ <a-form-item field="perms" label="璧勬簮鎺у埗鏉冮檺瀛楃">
+ <a-input v-model="resourceform.perms" />
+ </a-form-item>
+ <a-form-item field="component" label="璧勬簮鍦板潃" style="align: start">
+ <a-input v-model="resourceform.component" />
+ </a-form-item>
+ <a-form-item>
+ <a-space>
+ <a-button @click="editresource">淇濆瓨</a-button>
+ <a-button @click="reset(resourceform.menuId)">閲嶇疆</a-button>
+ </a-space>
+ </a-form-item>
+ </a-form>
+ </a-card>
+ </a-col>
+ </a-row>
+ <a-modal width="50%" v-model:visible="visible" title="鏂板" @cancel="handleCancel" @ok="addresource">
+ <a-form :model="resourceform" layout="horizontal">
+ <a-form-item field="parentName" label="涓婄骇璧勬簮" disabled>
+ <a-input v-model="resourceform.parentName" />
+ </a-form-item>
+ <a-form-item field="status" label="璧勬簮鐘舵��">
+ <a-switch checked-value="0" unchecked-value="1" v-model="resourceform.status"></a-switch>
+ </a-form-item>
+ <a-form-item field="menuName" label="璧勬簮鍚嶇О">
+ <a-input v-model="resourceform.menuName" />
+ </a-form-item>
+ <a-form-item field="menuType" label="璧勬簮绫诲瀷">
+ <a-select v-model="resourceform.menuType" :options="options" :field-names="fieldNames"
+ :style="{width:'320px'}"
+ placeholder="璇烽�夋嫨" />
+ </a-form-item>
+ <a-form-item field="perms" label="璧勬簮鎺у埗鏉冮檺瀛楃">
+ <a-input v-model="resourceform.perms" />
+ </a-form-item>
+ <a-form-item field="component" label="璧勬簮鍦板潃" style="align: start">
+ <a-input v-model="resourceform.component" />
+ </a-form-item>
+ </a-form>
+ </a-modal>
+ </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+import { IconPlus } from "@arco-design/web-vue/es/icon";
+import { Resource, ResourceAdd, ResourceById, ResourceDelete, ResourceList, ResourceUpdate } from "@/api/authority";
+import Authheader from "@/views/authority/components/authheader.vue";
+import { Modal } from "@arco-design/web-vue";
+
+let visible = ref(false);
+let treeData = ref([]);
+let showLine = ref(true);
+let menuTips = ref(["鏉冮檺绠$悊", "璧勬簮"]);
+const fieldNames = { value: "key", label: "value" };
+// 0鐩綍 1鑿滃崟 2鎸夐挳
+let options = ref([
+ {
+ key: "0",
+ value: "鐩綍"
+ },
+ {
+ key: "1",
+ value: "鑿滃崟"
+ },
+ {
+ key: "2",
+ value: "鎸夐挳"
+ }
+]);
+let resourceform = ref<Resource>({
+ component: "",
+ createTime: "",
+ description: "",
+ icon: "",
+ menuId: "",
+ menuName: "",
+ menuType: "",
+ orderNum: "",
+ parentId: "",
+ parentName: "",
+ children: [],
+ path: "",
+ perms: "",
+ status: "",
+ syesourcetype: "",
+ target: "",
+ updateTime: ""
+});
+
+const onIconClick = (nodeData) => {
+ resourceform.value.parentId = nodeData.menuId;
+ visible.value = true;
+};
+
+const addresource = async () => {
+ await ResourceAdd({
+ ...resourceform.value
+ } as unknown as Resource).then((res) => {
+ ResourceData("");
+ });
+};
+
+const onIconClickDelete = (nodeData) => {
+ ResourceDelete(nodeData.menuId).then(() => {
+ ResourceData("");
+ });
+};
+
+const showDetail = (id) => {
+ ResourceById(id).then((res) => {
+ resourceform.value = { ...res.data };
+ });
+};
+const editresource = () => {
+ ResourceUpdate({
+ ...resourceform.value
+ } as unknown as Resource).then((res) => {
+ ResourceData("");
+ Modal.success({
+ title: "淇濆瓨鎴愬姛",
+ content: "淇濆瓨鎴愬姛"
+ });
+ });
+};
+const reset = (id) => {
+ ResourceById(id).then((res) => {
+ resourceform.value = { ...res.data };
+ });
+};
+
+const onDrop = ({ dragNode, dropNode, dropPosition }) => {
+ const data = treeData.value;
+ ResourceUpdate({
+ orderNum: "0", parentId: dropNode.menuId, menuId: dragNode.menuId
+ });
+ const loop = (data, key, callback) => {
+ data.some((item, index, arr) => {
+ if (item.menuId === key) {
+ callback(item, index, arr);
+ return true;
+ }
+ if (item.children) {
+ return loop(item.children, key, callback);
+ }
+ return false;
+ });
+ };
+
+ loop(data, dragNode.menuId, (_, index, arr) => {
+ arr.splice(index, 1);
+ });
+
+ if (dropPosition === 0) {
+ loop(data, dropNode.menuId, (item) => {
+ item.children = item.children || [];
+ item.children.push(dragNode);
+ });
+ } else {
+ loop(data, dropNode.menuId, (_, index, arr) => {
+ arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode);
+ });
+ }
+};
+
+const handleCancel = (type) => {
+ if (type == 1) {
+ visible.value = false;
+ }
+};
+
+const ResourceData = async (key) => {
+ await ResourceList(key).then((res) => {
+ treeData.value = [...res.rows];
+ });
+};
+
+ResourceData("");
+</script>
+
+
+<style scoped>
+.tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title),
+.tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title):hover {
+ animation: blinkBg 0.4s 2;
+}
+
+@keyframes blinkBg {
+ 0% {
+ background-color: transparent;
+ }
+
+ 100% {
+ background-color: var(--color-primary-light-1);
+ }
+}
+</style>
diff --git a/src/views/authority/resource/locale/en-US.ts b/src/views/authority/resource/locale/en-US.ts
new file mode 100644
index 0000000..114060f
--- /dev/null
+++ b/src/views/authority/resource/locale/en-US.ts
@@ -0,0 +1,5 @@
+export default {
+ "menu.resource.title": "resource",
+ 'menu.resource.detail': 'Detail',
+};
+// export default { "menu.user.title": "Account" };
\ No newline at end of file
diff --git a/src/views/authority/resource/locale/zh-CN.ts b/src/views/authority/resource/locale/zh-CN.ts
new file mode 100644
index 0000000..e70b222
--- /dev/null
+++ b/src/views/authority/resource/locale/zh-CN.ts
@@ -0,0 +1,4 @@
+export default {
+ 'menu.resource.title': '璧勬簮',
+ 'menu.resource.detail': '璇︽儏',
+};
\ No newline at end of file
--
Gitblit v1.8.0