|
@@ -6,11 +6,20 @@
|
|
|
<a-card
|
|
<a-card
|
|
|
:title="$t('menu.resource.title')"
|
|
:title="$t('menu.resource.title')"
|
|
|
:bordered="false"
|
|
:bordered="false"
|
|
|
|
|
+ :header-style="{ textAlign: 'left' }"
|
|
|
style=" 'width': '100%'; height: calc(100vh - 250px); overflow-y:auto "
|
|
style=" 'width': '100%'; height: calc(100vh - 250px); overflow-y:auto "
|
|
|
>
|
|
>
|
|
|
|
|
+ <template #title>
|
|
|
|
|
+ <span>{{ $t('menu.resource.title') }}</span>
|
|
|
|
|
+ <a-tooltip content="点击后可通过拖拽更改资源结构,再次点击来关闭" background-color="#165DFF">
|
|
|
|
|
+ <a-button type="outline" style="float: right;" @click="toggleDraggable" :style="{color: buttonColor}">
|
|
|
|
|
+ <component :is="lockIcon" />
|
|
|
|
|
+ </a-button>
|
|
|
|
|
+ </a-tooltip>
|
|
|
|
|
+ </template>
|
|
|
<a-tree
|
|
<a-tree
|
|
|
class="tree-demo"
|
|
class="tree-demo"
|
|
|
- draggable
|
|
|
|
|
|
|
+ :draggable="draggable"
|
|
|
blockNode
|
|
blockNode
|
|
|
:default-expand-all=true
|
|
:default-expand-all=true
|
|
|
:data="treeData"
|
|
:data="treeData"
|
|
@@ -35,9 +44,9 @@
|
|
|
@click="() => onIconClick(nodeData)"
|
|
@click="() => onIconClick(nodeData)"
|
|
|
/>
|
|
/>
|
|
|
<a-popconfirm v-if="nodeData.menuName!='root'"
|
|
<a-popconfirm v-if="nodeData.menuName!='root'"
|
|
|
- content="请确认是否删除?"
|
|
|
|
|
- type="success"
|
|
|
|
|
- @ok="() => onIconClickDelete(nodeData)"
|
|
|
|
|
|
|
+ content="请确认是否删除?"
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ @ok="() => onIconClickDelete(nodeData)"
|
|
|
>
|
|
>
|
|
|
<IconDelete
|
|
<IconDelete
|
|
|
style="
|
|
style="
|
|
@@ -174,227 +183,235 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
- import { ref } from 'vue';
|
|
|
|
|
- import { IconPlus } from '@arco-design/web-vue/es/icon';
|
|
|
|
|
- import {
|
|
|
|
|
- Organization,
|
|
|
|
|
- OrganizationAdd, OrganizationUpdate,
|
|
|
|
|
- Resource,
|
|
|
|
|
- ResourceAdd,
|
|
|
|
|
- ResourceById,
|
|
|
|
|
- ResourceDelete,
|
|
|
|
|
- ResourceList,
|
|
|
|
|
- ResourceUpdate
|
|
|
|
|
- } from "@/api/authority";
|
|
|
|
|
- import Authheader from '@/views/authority/components/authheader.vue';
|
|
|
|
|
- import { Modal } from '@arco-design/web-vue';
|
|
|
|
|
- import { userModelState } from '@/store';
|
|
|
|
|
|
|
+import { ref } from 'vue';
|
|
|
|
|
+import { IconPlus } from '@arco-design/web-vue/es/icon';
|
|
|
|
|
+import {
|
|
|
|
|
+ Organization,
|
|
|
|
|
+ OrganizationAdd, OrganizationUpdate,
|
|
|
|
|
+ Resource,
|
|
|
|
|
+ ResourceAdd,
|
|
|
|
|
+ ResourceById,
|
|
|
|
|
+ ResourceDelete,
|
|
|
|
|
+ ResourceList,
|
|
|
|
|
+ ResourceUpdate
|
|
|
|
|
+} from "@/api/authority";
|
|
|
|
|
+import Authheader from '@/views/authority/components/authheader.vue';
|
|
|
|
|
+import { Modal } from '@arco-design/web-vue';
|
|
|
|
|
+import { userModelState } from '@/store';
|
|
|
|
|
|
|
|
- const modelStore = userModelState();
|
|
|
|
|
- let formRef = ref();
|
|
|
|
|
- let addFormRef= ref();
|
|
|
|
|
- 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: '3',
|
|
|
|
|
- value: '目录',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- key: '0',
|
|
|
|
|
- value: '菜单',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- key: '1',
|
|
|
|
|
- value: '按钮',
|
|
|
|
|
- },
|
|
|
|
|
- ]);
|
|
|
|
|
- let resourceform = ref<Resource>({
|
|
|
|
|
- component: '',
|
|
|
|
|
- createTime: '',
|
|
|
|
|
- description: '',
|
|
|
|
|
- icon: '',
|
|
|
|
|
- menuId: '',
|
|
|
|
|
- menuName: '',
|
|
|
|
|
- menuType: '',
|
|
|
|
|
- orderNum: '0',
|
|
|
|
|
- parentId: '',
|
|
|
|
|
- parentName: '',
|
|
|
|
|
- children: [],
|
|
|
|
|
- path: '',
|
|
|
|
|
- perms: '',
|
|
|
|
|
- status: '',
|
|
|
|
|
- syesourcetype: '',
|
|
|
|
|
- target: '',
|
|
|
|
|
- updateTime: '',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+const modelStore = userModelState();
|
|
|
|
|
+let formRef = ref();
|
|
|
|
|
+let addFormRef= ref();
|
|
|
|
|
+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: '3',
|
|
|
|
|
+ value: '目录',
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ key: '0',
|
|
|
|
|
+ value: '菜单',
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ key: '1',
|
|
|
|
|
+ value: '按钮',
|
|
|
|
|
+ },
|
|
|
|
|
+]);
|
|
|
|
|
+let resourceform = ref<Resource>({
|
|
|
|
|
+ component: '',
|
|
|
|
|
+ createTime: '',
|
|
|
|
|
+ description: '',
|
|
|
|
|
+ icon: '',
|
|
|
|
|
+ menuId: '',
|
|
|
|
|
+ menuName: '',
|
|
|
|
|
+ menuType: '',
|
|
|
|
|
+ orderNum: '0',
|
|
|
|
|
+ parentId: '',
|
|
|
|
|
+ parentName: '',
|
|
|
|
|
+ children: [],
|
|
|
|
|
+ path: '',
|
|
|
|
|
+ perms: '',
|
|
|
|
|
+ status: '',
|
|
|
|
|
+ syesourcetype: '',
|
|
|
|
|
+ target: '',
|
|
|
|
|
+ updateTime: '',
|
|
|
|
|
+});
|
|
|
|
|
+let draggable = ref(false);
|
|
|
|
|
+let buttonColor = ref("");
|
|
|
|
|
+let lockIcon = ref("IconLock");
|
|
|
|
|
|
|
|
|
|
|
|
|
- const onIconClick = (nodeData) => {
|
|
|
|
|
- if (nodeData) {
|
|
|
|
|
- resourceform.value.parentId = nodeData.menuId;
|
|
|
|
|
- resourceform.value.parentName = nodeData.menuName;
|
|
|
|
|
- }
|
|
|
|
|
- resourceform.value.component = '';
|
|
|
|
|
- resourceform.value.createTime = '';
|
|
|
|
|
- resourceform.value.description = '';
|
|
|
|
|
- resourceform.value.icon = '';
|
|
|
|
|
- resourceform.value.menuId = '';
|
|
|
|
|
- resourceform.value.menuName = '';
|
|
|
|
|
- resourceform.value.menuType = '';
|
|
|
|
|
- resourceform.value.orderNum = '0';
|
|
|
|
|
- resourceform.value.path = '';
|
|
|
|
|
- resourceform.value.perms = '';
|
|
|
|
|
- resourceform.value.status = '';
|
|
|
|
|
- resourceform.value.syesourcetype = '';
|
|
|
|
|
|
|
+const onIconClick = (nodeData) => {
|
|
|
|
|
+ if (nodeData) {
|
|
|
|
|
+ resourceform.value.parentId = nodeData.menuId;
|
|
|
|
|
+ resourceform.value.parentName = nodeData.menuName;
|
|
|
|
|
+ }
|
|
|
|
|
+ resourceform.value.component = '';
|
|
|
|
|
+ resourceform.value.createTime = '';
|
|
|
|
|
+ resourceform.value.description = '';
|
|
|
|
|
+ resourceform.value.icon = '';
|
|
|
|
|
+ resourceform.value.menuId = '';
|
|
|
|
|
+ resourceform.value.menuName = '';
|
|
|
|
|
+ resourceform.value.menuType = '';
|
|
|
|
|
+ resourceform.value.orderNum = '0';
|
|
|
|
|
+ resourceform.value.path = '';
|
|
|
|
|
+ resourceform.value.perms = '';
|
|
|
|
|
+ resourceform.value.status = '';
|
|
|
|
|
+ resourceform.value.syesourcetype = '';
|
|
|
|
|
|
|
|
- visible.value = true;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ visible.value = true;
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- //图片上传
|
|
|
|
|
- const uploadAction = '/api/v1/llm/upload'; // 替换为你的上传API
|
|
|
|
|
- const fileList = ref([]);
|
|
|
|
|
- const imageUrls = ref([]);
|
|
|
|
|
- const uploadUrl = ref([]);
|
|
|
|
|
- const httpUrl = modelStore.hrefUrl;
|
|
|
|
|
- const updateFileList = (newFileList) => {
|
|
|
|
|
- fileList.value = newFileList;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+//图片上传
|
|
|
|
|
+const uploadAction = '/api/v1/llm/upload'; // 替换为你的上传API
|
|
|
|
|
+const fileList = ref([]);
|
|
|
|
|
+const imageUrls = ref([]);
|
|
|
|
|
+const uploadUrl = ref([]);
|
|
|
|
|
+const httpUrl = modelStore.hrefUrl;
|
|
|
|
|
+const updateFileList = (newFileList) => {
|
|
|
|
|
+ fileList.value = newFileList;
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- const handleSuccess = (urls) => {
|
|
|
|
|
- uploadUrl.value = urls;
|
|
|
|
|
|
|
+const handleSuccess = (urls) => {
|
|
|
|
|
+ uploadUrl.value = urls;
|
|
|
|
|
|
|
|
- const urlsArr = urls.map((url) => {
|
|
|
|
|
- return httpUrl + url;
|
|
|
|
|
- });
|
|
|
|
|
- imageUrls.value = urlsArr; // 拿到上传的图片地址
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const urlsArr = urls.map((url) => {
|
|
|
|
|
+ return httpUrl + url;
|
|
|
|
|
+ });
|
|
|
|
|
+ imageUrls.value = urlsArr; // 拿到上传的图片地址
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- const addCb = async (err) => {
|
|
|
|
|
- if (err) {
|
|
|
|
|
- visible.value = true;
|
|
|
|
|
- } else {
|
|
|
|
|
- resourceform.value.icon = uploadUrl.value[0] || '';
|
|
|
|
|
- await ResourceAdd({
|
|
|
|
|
- ...resourceform.value,
|
|
|
|
|
- } as unknown as Resource).then((res) => {
|
|
|
|
|
- ResourceData('');
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
|
|
+const addCb = async (err) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ visible.value = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ resourceform.value.icon = uploadUrl.value[0] || '';
|
|
|
|
|
+ await ResourceAdd({
|
|
|
|
|
+ ...resourceform.value,
|
|
|
|
|
+ } as unknown as Resource).then((res) => {
|
|
|
|
|
+ ResourceData('');
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- const addresource = async (done) => {
|
|
|
|
|
- addFormRef.value.validate(addCb);
|
|
|
|
|
- };
|
|
|
|
|
|
|
+const addresource = async (done) => {
|
|
|
|
|
+ addFormRef.value.validate(addCb);
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- const onIconClickDelete = (nodeData) => {
|
|
|
|
|
- ResourceDelete(nodeData.menuId).then(() => {
|
|
|
|
|
- ResourceData('');
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
|
|
+const onIconClickDelete = (nodeData) => {
|
|
|
|
|
+ ResourceDelete(nodeData.menuId).then(() => {
|
|
|
|
|
+ ResourceData('');
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- const showDetail = (id) => {
|
|
|
|
|
- ResourceById(id).then((res) => {
|
|
|
|
|
- resourceform.value = { ...res.data };
|
|
|
|
|
- resourceform.value.icon = res.data.icon;
|
|
|
|
|
|
|
+const showDetail = (id) => {
|
|
|
|
|
+ ResourceById(id).then((res) => {
|
|
|
|
|
+ resourceform.value = { ...res.data };
|
|
|
|
|
+ resourceform.value.icon = res.data.icon;
|
|
|
|
|
|
|
|
- imageUrls.value.push(httpUrl + res.data.icon);
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
- const cb = async (err) => {
|
|
|
|
|
- if (err) {
|
|
|
|
|
|
|
+ imageUrls.value.push(httpUrl + res.data.icon);
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+const cb = async (err) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
|
|
|
- } else {
|
|
|
|
|
- resourceform.value.icon = uploadUrl.value[0] || '';
|
|
|
|
|
- ResourceUpdate({
|
|
|
|
|
- ...resourceform.value,
|
|
|
|
|
- } as unknown as Resource).then((res) => {
|
|
|
|
|
- ResourceData('');
|
|
|
|
|
- Modal.success({
|
|
|
|
|
- title: '保存成功',
|
|
|
|
|
- content: '保存成功',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ resourceform.value.icon = uploadUrl.value[0] || '';
|
|
|
|
|
+ ResourceUpdate({
|
|
|
|
|
+ ...resourceform.value,
|
|
|
|
|
+ } as unknown as Resource).then((res) => {
|
|
|
|
|
+ ResourceData('');
|
|
|
|
|
+ Modal.success({
|
|
|
|
|
+ title: '保存成功',
|
|
|
|
|
+ content: '保存成功',
|
|
|
});
|
|
});
|
|
|
- }
|
|
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
- const editresource = () => {
|
|
|
|
|
- formRef.value.validate(cb);
|
|
|
|
|
|
|
+}
|
|
|
|
|
+const editresource = () => {
|
|
|
|
|
+ formRef.value.validate(cb);
|
|
|
|
|
|
|
|
- };
|
|
|
|
|
- const reset = (id) => {
|
|
|
|
|
- ResourceById(id).then((res) => {
|
|
|
|
|
- resourceform.value = { ...res.data };
|
|
|
|
|
|
|
+};
|
|
|
|
|
+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;
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- 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);
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- 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);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- 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 handleCancel = (type) => {
|
|
|
|
|
+ if (type == 1) {
|
|
|
|
|
+ visible.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- const ResourceData = async (key) => {
|
|
|
|
|
- await ResourceList(key).then((res) => {
|
|
|
|
|
- treeData.value = [...res.rows];
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
|
|
+const toggleDraggable = () =>{
|
|
|
|
|
+ draggable.value = !draggable.value;
|
|
|
|
|
+ buttonColor.value= draggable.value ? '#575757' : '';
|
|
|
|
|
+ lockIcon.value = draggable.value ? 'IconUnlock' : 'IconLock';
|
|
|
|
|
+};
|
|
|
|
|
+const ResourceData = async (key) => {
|
|
|
|
|
+ await ResourceList(key).then((res) => {
|
|
|
|
|
+ treeData.value = [...res.rows];
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
- ResourceData('');
|
|
|
|
|
|
|
+ResourceData('');
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<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;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+.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;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+@keyframes blinkBg {
|
|
|
|
|
+ 0% {
|
|
|
|
|
+ background-color: transparent;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- 100% {
|
|
|
|
|
- background-color: var(--color-primary-light-1);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ background-color: var(--color-primary-light-1);
|
|
|
}
|
|
}
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|