🐛 终端无法粘贴.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "orion-ops-pro-ui",
|
"name": "orion-ops-pro-ui",
|
||||||
"description": "Orion Ops Pro for Vue",
|
"description": "Orion Ops Pro for Vue",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"author": "Jiahang Li",
|
"author": "Jiahang Li",
|
||||||
"license": "Apache 2.0",
|
"license": "Apache 2.0",
|
||||||
|
|||||||
3328
orion-ops-ui/pnpm-lock.yaml
generated
3328
orion-ops-ui/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,189 +1,189 @@
|
|||||||
<script lang="tsx">
|
<!--<script lang="tsx">-->
|
||||||
import type { RouteMeta, RouteRecordRaw } from 'vue-router';
|
<!-- import type { RouteMeta, RouteRecordRaw } from 'vue-router';-->
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
<!-- import { useRoute, useRouter } from 'vue-router';-->
|
||||||
import { compile, computed, defineComponent, h, ref } from 'vue';
|
<!-- import { compile, computed, defineComponent, h, ref } from 'vue';-->
|
||||||
import { useAppStore } from '@/store';
|
<!-- import { useAppStore } from '@/store';-->
|
||||||
import { listenerRouteChange } from '@/utils/route-listener';
|
<!-- import { listenerRouteChange } from '@/utils/route-listener';-->
|
||||||
import { openWindow, regexUrl } from '@/utils';
|
<!-- import { openWindow, regexUrl } from '@/utils';-->
|
||||||
import { openNewRoute } from '@/router';
|
<!-- import { openNewRoute } from '@/router';-->
|
||||||
import useMenuTree from './use-menu-tree';
|
<!-- import useMenuTree from './use-menu-tree';-->
|
||||||
|
|
||||||
export default defineComponent({
|
<!-- export default defineComponent({-->
|
||||||
name: 'menuTree',
|
<!-- name: 'menuTree',-->
|
||||||
emit: ['collapse'],
|
<!-- emit: ['collapse'],-->
|
||||||
setup() {
|
<!-- setup() {-->
|
||||||
const appStore = useAppStore();
|
<!-- const appStore = useAppStore();-->
|
||||||
const router = useRouter();
|
<!-- const router = useRouter();-->
|
||||||
const route = useRoute();
|
<!-- const route = useRoute();-->
|
||||||
const { menuTree } = useMenuTree();
|
<!-- const { menuTree } = useMenuTree();-->
|
||||||
const collapsed = computed({
|
<!-- const collapsed = computed({-->
|
||||||
get() {
|
<!-- get() {-->
|
||||||
if (appStore.device === 'desktop') return appStore.menuCollapse;
|
<!-- if (appStore.device === 'desktop') return appStore.menuCollapse;-->
|
||||||
return false;
|
<!-- return false;-->
|
||||||
},
|
<!-- },-->
|
||||||
set(value: boolean) {
|
<!-- set(value: boolean) {-->
|
||||||
appStore.updateSettings({ menuCollapse: value });
|
<!-- appStore.updateSettings({ menuCollapse: value });-->
|
||||||
},
|
<!-- },-->
|
||||||
});
|
<!-- });-->
|
||||||
|
|
||||||
const topMenu = computed(() => appStore.topMenu);
|
<!-- const topMenu = computed(() => appStore.topMenu);-->
|
||||||
const openKeys = ref<string[]>([]);
|
<!-- const openKeys = ref<string[]>([]);-->
|
||||||
const selectedKey = ref<string[]>([]);
|
<!-- const selectedKey = ref<string[]>([]);-->
|
||||||
|
|
||||||
// 跳转路由
|
<!-- // 跳转路由-->
|
||||||
const goto = (e: any, item: RouteRecordRaw) => {
|
<!-- const goto = (e: any, item: RouteRecordRaw) => {-->
|
||||||
// 打开外链
|
<!-- // 打开外链-->
|
||||||
if (regexUrl.test(item.path)) {
|
<!-- if (regexUrl.test(item.path)) {-->
|
||||||
openWindow(item.path);
|
<!-- openWindow(item.path);-->
|
||||||
return;
|
<!-- return;-->
|
||||||
}
|
<!-- }-->
|
||||||
const { hideInMenu, activeMenu, newWindow } = item.meta as RouteMeta;
|
<!-- const { hideInMenu, activeMenu, newWindow } = item.meta as RouteMeta;-->
|
||||||
// 新页面打开
|
<!-- // 新页面打开-->
|
||||||
if (newWindow || e.ctrlKey) {
|
<!-- if (newWindow || e.ctrlKey) {-->
|
||||||
openNewRoute({
|
<!-- openNewRoute({-->
|
||||||
name: item.name,
|
<!-- name: item.name,-->
|
||||||
});
|
<!-- });-->
|
||||||
return;
|
<!-- return;-->
|
||||||
}
|
<!-- }-->
|
||||||
// 设置 selectedKey
|
<!-- // 设置 selectedKey-->
|
||||||
if (route.name === item.name && !hideInMenu && !activeMenu) {
|
<!-- if (route.name === item.name && !hideInMenu && !activeMenu) {-->
|
||||||
selectedKey.value = [item.name as string];
|
<!-- selectedKey.value = [item.name as string];-->
|
||||||
return;
|
<!-- return;-->
|
||||||
}
|
<!-- }-->
|
||||||
// 触发跳转
|
<!-- // 触发跳转-->
|
||||||
router.push({
|
<!-- router.push({-->
|
||||||
name: item.name,
|
<!-- name: item.name,-->
|
||||||
});
|
<!-- });-->
|
||||||
};
|
<!-- };-->
|
||||||
|
|
||||||
const findMenuOpenKeys = (target: string) => {
|
<!-- const findMenuOpenKeys = (target: string) => {-->
|
||||||
const result: string[] = [];
|
<!-- const result: string[] = [];-->
|
||||||
let isFind = false;
|
<!-- let isFind = false;-->
|
||||||
const backtrack = (item: RouteRecordRaw, keys: string[]) => {
|
<!-- const backtrack = (item: RouteRecordRaw, keys: string[]) => {-->
|
||||||
if (item.name === target) {
|
<!-- if (item.name === target) {-->
|
||||||
isFind = true;
|
<!-- isFind = true;-->
|
||||||
result.push(...keys);
|
<!-- result.push(...keys);-->
|
||||||
return;
|
<!-- return;-->
|
||||||
}
|
<!-- }-->
|
||||||
if (item.children?.length) {
|
<!-- if (item.children?.length) {-->
|
||||||
item.children.forEach((el) => {
|
<!-- item.children.forEach((el) => {-->
|
||||||
backtrack(el, [...keys, el.name as string]);
|
<!-- backtrack(el, [...keys, el.name as string]);-->
|
||||||
});
|
<!-- });-->
|
||||||
}
|
<!-- }-->
|
||||||
};
|
<!-- };-->
|
||||||
menuTree.value.forEach((el: RouteRecordRaw) => {
|
<!-- menuTree.value.forEach((el: RouteRecordRaw) => {-->
|
||||||
if (isFind) return;
|
<!-- if (isFind) return;-->
|
||||||
backtrack(el, [el.name as string]);
|
<!-- backtrack(el, [el.name as string]);-->
|
||||||
});
|
<!-- });-->
|
||||||
return result;
|
<!-- return result;-->
|
||||||
};
|
<!-- };-->
|
||||||
|
|
||||||
// 监听路由 设置打开的 key
|
<!-- // 监听路由 设置打开的 key-->
|
||||||
listenerRouteChange((newRoute) => {
|
<!-- listenerRouteChange((newRoute) => {-->
|
||||||
const { activeMenu, hideInMenu } = newRoute.meta;
|
<!-- const { activeMenu, hideInMenu } = newRoute.meta;-->
|
||||||
if (!hideInMenu || activeMenu) {
|
<!-- if (!hideInMenu || activeMenu) {-->
|
||||||
const menuOpenKeys = findMenuOpenKeys(
|
<!-- const menuOpenKeys = findMenuOpenKeys(-->
|
||||||
(activeMenu || newRoute.name) as string
|
<!-- (activeMenu || newRoute.name) as string-->
|
||||||
);
|
<!-- );-->
|
||||||
|
|
||||||
const keySet = new Set([...menuOpenKeys, ...openKeys.value]);
|
<!-- const keySet = new Set([...menuOpenKeys, ...openKeys.value]);-->
|
||||||
openKeys.value = [...keySet];
|
<!-- openKeys.value = [...keySet];-->
|
||||||
|
|
||||||
selectedKey.value = [
|
<!-- selectedKey.value = [-->
|
||||||
activeMenu || menuOpenKeys[menuOpenKeys.length - 1],
|
<!-- activeMenu || menuOpenKeys[menuOpenKeys.length - 1],-->
|
||||||
];
|
<!-- ];-->
|
||||||
}
|
<!-- }-->
|
||||||
}, true);
|
<!-- }, true);-->
|
||||||
|
|
||||||
// 展开菜单
|
<!-- // 展开菜单-->
|
||||||
const setCollapse = (val: boolean) => {
|
<!-- const setCollapse = (val: boolean) => {-->
|
||||||
if (appStore.device === 'desktop')
|
<!-- if (appStore.device === 'desktop')-->
|
||||||
appStore.updateSettings({ menuCollapse: val });
|
<!-- appStore.updateSettings({ menuCollapse: val });-->
|
||||||
};
|
<!-- };-->
|
||||||
|
|
||||||
// 渲染菜单
|
<!-- // 渲染菜单-->
|
||||||
const renderSubMenu = () => {
|
<!-- const renderSubMenu = () => {-->
|
||||||
function travel(_route: RouteRecordRaw[], nodes = []) {
|
<!-- function travel(_route: RouteRecordRaw[], nodes = []) {-->
|
||||||
if (_route) {
|
<!-- if (_route) {-->
|
||||||
_route.forEach((element) => {
|
<!-- _route.forEach((element) => {-->
|
||||||
// This is demo, modify nodes as needed
|
<!-- // This is demo, modify nodes as needed-->
|
||||||
const icon = element?.meta?.icon
|
<!-- const icon = element?.meta?.icon-->
|
||||||
? () => h(compile(`<${element?.meta?.icon}/>`))
|
<!-- ? () => h(compile(`<${element?.meta?.icon}/>`))-->
|
||||||
: null;
|
<!-- : null;-->
|
||||||
const node =
|
<!-- const node =-->
|
||||||
element?.children && element?.children.length !== 0 ? (
|
<!-- element?.children && element?.children.length !== 0 ? (-->
|
||||||
<a-sub-menu
|
<!-- <a-sub-menu-->
|
||||||
key={element?.name}
|
<!-- key={element?.name}-->
|
||||||
v-slots={{
|
<!-- v-slots={{-->
|
||||||
icon,
|
<!-- icon,-->
|
||||||
// 去除国际化 title: () => h(compile(t(element?.meta?.locale || ''))),
|
<!-- // 去除国际化 title: () => h(compile(t(element?.meta?.locale || ''))),-->
|
||||||
title: () => h(compile(element?.meta?.locale || '')),
|
<!-- title: () => h(compile(element?.meta?.locale || '')),-->
|
||||||
}}
|
<!-- }}-->
|
||||||
>
|
<!-- >-->
|
||||||
{travel(element?.children)}
|
<!-- {travel(element?.children)}-->
|
||||||
</a-sub-menu>
|
<!-- </a-sub-menu>-->
|
||||||
) : (
|
<!-- ) : (-->
|
||||||
<a-menu-item
|
<!-- <a-menu-item-->
|
||||||
key={element?.name}
|
<!-- key={element?.name}-->
|
||||||
v-slots={{ icon }}
|
<!-- v-slots={{ icon }}-->
|
||||||
onClick={($event: any) => goto($event, element)}
|
<!-- onClick={($event: any) => goto($event, element)}-->
|
||||||
>
|
<!-- >-->
|
||||||
{element?.meta?.locale || ''}
|
<!-- {element?.meta?.locale || ''}-->
|
||||||
</a-menu-item>
|
<!-- </a-menu-item>-->
|
||||||
);
|
<!-- );-->
|
||||||
nodes.push(node as never);
|
<!-- nodes.push(node as never);-->
|
||||||
});
|
<!-- });-->
|
||||||
}
|
<!-- }-->
|
||||||
return nodes;
|
<!-- return nodes;-->
|
||||||
}
|
<!-- }-->
|
||||||
|
|
||||||
return travel(menuTree.value);
|
<!-- return travel(menuTree.value);-->
|
||||||
};
|
<!-- };-->
|
||||||
|
|
||||||
return () => (
|
<!-- return () => (-->
|
||||||
<a-menu
|
<!-- <a-menu-->
|
||||||
mode={topMenu.value ? 'horizontal' : 'vertical'}
|
<!-- mode={topMenu.value ? 'horizontal' : 'vertical'}-->
|
||||||
v-model:collapsed={collapsed.value}
|
<!-- v-model:collapsed={collapsed.value}-->
|
||||||
v-model:open-keys={openKeys.value}
|
<!-- v-model:open-keys={openKeys.value}-->
|
||||||
show-collapse-button={appStore.device !== 'mobile'}
|
<!-- show-collapse-button={appStore.device !== 'mobile'}-->
|
||||||
auto-open={false}
|
<!-- auto-open={false}-->
|
||||||
selected-keys={selectedKey.value}
|
<!-- selected-keys={selectedKey.value}-->
|
||||||
auto-open-selected={true}
|
<!-- auto-open-selected={true}-->
|
||||||
level-indent={34}
|
<!-- level-indent={34}-->
|
||||||
style="height: 100%; width:100%;"
|
<!-- style="height: 100%; width:100%;"-->
|
||||||
onCollapse={setCollapse}
|
<!-- onCollapse={setCollapse}-->
|
||||||
>
|
<!-- >-->
|
||||||
{renderSubMenu()}
|
<!-- {renderSubMenu()}-->
|
||||||
</a-menu>
|
<!-- </a-menu>-->
|
||||||
);
|
<!-- );-->
|
||||||
},
|
<!-- },-->
|
||||||
});
|
<!-- });-->
|
||||||
</script>
|
<!--</script>-->
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<!--<style lang="less" scoped>-->
|
||||||
:deep(.arco-menu-inner) {
|
<!-- :deep(.arco-menu-inner) {-->
|
||||||
.arco-menu-inline-header {
|
<!-- .arco-menu-inline-header {-->
|
||||||
display: flex;
|
<!-- display: flex;-->
|
||||||
align-items: center;
|
<!-- align-items: center;-->
|
||||||
}
|
<!-- }-->
|
||||||
|
|
||||||
.arco-icon {
|
<!-- .arco-icon {-->
|
||||||
&:not(.arco-icon-down) {
|
<!-- &:not(.arco-icon-down) {-->
|
||||||
font-size: 18px;
|
<!-- font-size: 18px;-->
|
||||||
}
|
<!-- }-->
|
||||||
}
|
<!-- }-->
|
||||||
|
|
||||||
.arco-menu-icon {
|
<!-- .arco-menu-icon {-->
|
||||||
margin-right: 10px !important;
|
<!-- margin-right: 10px !important;-->
|
||||||
}
|
<!-- }-->
|
||||||
|
|
||||||
.arco-menu-indent-list {
|
<!-- .arco-menu-indent-list {-->
|
||||||
width: 28px;
|
<!-- width: 28px;-->
|
||||||
display: inline-block;
|
<!-- display: inline-block;-->
|
||||||
}
|
<!-- }-->
|
||||||
|
|
||||||
.arco-menu-title {
|
<!-- .arco-menu-title {-->
|
||||||
user-select: none;
|
<!-- user-select: none;-->
|
||||||
}
|
<!-- }-->
|
||||||
}
|
<!-- }-->
|
||||||
</style>
|
<!--</style>-->
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import { useClipboard } from '@vueuse/core';
|
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
const { copy: c } = useClipboard();
|
|
||||||
|
|
||||||
// 复制
|
// 复制
|
||||||
export const copy = async (value: string | undefined, tips: string | boolean = `${value} 已复制`) => {
|
export const copy = async (value: string | undefined, tips: string | boolean = `${value} 已复制`) => {
|
||||||
try {
|
try {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await c(value);
|
await copyToClipboard(value);
|
||||||
if (tips) {
|
if (tips) {
|
||||||
Message.success(tips as string);
|
Message.success(tips as string);
|
||||||
}
|
}
|
||||||
@@ -20,7 +17,49 @@ export const copy = async (value: string | undefined, tips: string | boolean = `
|
|||||||
|
|
||||||
// 获取剪切板内容
|
// 获取剪切板内容
|
||||||
export const readText = () => {
|
export const readText = () => {
|
||||||
return navigator.clipboard.readText();
|
if (navigator.clipboard) {
|
||||||
|
return navigator.clipboard.readText();
|
||||||
|
} else {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.style.position = 'absolute';
|
||||||
|
textarea.style.left = '-9999px';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
try {
|
||||||
|
const success = document.execCommand('paste');
|
||||||
|
if (!success) {
|
||||||
|
Message.error('当前浏览器无法读取剪切板内容');
|
||||||
|
}
|
||||||
|
resolve(textarea.value);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 复制到剪切板
|
||||||
|
export const copyToClipboard = async (value: string) => {
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
await navigator.clipboard.writeText(value);
|
||||||
|
} else {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.textContent = value;
|
||||||
|
textarea.style.position = 'absolute';
|
||||||
|
textarea.style.left = '-9999px';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function useCopy() {
|
export default function useCopy() {
|
||||||
|
|||||||
@@ -16,17 +16,18 @@ const preventKeys: Array<ShortcutKey> = [
|
|||||||
altKey: false,
|
altKey: false,
|
||||||
shiftKey: true,
|
shiftKey: true,
|
||||||
code: 'KeyC'
|
code: 'KeyC'
|
||||||
}, {
|
}
|
||||||
ctrlKey: true,
|
// , {
|
||||||
altKey: false,
|
// ctrlKey: true,
|
||||||
shiftKey: true,
|
// altKey: false,
|
||||||
code: 'KeyV'
|
// shiftKey: true,
|
||||||
}, {
|
// code: 'KeyV'
|
||||||
ctrlKey: false,
|
// }, {
|
||||||
altKey: false,
|
// ctrlKey: false,
|
||||||
shiftKey: true,
|
// altKey: false,
|
||||||
code: 'Insert'
|
// shiftKey: true,
|
||||||
},
|
// code: 'Insert'
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
const { copy: copyValue, readText } = useCopy();
|
const { copy: copyValue, readText } = useCopy();
|
||||||
|
|||||||
Reference in New Issue
Block a user