🐛 终端无法粘贴.

This commit is contained in:
lijiahangmax
2024-03-23 23:31:21 +08:00
parent a3d4420754
commit 1125ef8a5a
5 changed files with 2714 additions and 1034 deletions

View File

@@ -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",

File diff suppressed because it is too large Load Diff

View File

@@ -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>-->

View File

@@ -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() {

View File

@@ -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();