| | |
| | | <a-card |
| | | :title="$t('menu.resource.title')" |
| | | :bordered="false" |
| | | :header-style="{ textAlign: 'left' }" |
| | | 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 |
| | | class="tree-demo" |
| | | draggable |
| | | :draggable="draggable" |
| | | blockNode |
| | | :default-expand-all=true |
| | | :data="treeData" |
| | |
| | | @click="() => onIconClick(nodeData)" |
| | | /> |
| | | <a-popconfirm v-if="nodeData.menuName!='root'" |
| | | content="请确认是否删除?" |
| | | type="success" |
| | | @ok="() => onIconClickDelete(nodeData)" |
| | | content="请确认是否删除?" |
| | | type="success" |
| | | @ok="() => onIconClickDelete(nodeData)" |
| | | > |
| | | <IconDelete |
| | | style=" |
| | |
| | | </template> |
| | | |
| | | <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 = ''; |
| | | |
| | | 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 handleSuccess = (urls) => { |
| | | uploadUrl.value = urls; |
| | | |
| | | 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 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 addresource = async (done) => { |
| | | addFormRef.value.validate(addCb); |
| | | }; |
| | | visible.value = true; |
| | | }; |
| | | |
| | | const onIconClickDelete = (nodeData) => { |
| | | ResourceDelete(nodeData.menuId).then(() => { |
| | | //图片上传 |
| | | 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 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 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) { |
| | | |
| | | } 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 reset = (id) => { |
| | | ResourceById(id).then((res) => { |
| | | resourceform.value = { ...res.data }; |
| | | }); |
| | | }; |
| | | const addresource = async (done) => { |
| | | addFormRef.value.validate(addCb); |
| | | }; |
| | | |
| | | const onDrop = ({ dragNode, dropNode, dropPosition }) => { |
| | | const data = treeData.value; |
| | | 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; |
| | | |
| | | imageUrls.value.push(httpUrl + res.data.icon); |
| | | }); |
| | | }; |
| | | const cb = async (err) => { |
| | | if (err) { |
| | | |
| | | } else { |
| | | resourceform.value.icon = uploadUrl.value[0] || ''; |
| | | ResourceUpdate({ |
| | | orderNum: '0', |
| | | parentId: dropNode.menuId, |
| | | menuId: dragNode.menuId, |
| | | ...resourceform.value, |
| | | } as unknown as Resource).then((res) => { |
| | | ResourceData(''); |
| | | Modal.success({ |
| | | title: '保存成功', |
| | | content: '保存成功', |
| | | }); |
| | | }); |
| | | 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 editresource = () => { |
| | | formRef.value.validate(cb); |
| | | |
| | | loop(data, dragNode.menuId, (_, index, arr) => { |
| | | arr.splice(index, 1); |
| | | }); |
| | | }; |
| | | const reset = (id) => { |
| | | ResourceById(id).then((res) => { |
| | | resourceform.value = { ...res.data }; |
| | | }); |
| | | }; |
| | | |
| | | 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]; |
| | | 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; |
| | | }); |
| | | }; |
| | | |
| | | ResourceData(''); |
| | | 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 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(''); |
| | | </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; |
| | | .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> |