vue-happy-framework 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vite/deps_temp_c7436e1e/package.json +3 -0
- package/.vite/deps_temp_c7436e1e/vue.js +10857 -0
- package/.vite/deps_temp_c7436e1e/vue.js.map +7 -0
- package/.vscode/extensions.json +3 -0
- package/README.md +18 -0
- package/index.html +13 -0
- package/package.json +36 -0
- package/public/vite.svg +1 -0
- package/src/App.vue +30 -0
- package/src/assets/vue.svg +1 -0
- package/src/components/HelloWorld.vue +38 -0
- package/src/directives/copy.ts +27 -0
- package/src/main.ts +5 -0
- package/src/style.css +80 -0
- package/src/utils/EventBus.ts +19 -0
- package/src/utils/file.ts +15 -0
- package/src/utils/function.ts +106 -0
- package/src/utils/img.ts +36 -0
- package/src/utils/request.ts +0 -0
- package/src/utils/tree.ts +122 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +25 -0
- package/tsconfig.node.json +10 -0
- package/vite.config.ts +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Vue 3 + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
4
|
+
|
|
5
|
+
## Recommended IDE Setup
|
|
6
|
+
|
|
7
|
+
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
|
8
|
+
|
|
9
|
+
## Type Support For `.vue` Imports in TS
|
|
10
|
+
|
|
11
|
+
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
|
12
|
+
|
|
13
|
+
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
|
14
|
+
|
|
15
|
+
1. Disable the built-in TypeScript Extension
|
|
16
|
+
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
|
17
|
+
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
|
18
|
+
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + Vue + TS</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vue-happy-framework",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite",
|
|
7
|
+
"build": "vue-tsc && vite build",
|
|
8
|
+
"preview": "vite preview"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://gitee.com/Y_W_J/vue-happy-framework.git"
|
|
13
|
+
},
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@element-plus/icons-vue": "^2.1.0",
|
|
18
|
+
"animate.css": "^4.1.1",
|
|
19
|
+
"axios": "^1.6.2",
|
|
20
|
+
"clipboard": "^2.0.11",
|
|
21
|
+
"dayjs": "^1.11.10",
|
|
22
|
+
"echarts": "^5.4.3",
|
|
23
|
+
"element-plus": "^2.4.2",
|
|
24
|
+
"pinia": "^2.1.7",
|
|
25
|
+
"vant": "^4.7.3",
|
|
26
|
+
"vue": "^3.3.4",
|
|
27
|
+
"vue-router": "^4.2.5"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@vitejs/plugin-vue": "^4.2.3",
|
|
31
|
+
"sass": "^1.69.5",
|
|
32
|
+
"typescript": "^5.0.2",
|
|
33
|
+
"vite": "^4.4.5",
|
|
34
|
+
"vue-tsc": "^1.8.5"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/public/vite.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
package/src/App.vue
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import HelloWorld from './components/HelloWorld.vue'
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div>
|
|
7
|
+
<a href="https://vitejs.dev" target="_blank">
|
|
8
|
+
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://vuejs.org/" target="_blank">
|
|
11
|
+
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
|
12
|
+
</a>
|
|
13
|
+
</div>
|
|
14
|
+
<HelloWorld msg="Vite + Vue" />
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<style scoped>
|
|
18
|
+
.logo {
|
|
19
|
+
height: 6em;
|
|
20
|
+
padding: 1.5em;
|
|
21
|
+
will-change: filter;
|
|
22
|
+
transition: filter 300ms;
|
|
23
|
+
}
|
|
24
|
+
.logo:hover {
|
|
25
|
+
filter: drop-shadow(0 0 2em #646cffaa);
|
|
26
|
+
}
|
|
27
|
+
.logo.vue:hover {
|
|
28
|
+
filter: drop-shadow(0 0 2em #42b883aa);
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineProps<{ msg: string }>()
|
|
5
|
+
|
|
6
|
+
const count = ref(0)
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<h1>{{ msg }}</h1>
|
|
11
|
+
|
|
12
|
+
<div class="card">
|
|
13
|
+
<button type="button" @click="count++">count is {{ count }}</button>
|
|
14
|
+
<p>
|
|
15
|
+
Edit
|
|
16
|
+
<code>components/HelloWorld.vue</code> to test HMR
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<p>
|
|
21
|
+
Check out
|
|
22
|
+
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
|
23
|
+
>create-vue</a
|
|
24
|
+
>, the official Vue + Vite starter
|
|
25
|
+
</p>
|
|
26
|
+
<p>
|
|
27
|
+
Install
|
|
28
|
+
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
|
29
|
+
in your IDE for a better DX
|
|
30
|
+
</p>
|
|
31
|
+
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
.read-the-docs {
|
|
36
|
+
color: #888;
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import clipboard from 'clipboard'
|
|
2
|
+
import {
|
|
3
|
+
ElMessage
|
|
4
|
+
} from 'element-plus';
|
|
5
|
+
|
|
6
|
+
export default function copy(el, binding) {
|
|
7
|
+
var _clipboard;
|
|
8
|
+
el.onmouseenter = () => {
|
|
9
|
+
_clipboard = new clipboard(el, {
|
|
10
|
+
text: () => {
|
|
11
|
+
if (binding.value == undefined) {
|
|
12
|
+
return el.innerText;
|
|
13
|
+
} else {
|
|
14
|
+
return binding.value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
el.onclick = () => {
|
|
20
|
+
_clipboard.on('success', () => {
|
|
21
|
+
ElMessage.success({
|
|
22
|
+
message: '复制成功'
|
|
23
|
+
})
|
|
24
|
+
_clipboard.destroy();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/main.ts
ADDED
package/src/style.css
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
-webkit-text-size-adjust: 100%;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
a {
|
|
18
|
+
font-weight: 500;
|
|
19
|
+
color: #646cff;
|
|
20
|
+
text-decoration: inherit;
|
|
21
|
+
}
|
|
22
|
+
a:hover {
|
|
23
|
+
color: #535bf2;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
body {
|
|
27
|
+
margin: 0;
|
|
28
|
+
display: flex;
|
|
29
|
+
place-items: center;
|
|
30
|
+
min-width: 320px;
|
|
31
|
+
min-height: 100vh;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h1 {
|
|
35
|
+
font-size: 3.2em;
|
|
36
|
+
line-height: 1.1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
button {
|
|
40
|
+
border-radius: 8px;
|
|
41
|
+
border: 1px solid transparent;
|
|
42
|
+
padding: 0.6em 1.2em;
|
|
43
|
+
font-size: 1em;
|
|
44
|
+
font-weight: 500;
|
|
45
|
+
font-family: inherit;
|
|
46
|
+
background-color: #1a1a1a;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
transition: border-color 0.25s;
|
|
49
|
+
}
|
|
50
|
+
button:hover {
|
|
51
|
+
border-color: #646cff;
|
|
52
|
+
}
|
|
53
|
+
button:focus,
|
|
54
|
+
button:focus-visible {
|
|
55
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.card {
|
|
59
|
+
padding: 2em;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#app {
|
|
63
|
+
max-width: 1280px;
|
|
64
|
+
margin: 0 auto;
|
|
65
|
+
padding: 2rem;
|
|
66
|
+
text-align: center;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@media (prefers-color-scheme: light) {
|
|
70
|
+
:root {
|
|
71
|
+
color: #213547;
|
|
72
|
+
background-color: #ffffff;
|
|
73
|
+
}
|
|
74
|
+
a:hover {
|
|
75
|
+
color: #747bff;
|
|
76
|
+
}
|
|
77
|
+
button {
|
|
78
|
+
background-color: #f9f9f9;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// 事件总线
|
|
2
|
+
export default class EventBus {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.bus = {};
|
|
5
|
+
}
|
|
6
|
+
$on(busName, fn) {
|
|
7
|
+
if (this.bus.hasOwnProperty(busName)) {
|
|
8
|
+
console.log('该事件名已订阅过');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
this.bus[busName] = fn;
|
|
12
|
+
}
|
|
13
|
+
$emit(busName, args) {
|
|
14
|
+
this.bus[busName].apply(null, [args]);
|
|
15
|
+
}
|
|
16
|
+
$off(busName) {
|
|
17
|
+
delete this.bus[busName]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// 导出
|
|
2
|
+
export function exportExl(data, settings) {
|
|
3
|
+
// let fileFullNameTemp=data.headers["content-disposition"].split(";")[1].split("=")[1];
|
|
4
|
+
// let fileFullName=decodeURI(escape(fileFullNameTemp.replace(/\"/g,"")));
|
|
5
|
+
let blob = new Blob([data]);
|
|
6
|
+
let link = document.createElement('a');
|
|
7
|
+
link.download = '导出文件.xlsx';
|
|
8
|
+
link.href = URL.createObjectURL(blob);
|
|
9
|
+
link.style.display = 'none';
|
|
10
|
+
link.target = "_blank";
|
|
11
|
+
document.appendChild(link);
|
|
12
|
+
link.click();
|
|
13
|
+
URL.revokeObjectURL(blob);
|
|
14
|
+
document.body.removeChild(link);
|
|
15
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// 防抖
|
|
2
|
+
export function debounce(fn, wait) {
|
|
3
|
+
var timer = null;
|
|
4
|
+
return function () {
|
|
5
|
+
clearTimeout(timer);
|
|
6
|
+
timer = setTimeout(() => {
|
|
7
|
+
fn.apply(this, arguments);
|
|
8
|
+
}, wait);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 节流
|
|
13
|
+
export function throttle(fn, delay) {
|
|
14
|
+
var canRun = true;
|
|
15
|
+
return function () {
|
|
16
|
+
if (!canRun) return;
|
|
17
|
+
canRun = false;
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
fn.apply(this, arguments);
|
|
20
|
+
canRun = true;
|
|
21
|
+
}, delay);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
// 函数柯里化
|
|
27
|
+
// 这个方法有问题
|
|
28
|
+
/**
|
|
29
|
+
* @description: 将函数柯里化的工具函数
|
|
30
|
+
* @param {Function} fn 待柯里化的函数
|
|
31
|
+
* @param {array} args 已经接收的参数列表
|
|
32
|
+
* @return {Function}
|
|
33
|
+
*/
|
|
34
|
+
export function currying(fn, ...args) {
|
|
35
|
+
// fn需要的参数个数
|
|
36
|
+
const len = fn.length
|
|
37
|
+
// 返回一个函数接收剩余参数
|
|
38
|
+
return function (...params) {
|
|
39
|
+
// 拼接已经接收和新接收的参数列表
|
|
40
|
+
let _args = [...args, ...params]
|
|
41
|
+
// 如果已经接收的参数个数还不够,继续返回一个新函数接收剩余参数
|
|
42
|
+
if (_args.length < len) {
|
|
43
|
+
return currying.call(this, fn, ..._args)
|
|
44
|
+
}
|
|
45
|
+
// 参数全部接收完调用原函数
|
|
46
|
+
return fn.apply(this, _args)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//柯里化方法
|
|
50
|
+
export function curry(fn) {
|
|
51
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
52
|
+
return function () {
|
|
53
|
+
var innerArgs = Array.prototype.slice.call(arguments);
|
|
54
|
+
var finalArgs = args.concat(innerArgs);
|
|
55
|
+
return fn.apply(null, finalArgs);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 事件委托
|
|
59
|
+
export function delegate(element, eventType, selector, fn) {
|
|
60
|
+
element.addEventListener(eventType, e => {
|
|
61
|
+
let el = e.target
|
|
62
|
+
while (!el.matches(selector)) {
|
|
63
|
+
if (element === el) {
|
|
64
|
+
el = null
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
el = el.parentNode
|
|
68
|
+
}
|
|
69
|
+
el && fn.call(el, e, el)
|
|
70
|
+
})
|
|
71
|
+
return element
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 对象深拷贝
|
|
75
|
+
export function deepClone(obj) {
|
|
76
|
+
var objClone = Array.isArray(obj) ? [] : {}; // 判断是对象还是数组
|
|
77
|
+
if (obj && typeof obj === 'object') {
|
|
78
|
+
for (let key in obj) {
|
|
79
|
+
if (obj.hasOwnProperty(key)) {
|
|
80
|
+
if (obj[key] && typeof obj[key] === 'object') {
|
|
81
|
+
objClone[key] = deepClone(obj[key]);
|
|
82
|
+
} else {
|
|
83
|
+
objClone[key] = obj[key]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return objClone;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 单例模式
|
|
92
|
+
export function SingleWrapper(obj) {
|
|
93
|
+
// 排除非函数与箭头函数
|
|
94
|
+
if (!(obj instanceof Function) || !obj.prototype) {
|
|
95
|
+
throw new Error('不是合法的构造函数');
|
|
96
|
+
}
|
|
97
|
+
let instance;
|
|
98
|
+
return function () {
|
|
99
|
+
if (!instance) {
|
|
100
|
+
instance = new obj();
|
|
101
|
+
}
|
|
102
|
+
return instance;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
}
|
package/src/utils/img.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// 图片url转base64
|
|
2
|
+
function imgToBase64(imgUrl) {
|
|
3
|
+
return new Promise((resolve) => {
|
|
4
|
+
var img = new Image();
|
|
5
|
+
img.crossOrigin = 'anonymous';
|
|
6
|
+
img.src = imgUrl;
|
|
7
|
+
img.onload = function () {
|
|
8
|
+
var canvas = document.createElement("canvas");
|
|
9
|
+
canvas.width = img.width;
|
|
10
|
+
canvas.height = img.height;
|
|
11
|
+
canvas.getContext("2d").drawImage(img, 0, 0);
|
|
12
|
+
var base64 = canvas.toDataURL();
|
|
13
|
+
resolve(base64);
|
|
14
|
+
};
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 图片url转blob
|
|
19
|
+
function imgToBlob(imgUrl) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
var img = new Image();
|
|
22
|
+
img.crossOrigin = 'anonymous';
|
|
23
|
+
img.src = imgUrl;
|
|
24
|
+
img.onload = function () {
|
|
25
|
+
var canvas = document.createElement("canvas");
|
|
26
|
+
canvas.width = img.width;
|
|
27
|
+
canvas.height = img.height;
|
|
28
|
+
canvas.getContext("2d").drawImage(img, 0, 0);
|
|
29
|
+
canvas.toBlob((blob) => {
|
|
30
|
+
resolve(blob);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { imgToBase64, imgToBlob };
|
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// 数据转换成树型数据
|
|
2
|
+
export function listToTree(list, mapping) {
|
|
3
|
+
let data = JSON.parse(JSON.stringify(list));
|
|
4
|
+
let idMap = 'id';
|
|
5
|
+
let pidMap = 'pid';
|
|
6
|
+
if (mapping) {
|
|
7
|
+
idMap = mapping.id;
|
|
8
|
+
pidMap = mapping.pid;
|
|
9
|
+
}
|
|
10
|
+
let map = new Map();
|
|
11
|
+
for (let item of data) {
|
|
12
|
+
map.set(item[idMap], item);
|
|
13
|
+
}
|
|
14
|
+
let result = [];
|
|
15
|
+
for (let item of data) {
|
|
16
|
+
if (map.has(item[pidMap])) {
|
|
17
|
+
let parentData = map.get(item[pidMap]);
|
|
18
|
+
if (parentData.children == undefined) {
|
|
19
|
+
parentData.children = [];
|
|
20
|
+
}
|
|
21
|
+
parentData.children.push(item);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
result.push(item);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 树型数据过滤
|
|
31
|
+
export function filterTree(tree = [], map = [], arr = []) {
|
|
32
|
+
if (!tree.length) return [];
|
|
33
|
+
for (let item of tree) {
|
|
34
|
+
if (!(map.includes(items.parentCode) || map.includes(item.organCode))) continue;
|
|
35
|
+
let node = {
|
|
36
|
+
...item,
|
|
37
|
+
children: []
|
|
38
|
+
};
|
|
39
|
+
arr.push(node);
|
|
40
|
+
if (item.children && item.children.length)
|
|
41
|
+
filterTree(item.children, map, node.children);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 筛选某个节点极其所有的子节点
|
|
46
|
+
export function findTreeNode(tree, fn, childrenName) {
|
|
47
|
+
if (childrenName == undefined)
|
|
48
|
+
childrenName = 'children';
|
|
49
|
+
for (let item of tree) {
|
|
50
|
+
if (fn(item))
|
|
51
|
+
return item;
|
|
52
|
+
if (item[childrenName]) {
|
|
53
|
+
let res = findTreeNode(item[childrenName], fn);
|
|
54
|
+
if (res)
|
|
55
|
+
return res;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 给树型数据添加新的字段
|
|
60
|
+
export function addDataTree(tree, data, childrenName) {
|
|
61
|
+
if (childrenName == undefined)
|
|
62
|
+
childrenName = 'children';
|
|
63
|
+
for (let item of tree) {
|
|
64
|
+
for (let dataKey in data) {
|
|
65
|
+
item[dataKey] = data[dataKey];
|
|
66
|
+
}
|
|
67
|
+
if (item[childrenName])
|
|
68
|
+
addDataTree(item[childrenName], data, childrenName);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 树型数据转list
|
|
73
|
+
export function treeToList(tree, mapping) {
|
|
74
|
+
var list = [];
|
|
75
|
+
let childrenName = 'children';
|
|
76
|
+
if (mapping) {
|
|
77
|
+
childrenName = mapping.children;
|
|
78
|
+
}
|
|
79
|
+
handleTreeToList(tree, list, childrenName);
|
|
80
|
+
return list;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function handleTreeToList(tree, list, childrenName) {
|
|
84
|
+
if (!tree || !tree.length) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
for (let item of tree) {
|
|
88
|
+
let temp = JSON.parse(JSON.stringify(item));
|
|
89
|
+
if (item[childrenName]) {
|
|
90
|
+
delete temp[childrenName];
|
|
91
|
+
}
|
|
92
|
+
list.push(temp);
|
|
93
|
+
if (item[childrenName]) {
|
|
94
|
+
handleTreeToList(item[childrenName], list, childrenName);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 寻找父级数据
|
|
100
|
+
export function getParentData(tree, code, mapping) {
|
|
101
|
+
let list = treeToList(tree, mapping);
|
|
102
|
+
// let idMap = 'id';
|
|
103
|
+
// let pidMap = 'pid';
|
|
104
|
+
// if (mapping) {
|
|
105
|
+
// idMap = mapping.id;
|
|
106
|
+
// pidMap = mapping.pid;
|
|
107
|
+
// }
|
|
108
|
+
// let data = {};
|
|
109
|
+
// let itemMap = {};
|
|
110
|
+
for (let item of list) {
|
|
111
|
+
itemMap[item.id] = item;
|
|
112
|
+
let parentData = itemMap[item.parentId];
|
|
113
|
+
if (parentData) {
|
|
114
|
+
item.parent = {};
|
|
115
|
+
item.parent = parentData;
|
|
116
|
+
}
|
|
117
|
+
if (item.code == code) {
|
|
118
|
+
data = itemMap[item.id];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return data;
|
|
122
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "preserve",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
|
24
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
25
|
+
}
|