build 调整

This commit is contained in:
icssoa 2021-04-01 18:36:57 +08:00
parent a6b3e9118e
commit 13b2788a84
33 changed files with 5143 additions and 414 deletions

View File

@ -1,3 +1 @@
vue.config.js vue.config.js
/src/crud
/src/core

4571
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
{ {
"name": "front-next", "name": "front-next",
"version": "0.0.1", "version": "0.1.0",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vue-tsc --noEmit && vite build", "build": "vue-tsc --noEmit --skipLibCheck && vite build",
"serve": "vite preview", "serve": "vite preview",
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix" "lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
@ -34,6 +34,8 @@
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.14.168",
"@types/node": "^14.14.37",
"@typescript-eslint/eslint-plugin": "^4.20.0", "@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0", "@typescript-eslint/parser": "^4.20.0",
"@vitejs/plugin-vue": "^1.1.5", "@vitejs/plugin-vue": "^1.1.5",

View File

@ -10,7 +10,7 @@ export default defineComponent({
setup(_: any, { emit }) { setup(_: any, { emit }) {
const $service = inject<any>("service"); const $service = inject<any>("service");
const { refs, setRefs } = useRefs(); const { refs, setRefs }: any = useRefs();
// 树形列表 // 树形列表
const list = ref<any[]>([]); const list = ref<any[]>([]);

View File

@ -23,7 +23,7 @@
</ul> </ul>
</div> </div>
<div class="cl-dept-tree__container" @contextmenu.prevent="openCM"> <div class="cl-dept-tree__container" @contextmenu.stop.prevent="openCM">
<el-tree <el-tree
v-loading="loading" v-loading="loading"
node-key="id" node-key="id"
@ -294,7 +294,7 @@ export default defineComponent({
} }
// //
function openCM(e: any, d: any, n: any) { function openCM(e: any, d?: any, n?: any) {
if (!d) { if (!d) {
d = list.value[0] || {}; d = list.value[0] || {};
} }

View File

@ -31,7 +31,7 @@ export default defineComponent({
emits: ["update:modelValue", "load"], emits: ["update:modelValue", "load"],
setup(props, { emit }) { setup(props, { emit }) {
const { refs, setRefs } = useRefs(); const { refs, setRefs }: any = useRefs();
let quill: any = null; let quill: any = null;

View File

@ -12,11 +12,15 @@
class="app-process__item" class="app-process__item"
:class="{ active: item.active }" :class="{ active: item.active }"
:data-index="index" :data-index="index"
@click="onTap(item)" @click="onTap(item, Number(index))"
@contextmenu.stop.prevent="openCM($event, item)" @contextmenu.stop.prevent="openCM($event, item)"
> >
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
<i v-if="index > 0" class="el-icon-close" @mousedown.stop="onDel(index)"></i> <i
v-if="index > 0"
class="el-icon-close"
@mousedown.stop="onDel(Number(index))"
></i>
</div> </div>
</div> </div>
@ -41,7 +45,7 @@ export default {
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const store = useStore(); const store = useStore();
const { refs, setRefs } = useRefs(); const { refs, setRefs }: any = useRefs();
// //
const menu = reactive<any>({ const menu = reactive<any>({

View File

@ -113,7 +113,7 @@ const mutations = {
// 设置视图路由 // 设置视图路由
SET_VIEW_ROUTES(state: any, list: MenuItem[]) { SET_VIEW_ROUTES(state: any, list: MenuItem[]) {
router.$plugin.addViews(list); router.$plugin?.addViews(list);
state.routes = list; state.routes = list;
storage.set("viewRoutes", list); storage.set("viewRoutes", list);

View File

@ -49,7 +49,7 @@ export default defineComponent({
setup() { setup() {
const $service = inject<any>("service"); const $service = inject<any>("service");
const { refs, setRefs } = useRefs(); const { refs, setRefs }: any = useRefs();
// //
const day = ref<number>(1); const day = ref<number>(1);
@ -148,6 +148,7 @@ export default defineComponent({
}); });
return { return {
$service,
refs, refs,
day, day,
table, table,

View File

@ -477,7 +477,7 @@ export default defineComponent({
} }
// //
async function toMove(e: any) { async function toMove(e?: any) {
let ids = []; let ids = [];
if (!e) { if (!e) {
@ -490,6 +490,7 @@ export default defineComponent({
} }
return { return {
$service,
refs, refs,
isExpand, isExpand,
selects, selects,

View File

@ -3,49 +3,21 @@
<!-- 工具栏 --> <!-- 工具栏 -->
<div class="cl-chat-input__opbar"> <div class="cl-chat-input__opbar">
<ul> <ul>
<!-- 表情 -->
<li> <li>
<!-- 表情 -->
<emoji @select="onEmojiSelect" /> <emoji @select="onEmojiSelect" />
</li> </li>
<!-- 图片上传 -->
<li> <li>
<cl-upload <!-- 图片上传 -->
accept="image/*" <upload name="image" accept="image/*" @before-upload="append" @success="send">
list-type
:before-upload="
(file) => {
onBeforeUpload(file, 'image');
}
"
:on-progress="onUploadProgress"
:on-success="
(res, file) => {
onUploadSuccess(res, file, 'image');
}
"
>
<img src="../static/images/image.png" alt="" /> <img src="../static/images/image.png" alt="" />
</cl-upload> </upload>
</li> </li>
<!-- 视频上传 -->
<li> <li>
<cl-upload <!-- 视频上传 -->
accept="video/*" <upload name="video" accept="video/*" @before-upload="append" @success="send">
list-type
:before-upload="
(file) => {
onBeforeUpload(file, 'video');
}
"
:on-progress="onUploadProgress"
:on-success="
(res, file) => {
onUploadSuccess(res, file, 'video');
}
"
>
<img src="../static/images/video.png" alt="" /> <img src="../static/images/video.png" alt="" />
</cl-upload> </upload>
</li> </li>
</ul> </ul>
</div> </div>
@ -72,10 +44,12 @@
import { defineComponent, inject, nextTick, reactive, ref } from "vue"; import { defineComponent, inject, nextTick, reactive, ref } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import Emoji from "./emoji.vue"; import Emoji from "./emoji.vue";
import Upload from "./upload.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
Emoji Emoji,
Upload
}, },
setup() { setup() {
@ -121,86 +95,6 @@ export default defineComponent({
} }
} }
//
function onBeforeUpload(file: any, key: string) {
//
function next(options = {}) {
const data = {
content: {
[`${key}Url`]: ""
},
type: 0,
uid: file.uid,
loading: true,
progress: "0%",
contentType: chat.modes.indexOf(key),
...options
};
append(data);
}
//
if (key == "image") {
const fileReader = new FileReader();
fileReader.onload = (e: any) => {
const imageUrl = e.target.result;
const image = new Image();
image.onload = () => {
let height = 0;
let width = 0;
if (image.width > 200) {
width = 200;
height = (image.height * 200) / image.width;
}
next({
content: {
imageUrl
},
style: {
height: height + "px",
width: width + "px"
}
});
};
image.src = imageUrl;
};
fileReader.readAsDataURL(file);
} else {
next();
}
}
//
function onUploadProgress(e: any, file: any) {
store.commit("UPDATE_MESSAGE", {
file,
data: {
progress: e.percent + "%"
}
});
}
//
function onUploadSuccess(res: any, file: any, key: string) {
store.commit("UPDATE_MESSAGE", {
file,
data: {
loading: false,
content: {
[`${key}Url`]: res.data
}
},
callback: send
});
}
// //
function onTextSend() { function onTextSend() {
if (text.value) { if (text.value) {
@ -269,9 +163,7 @@ export default defineComponent({
text, text,
emoji, emoji,
send, send,
onBeforeUpload, append,
onUploadProgress,
onUploadSuccess,
onTextSend, onTextSend,
onImageSelect, onImageSelect,
onEmojiSelect, onEmojiSelect,

View File

@ -29,7 +29,7 @@
'is-active': session ? item.id == session.id : false 'is-active': session ? item.id == session.id : false
}" }"
@click="toDetail(item)" @click="toDetail(item)"
@contextmenu.stop.prevent="openCM($event, item.id, index)" @contextmenu.stop.prevent="openCM($event, item.id, Number(index))"
> >
<!-- 头像 --> <!-- 头像 -->
<div class="avatar"> <div class="avatar">

View File

@ -0,0 +1,119 @@
<template>
<cl-upload
:accept="accept"
list-type
:before-upload="onBeforeUpload"
:on-progress="onUploadProgress"
:on-success="onUploadSuccess"
>
<slot></slot>
</cl-upload>
</template>
<script lang="ts">
import { ElFile } from "element-plus/lib/el-upload/src/upload.type";
import { defineComponent, inject } from "vue";
import { useStore } from "vuex";
export default defineComponent({
props: {
name: String,
accept: String
},
emits: ["before-upload", "success"],
setup(props, { emit }) {
const store = useStore();
const chat = inject<any>("chat");
//
function onBeforeUpload(file: ElFile) {
//
function next(options = {}) {
const data = {
content: {
[`${props.name}Url`]: ""
},
type: 0,
uid: file.uid,
loading: true,
progress: "0%",
contentType: chat.modes.indexOf(props.name),
...options
};
emit("before-upload", data);
}
//
if (props.name == "image") {
const fileReader = new FileReader();
fileReader.onload = (e: any) => {
const imageUrl = e.target.result;
const image = new Image();
image.onload = () => {
let height = 0;
let width = 0;
if (image.width > 200) {
width = 200;
height = (image.height * 200) / image.width;
}
next({
content: {
imageUrl
},
style: {
height: height + "px",
width: width + "px"
}
});
};
image.src = imageUrl;
};
fileReader.readAsDataURL(file);
} else {
next();
}
}
//
function onUploadProgress(e: any, file: ElFile) {
store.commit("UPDATE_MESSAGE", {
file,
data: {
progress: e.percent + "%"
}
});
}
//
function onUploadSuccess(res: any, file: ElFile) {
store.commit("UPDATE_MESSAGE", {
file,
data: {
loading: false,
content: {
[`${props.name}Url`]: res.data
}
},
callback: (data: any) => {
emit("success", data);
}
});
}
return {
onBeforeUpload,
onUploadProgress,
onUploadSuccess
};
}
});
</script>

View File

@ -42,7 +42,7 @@
item-key="id" item-key="id"
:data-type="item.params.type" :data-type="item.params.type"
:data-status="item.params.status" :data-status="item.params.status"
@end="(e) => onDragEnd(e, item)" @end="onDragEnd"
> >
<template #item="{ element }"> <template #item="{ element }">
<li <li
@ -125,7 +125,7 @@
class="more" class="more"
type="text" type="text"
size="mini" size="mini"
@click="moreTask(index, item)" @click="moreTask(index)"
>查看更多</el-button >查看更多</el-button
> >
</div> </div>
@ -182,7 +182,9 @@
@click="expandLog(item)" @click="expandLog(item)"
> >
<div class="h"> <div class="h">
<span class="name">{{ index + 1 }} · {{ item.taskName }}</span> <span class="name"
>{{ Number(index) + 1 }} · {{ item.taskName }}</span
>
</div> </div>
<div class="remark" :class="{ _ellipsis: !item._expand }"> <div class="remark" :class="{ _ellipsis: !item._expand }">

View File

@ -145,7 +145,19 @@ export default {
} }
], ],
isDev, isDev,
form: {} form: {
name: "",
conf: {
showAMenu: false,
showRouteNav: true,
showProcess: true,
customMenu: false
},
theme: {
color: "",
url: ""
}
}
}; };
}, },

View File

@ -202,7 +202,7 @@ export default {
loading: false, loading: false,
preview: { preview: {
visible: false, visible: false,
url: null url: ""
} }
}; };
}, },

View File

@ -28,76 +28,81 @@
</ul> </ul>
</div> </div>
<cl-form ref="form" /> <cl-form :ref="setRefs('form')" />
</div> </div>
</template> </template>
<script> <script lang="ts">
import { mapGetters } from "vuex"; import { ElMessage, ElMessageBox } from "element-plus";
import { computed, defineComponent, inject, ref, watch } from "vue";
import { useStore } from "vuex";
import { isEmpty } from "/@/core/utils"; import { isEmpty } from "/@/core/utils";
import { ContextMenu } from "/@/crud";
import { useRefs } from "/@/crud/hooks/core";
export default { export default defineComponent({
name: "cl-upload-space-category", name: "cl-upload-space-category",
inject: ["space"],
props: { props: {
modelValue: [Number] modelValue: [Number, String]
}, },
emits: ["update:modelValue", "change"], emits: ["update:modelValue", "change"],
data() { setup(_, { emit }) {
return { const store = useStore();
list: [], const { refs, setRefs }: any = useRefs();
current: undefined, const $service: any = inject("service");
keyword: "" const space = inject<any>("space");
};
},
computed: { //
...mapGetters(["browser"]), const list = ref<any[]>([]);
flist() { //
return this.list.filter((e) => e.name.includes(this.keyword)); const current = ref<number | string>("");
}
},
watch: { //
current: { const keyword = ref<string>("");
handler(id) {
this.$emit("update:modelValue", id); //
this.$emit("change", id); const flist = computed(() => {
return list.value.filter((e: any) => e.name.includes(keyword.value));
});
//
const browser = computed(() => store.getters.browser);
//
watch(
() => current.value,
(id: number | string) => {
console.log(id);
emit("update:modelValue", id);
emit("change", id);
} }
} );
},
created() {
this.refresh();
},
methods: {
// //
refresh() { function refresh() {
return this.$service.space.type.list().then((res) => { return $service.space.type.list().then((res: any) => {
res.unshift({ res.unshift({
name: "全部文件", name: "全部文件",
id: null id: null
}); });
this.list = res; list.value = res;
if (!isEmpty(res)) { if (!isEmpty(res)) {
if (!this.current) { if (!current.value) {
this.current = res[0].id; current.value = res[0].id;
} }
} }
}); });
}, }
// //
edit(item = {}) { function edit(item: any = {}) {
this.$refs.form.open({ refs.value.form.open({
title: "添加分类", title: "添加分类",
width: "400px", width: "400px",
items: [ items: [
@ -118,87 +123,91 @@ export default {
} }
], ],
on: { on: {
submit: (data, { done, close }) => { submit: (data: any, { done, close }: any) => {
let next = null; let next = null;
if (!item.id) { if (!item.id) {
next = this.$service.space.type.add(data); next = $service.space.type.add(data);
} else { } else {
next = this.$service.space.type.update({ next = $service.space.type.update({
...data, ...data,
id: item.id id: item.id
}); });
} }
next.then(() => { next.then(() => {
this.refresh(); refresh();
close(); close();
}).catch((err) => { }).catch((err: string) => {
this.$message.error(err); ElMessage.error(err);
done(); done();
}); });
} }
} }
}); });
}, }
// //
select(id) { function select(id: number) {
this.current = id; current.value = id;
// //
if (this.browser.isMini) { if (browser.value.isMini) {
this.space.category.visible = false; space.category.visible = false;
} }
}, }
// //
openContextMenu(e, { id, name }) { function openContextMenu(e: any, { id, name }: any) {
if (!id) { if (!id) {
return false; return false;
} }
this.$crud.openContextMenu(e, { ContextMenu.open(e, {
list: [ list: [
{ {
label: "刷新", label: "刷新",
"suffix-icon": "el-icon-edit", "suffix-icon": "el-icon-edit",
callback: (_, done) => { callback: (_: any, done: Function) => {
this.refresh(); refresh();
done(); done();
} }
}, },
{ {
label: "编辑", label: "编辑",
"suffix-icon": "el-icon-edit", "suffix-icon": "el-icon-edit",
callback: (_, done) => { callback: (_: any, done: Function) => {
this.edit({ id, name }); edit({ id, name });
done(); done();
} }
}, },
{ {
label: "删除", label: "删除",
"suffix-icon": "el-icon-delete", "suffix-icon": "el-icon-delete",
callback: (_, done) => { callback: (_: any, done: Function) => {
this.$confirm(`此操作将删除【${name}】下的文件, 是否继续?`, "提示", { ElMessageBox.confirm(
type: "warning" `此操作将删除【${name}】下的文件, 是否继续?`,
}) "提示",
{
type: "warning"
}
)
.then(() => { .then(() => {
this.$service.space.type $service.space.type
.delete({ .delete({
ids: [id] ids: [id]
}) })
.then(() => { .then(() => {
this.$message.success("删除成功"); ElMessage.success("删除成功");
if (id == this.current) { if (id == current.value) {
this.current = null; current.value = 0;
} }
this.refresh(); refresh();
}) })
.catch((err) => { .catch((err: string) => {
this.$message.error(err); ElMessage.error(err);
}); });
}) })
.catch(() => null); .catch(() => null);
@ -209,8 +218,25 @@ export default {
] ]
}); });
} }
refresh();
return {
refs,
setRefs,
browser,
space,
list,
flist,
current,
keyword,
refresh,
edit,
select,
openContextMenu
};
} }
}; });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -6,32 +6,32 @@
@contextmenu.stop.prevent="openContextMenu" @contextmenu.stop.prevent="openContextMenu"
> >
<!-- 错误 --> <!-- 错误 -->
<template v-if="value.error"> <template v-if="info.error">
<div class="cl-upload-space-item__error">上传失败{{ value.error }}</div> <div class="cl-upload-space-item__error">上传失败{{ info.error }}</div>
</template> </template>
<!-- 成功 --> <!-- 成功 -->
<template v-else> <template v-else>
<!-- 图片 --> <!-- 图片 -->
<template v-if="type === 'image'"> <template v-if="type === 'image'">
<el-image fit="cover" :src="value.url" lazy /> <el-image fit="cover" :src="info.url" lazy />
</template> </template>
<!-- 视频 --> <!-- 视频 -->
<template v-else-if="type === 'video'"> <template v-else-if="type === 'video'">
<video <video
controls controls
:src="value.url" :src="info.url"
:style="{ :style="{
'max-height': '100%', maxHeight: '100%',
'max-width': '100%' maxWidth: '100%'
}" }"
></video> ></video>
</template> </template>
<!-- 其他 --> <!-- 其他 -->
<template v-else> <template v-else>
<span>{{ value.url }}</span> <span>{{ info.url }}</span>
</template> </template>
</template> </template>
@ -45,65 +45,86 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
export default { import { computed, defineComponent, inject } from "vue";
import { ContextMenu } from "/@/crud";
export default defineComponent({
name: "cl-upload-space-item", name: "cl-upload-space-item",
inject: ["space"],
props: { props: {
value: Object modelValue: {
type: Object,
default: () => {
return {};
}
}
}, },
emits: ["select", "remove"], emits: ["select", "remove"],
computed: { setup(props, { emit }) {
index() { const space = inject<any>("space");
return this.space.selection.findIndex((e) => e.id === this.value.id);
},
isSelected() { //
return this.index >= 0; const info = computed(() => props.modelValue);
},
type() { //
return (this.value.type || "").split("/")[0]; const index = computed(() =>
space.selection.value.findIndex((e: any) => e.id === info.value.id)
);
//
const isSelected = computed(() => index.value >= 0);
//
const type = computed(() => (info.value.type || "").split("/")[0]);
//
function select() {
emit("select", info.value);
} }
},
methods: { //
select() { function remove() {
this.$emit("select", this.value); emit("remove", info.value);
}, }
remove() { //
this.$emit("remove", this.value); function openContextMenu(e: any) {
}, ContextMenu.open(e, {
openContextMenu(e) {
this.$crud.openContextMenu(e, {
list: [ list: [
{ {
label: this.isSelected ? "取消选中" : "选中", label: isSelected.value ? "取消选中" : "选中",
"suffix-icon": this.isSelected ? "el-icon-close" : "el-icon-check", "suffix-icon": isSelected.value ? "el-icon-close" : "el-icon-check",
callback: (_, done) => { callback: (_: any, done: Function) => {
this.select(); select();
done(); done();
} }
}, },
{ {
label: "删除", label: "删除",
"suffix-icon": "el-icon-delete", "suffix-icon": "el-icon-delete",
callback: (_, done) => { callback: (_: any, done: Function) => {
this.remove(); remove();
done(); done();
} }
} }
] ]
}); });
} }
return {
info,
index,
type,
isSelected,
select,
remove,
openContextMenu
};
} }
}; });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -116,11 +116,7 @@
:page-size="pagination.size" :page-size="pagination.size"
:current-page="pagination.page" :current-page="pagination.page"
:total="pagination.total" :total="pagination.total"
@current-change=" @current-change="onCurrentChange"
(page) => {
refresh({ page });
}
"
/> />
</div> </div>
</div> </div>
@ -141,13 +137,16 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { computed, defineComponent, inject, provide, reactive, ref, watch } from "vue";
import { useStore } from "vuex";
import { ElMessage, ElMessageBox } from "element-plus";
import { ElFile } from "element-plus/lib/el-upload/src/upload.type";
import { isEmpty } from "/@/core/utils"; import { isEmpty } from "/@/core/utils";
import Category from "./category.vue"; import Category from "./category.vue";
import FileItem from "./file-item.vue"; import FileItem from "./file-item.vue";
import { mapGetters } from "vuex";
export default { export default defineComponent({
name: "cl-upload-space", name: "cl-upload-space",
components: { components: {
@ -155,13 +154,9 @@ export default {
FileItem FileItem
}, },
provide() {
return {
space: this
};
},
props: { props: {
//
modelValue: String,
// //
action: String, action: String,
// //
@ -195,199 +190,243 @@ export default {
emits: ["update:modelValue", "confirm"], emits: ["update:modelValue", "confirm"],
data() { setup(props, { emit }) {
return { const store = useStore();
visible: false, const $service = inject<any>("service");
loading: false,
category: { //
id: null, const visible = ref<boolean>(false);
visible: true
//
const loading = ref<boolean>(false);
//
const selection = ref<any[]>([]);
//
const list = ref<any[]>([]);
//
const category = reactive<any>({
id: "",
visible: true
});
//
const pagination = reactive<any>({
page: 1,
size: 12,
total: 0
});
//
const browser = computed(() => store.getters.browser);
//
watch(
() => browser.value.isMini,
(val) => {
category.visible = val ? false : true;
}, },
selection: [], {
list: [], immediate: true
pagination: {
page: 1,
size: 12,
total: 0
} }
}; );
},
computed: { //
...mapGetters(["browser"]), const limitTip = computed(() => selection.value.length + "/" + props.limit);
limitTip() { //
return this.selection.length + "/" + this.limit; const isSelected = computed(() => !isEmpty(selection.value));
},
isSelected() { // Provide
return !isEmpty(this.selection); provide("space", {
category,
selection
});
//
function open() {
visible.value = true;
} }
},
watch: { //
"browser.isMini": { function clear() {
immediate: true, selection.value = [];
handler(val) {
this.category.visible = val ? false : true;
}
} }
},
methods: { //
open() { function close() {
this.visible = true; visible.value = false;
}, clear();
}
close() {
this.visible = false;
this.clear();
},
clear() {
this.selection = [];
},
// //
onSuccess(res, file) { function onSuccess(res: any, file: ElFile) {
const item = this.list.find((e) => file.uid == e.uid); const item = list.value.find((e: any) => file.uid == e.uid);
if (item) { if (item) {
item.url = res.data; item.url = res.data;
this.$service.space.info $service.space.info
.add({ .add({
url: res.data, url: res.data,
type: item.type, type: item.type,
classifyId: item.classifyId classifyId: item.classifyId
}) })
.then((res) => { .then((res: any) => {
item.loading = false; item.loading = false;
item.id = res.id; item.id = res.id;
}) })
.catch((err) => { .catch((err: string) => {
this.$message.error(err); ElMessage.error(err);
}); });
} }
}, }
// //
onError(err, file) { function onError(err: string, file: ElFile) {
const item = this.list.find((e) => file.uid == e.uid); const item = list.value.find((e) => file.uid == e.uid);
if (item) { if (item) {
item.loading = false; item.loading = false;
this.$set(item, "error", err); item.error = err;
} }
}, }
// //
beforeUpload({ tempFilePath, type, uid }) { function beforeUpload({ tempFilePath, type, uid }: any) {
this.list.unshift({ list.value.unshift({
url: tempFilePath, url: tempFilePath,
type, type,
uid, uid,
classifyId: this.category.id, classifyId: category.id,
loading: true, loading: true,
progress: "0%" progress: "0%"
}); });
}, }
// //
onProgress({ percent }, file) { function onProgress({ percent }: any, file: ElFile) {
const item = this.list.find(({ uid }) => uid == file.uid); const item = list.value.find(({ uid }: any) => uid == file.uid);
if (item) { if (item) {
item.progress = percent + "%"; item.progress = percent + "%";
} }
}, }
// //
refresh(params) { function refresh(params: any = {}) {
// //
this.clear(); clear();
this.loading = true; loading.value = true;
this.$service.space.info $service.space.info
.page({ .page({
...this.pagination, ...pagination,
...params, ...params,
classifyId: this.category.id, classifyId: category.id,
type: this.accept type: props.accept
}) })
.then((res) => { .then((res: any) => {
this.pagination = res.pagination; Object.assign(pagination, res.pagination);
this.list = res.list.map((e) => { list.value = res.list.map((e: any) => {
e.loading = false; return {
return e; ...e,
loading: false
};
}); });
}) })
.done(() => { .done(() => {
this.loading = false; loading.value = false;
}); });
}, }
// //
confirm() { function confirm() {
const urls = this.selection.map((e) => e.url).join(","); const urls = selection.value.map((e: any) => e.url).join(",");
this.$emit("update:modelValue", urls); emit("update:modelValue", urls);
this.$emit("confirm", this.detailData ? this.selection : urls); emit("confirm", props.detailData ? selection.value : urls);
this.close(); close();
}, }
// //
select(item) { function select(item: any) {
const index = this.selection.findIndex((e) => e.id === item.id); const index = selection.value.findIndex((e: any) => e.id === item.id);
if (index >= 0) { if (index >= 0) {
this.selection.splice(index, 1); selection.value.splice(index, 1);
} else { } else {
if (this.selection.length < this.limit) { if (selection.value.length < props.limit) {
this.selection.push(item); selection.value.push(item);
} }
} }
}, }
// //
remove(...selection) { function remove(item: any) {
if (isEmpty(selection)) {
selection = this.selection;
}
// id // id
const ids = selection.map((e) => e.id); const ids: number[] = item ? [item.id] : selection.value.map((e: any) => e.id);
this.$confirm("此操作将删除文件, 是否继续?", "提示", { ElMessageBox.confirm("此操作将删除文件, 是否继续?", "提示", {
type: "warning" type: "warning"
}) })
.then(() => { .then(() => {
this.$message.success("删除成功"); ElMessage.success("删除成功");
// //
ids.forEach((id) => { ids.forEach((id) => {
[this.list, this.selection].forEach((list) => { [list.value, selection.value].forEach((list) => {
const index = list.findIndex((e) => e.id === id); const index = list.findIndex((e: any) => e.id === id);
list.splice(index, 1); list.splice(index, 1);
}); });
}); });
// //
this.$service.space.info $service.space.info
.delete({ .delete({
ids ids
}) })
.catch((err) => { .catch((err: string) => {
this.$message.error(err); ElMessage.error(err);
}); });
}) })
.catch(() => null); .catch(() => null);
} }
//
function onCurrentChange(page: number) {
refresh({ page });
}
return {
visible,
loading,
selection,
list,
category,
pagination,
browser,
limitTip,
isSelected,
open,
close,
refresh,
remove,
confirm,
select,
onSuccess,
onError,
beforeUpload,
onProgress,
onCurrentChange
};
} }
}; });
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -1,13 +1,13 @@
import { onBeforeUpdate, ref } from "vue"; import { onBeforeUpdate, ref } from "vue";
export function useRefs() { export function useRefs() {
const refs = ref<HTMLElement[]>([]); const refs: any = ref<any[]>([]);
onBeforeUpdate(() => { onBeforeUpdate(() => {
refs.value = []; refs.value = [];
}); });
const setRefs = (index: number) => (el: HTMLElement) => { const setRefs = (index: string) => (el: any) => {
refs.value[index] = el; refs.value[index] = el;
}; };

View File

@ -10,6 +10,6 @@ async function bootstrap(app: any) {
SET_SERVICE(app); SET_SERVICE(app);
SET_MODULE(app); SET_MODULE(app);
router.$plugin.addViews(store.getters.routes); router.$plugin?.addViews(store.getters.routes);
} }
export { Service, Permission, BaseService, bootstrap, useRefs }; export { Service, Permission, BaseService, bootstrap, useRefs };

View File

@ -18,22 +18,14 @@ export default function (app: any) {
if (!error) { if (!error) {
local.push({ local.push({
name, name,
value: files[i].default, value: files[i].default
}); });
} }
} }
// 安装模块 // 安装模块
function install(mod: any) { function install(mod: any) {
const { const { store: _store, components, service, directives, pages, views, name } = mod;
store: _store,
components,
service,
directives,
pages,
views,
name,
} = mod;
try { try {
// 注册vuex模块 // 注册vuex模块
@ -82,7 +74,7 @@ export default function (app: any) {
} }
if (e.path) { if (e.path) {
router.$plugin.addViews([e]); router.$plugin?.addViews([e]);
} else { } else {
console.error(`[${name}-views]:缺少 path 参数`); console.error(`[${name}-views]:缺少 path 参数`);
} }
@ -104,7 +96,7 @@ export default function (app: any) {
// Parse // Parse
if (isString(e)) { if (isString(e)) {
mod = { mod = {
name: e, name: e
}; };
} else if (isObject(e)) { } else if (isObject(e)) {
mod = e; mod = e;
@ -112,7 +104,7 @@ export default function (app: any) {
mod = { mod = {
name: e[0], name: e[0],
value: e[1], value: e[1],
options: e[2], options: e[2]
}; };
} else { } else {
console.error(e, "格式错误"); console.error(e, "格式错误");
@ -144,7 +136,7 @@ export default function (app: any) {
mod = { mod = {
name: mod.name, name: mod.name,
options: mod.options || {}, options: mod.options || {},
...mod.value, ...mod.value
}; };
modules.push(mod); modules.push(mod);

12
src/core/types/index.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
import { Store } from "vuex";
import { Router } from "vue-router";
export declare class CoolStore<S> extends Store<S> {
$service?: any;
}
export declare interface CoolRouter extends Router {
$plugin?: {
addViews(list: any[], options?: any): void;
};
}

View File

@ -208,7 +208,7 @@ export function getBrowser() {
} }
export function href(path: string, newWindow?: boolean) { export function href(path: string, newWindow?: boolean) {
const { search, origin, pathname } = window.location; const { origin, pathname } = window.location;
if (pathname == path) { if (pathname == path) {
return false; return false;
@ -219,7 +219,7 @@ export function href(path: string, newWindow?: boolean) {
if (routerMode == "history") { if (routerMode == "history") {
url = origin + import.meta.env.BASE_URL + path.substr(1); url = origin + import.meta.env.BASE_URL + path.substr(1);
} else { } else {
url = origin + search + "#" + path; url = origin + import.meta.env.BASE_URL + "#" + path;
} }
if (newWindow) { if (newWindow) {
@ -237,9 +237,9 @@ export function deepTree(list: Array<any>) {
const newList: Array<any> = []; const newList: Array<any> = [];
const map: any = {}; const map: any = {};
list.forEach(e => (map[e.id] = e)); list.forEach((e) => (map[e.id] = e));
list.forEach(e => { list.forEach((e) => {
const parent = map[e.parentId]; const parent = map[e.parentId];
if (parent) { if (parent) {
@ -250,7 +250,7 @@ export function deepTree(list: Array<any>) {
}); });
const fn = (list: Array<any>) => { const fn = (list: Array<any>) => {
list.map(e => { list.map((e) => {
if (e.children instanceof Array) { if (e.children instanceof Array) {
e.children = orderBy(e.children, "orderNum"); e.children = orderBy(e.children, "orderNum");
@ -269,7 +269,7 @@ export function revDeepTree(list: Array<any> = []) {
let id = 0; let id = 0;
const deep = (list: Array<any>, parentId: any) => { const deep = (list: Array<any>, parentId: any) => {
list.forEach(e => { list.forEach((e) => {
if (!e.id) { if (!e.id) {
e.id = id++; e.id = id++;
} }

View File

@ -12,7 +12,7 @@ const clearReturn = /(\r)|(\n)/g;
function findSvgFile(dir: string): string[] { function findSvgFile(dir: string): string[] {
const svgRes = []; const svgRes = [];
const dirents = readdirSync(dir, { const dirents = readdirSync(dir, {
withFileTypes: true, withFileTypes: true
}); });
for (const dirent of dirents) { for (const dirent of dirents) {
if (dirent.isDirectory()) { if (dirent.isDirectory()) {
@ -21,10 +21,10 @@ function findSvgFile(dir: string): string[] {
const svg = readFileSync(dir + dirent.name) const svg = readFileSync(dir + dirent.name)
.toString() .toString()
.replace(clearReturn, "") .replace(clearReturn, "")
.replace(svgTitle, (_, $2) => { .replace(svgTitle, (_: any, $2: any) => {
let width = 0; let width = 0;
let height = 0; let height = 0;
let content = $2.replace(clearHeightWidth, (s1, s2, s3) => { let content = $2.replace(clearHeightWidth, (_: any, s2: any, s3: any) => {
if (s2 === "width") { if (s2 === "width") {
width = s3; width = s3;
} else if (s2 === "height") { } else if (s2 === "height") {
@ -47,7 +47,7 @@ function findSvgFile(dir: string): string[] {
return svgRes; return svgRes;
} }
export const svgBuilder = (path: string, perfix = "icon"): Plugin => { export const svgBuilder = (path: string, perfix = "icon"): Plugin | null => {
if (path !== "") { if (path !== "") {
idPerfix = perfix; idPerfix = perfix;
const res = findSvgFile(path); const res = findSvgFile(path);
@ -63,7 +63,9 @@ export const svgBuilder = (path: string, perfix = "icon"): Plugin => {
</svg> </svg>
` `
); );
}, }
}; };
} else {
return null;
} }
}; };

View File

@ -1,3 +1,4 @@
// @ts-nocheck
Promise.prototype.done = function (cb: Function) { Promise.prototype.done = function (cb: Function) {
const P: any = this.constructor; const P: any = this.constructor;

View File

@ -5,7 +5,7 @@ import { deepMerge, isBoolean, isEmpty, isFunction, isObject, isString } from ".
import Parse from "../../utils/parse"; import Parse from "../../utils/parse";
import { renderNode } from "../../utils/vnode"; import { renderNode } from "../../utils/vnode";
import { useAction } from "./helper"; import { useAction } from "./helper";
import { Browser } from "@/crud/types"; import { Browser } from "../../types";
export default defineComponent({ export default defineComponent({
name: "cl-form", name: "cl-form",

View File

@ -34,7 +34,7 @@
<el-dropdown trigger="click" :hide-on-click="false" @command="onCommand"> <el-dropdown trigger="click" :hide-on-click="false" @command="onCommand">
<span v-if="userInfo" class="el-dropdown-link"> <span v-if="userInfo" class="el-dropdown-link">
<span class="name">{{ userInfo.nickName }}</span> <span class="name">{{ userInfo.nickName }}</span>
<img class="avatar" :src="userInfo.headImg" alt /> <img class="avatar" :src="userInfo.headImg" />
</span> </span>
<template #dropdown> <template #dropdown>

View File

@ -1,4 +1,5 @@
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"; import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import { CoolRouter } from "/@/core/types";
// 忽略规则 // 忽略规则
const ignore: any = { const ignore: any = {
@ -28,7 +29,7 @@ const routes: Array<RouteRecordRaw> = [
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes routes
}); }) as CoolRouter;
export default router; export default router;
export { ignore }; export { ignore };

View File

@ -1,7 +1,8 @@
import { createStore } from "vuex"; import { createStore } from "vuex";
import { CoolStore } from "/@/core/types";
const store = createStore({ const store = createStore({
strict: true strict: true
}); }) as CoolStore<any>;
export default store; export default store;

View File

@ -7,6 +7,7 @@
"jsx": "preserve", "jsx": "preserve",
"sourceMap": true, "sourceMap": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"experimentalDecorators": true,
"esModuleInterop": true, "esModuleInterop": true,
"lib": ["esnext", "dom"], "lib": ["esnext", "dom"],
"types": ["vite/client", "vite-svg-loader"], "types": ["vite/client", "vite-svg-loader"],
@ -15,5 +16,6 @@
"/#/*": ["./types/*"] "/#/*": ["./types/*"]
} }
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules", "dist"]
} }

View File

@ -1,5 +1,5 @@
Arguments: Arguments:
D:\node\node.exe C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js add eslint-config-prettier -D D:\node\node.exe C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js remove @types/node
PATH: PATH:
C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64\compiler;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;D:\Tortoise\bin;C:\Program Files\Git\cmd;C:\Program Files\python;C:\Program Files\python\Scripts;;D:\BtSoft\panel\script;D:\node\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;D:\cool\Microsoft VS Code\bin;C:\Users\Administrator\AppData\Roaming\npm C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64\compiler;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;D:\Tortoise\bin;C:\Program Files\Git\cmd;C:\Program Files\python;C:\Program Files\python\Scripts;;D:\BtSoft\panel\script;D:\node\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;D:\cool\Microsoft VS Code\bin;C:\Users\Administrator\AppData\Roaming\npm
@ -14,29 +14,18 @@ Platform:
win32 x64 win32 x64
Trace: Trace:
Error: https://registry.yarnpkg.com/eslint-config-prettier%20-D: Not found Error: EPERM: operation not permitted, copyfile 'C:\Users\Administrator\AppData\Local\Yarn\Cache\v6\npm-yallist-2.1.2-1c11f9218f076089a47dd512f93c6699a6a81d52-integrity\node_modules\yallist\README.md' -> 'D:\cool\srcs\admin\front-next\node_modules\editorconfig\node_modules\yallist\README.md'
at Request.params.callback [as _callback] (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:66988:18)
at Request.self.callback (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:140662:22)
at Request.emit (events.js:315:20)
at Request.<anonymous> (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:141634:10)
at Request.emit (events.js:315:20)
at IncomingMessage.<anonymous> (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:141556:12)
at Object.onceWrapper (events.js:421:28)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
npm manifest: npm manifest:
{ {
"name": "front-next", "name": "front-next",
"version": "0.0.1", "version": "0.1.0",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vue-tsc --noEmit && vite build", "build": "vue-tsc --noEmit --skipLibCheck && vite build",
"serve": "vite preview", "serve": "vite preview",
"lint": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", "lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
"lint:ls": "ls-lint"
}, },
"dependencies": { "dependencies": {
"array.prototype.flat": "^1.2.4", "array.prototype.flat": "^1.2.4",
@ -70,6 +59,8 @@ npm manifest:
"@vitejs/plugin-vue-jsx": "^1.1.2", "@vitejs/plugin-vue-jsx": "^1.1.2",
"@vue/compiler-sfc": "^3.0.5", "@vue/compiler-sfc": "^3.0.5",
"eslint": "^7.23.0", "eslint": "^7.23.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.8.0", "eslint-plugin-vue": "^7.8.0",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"sass": "^1.32.8", "sass": "^1.32.8",
@ -387,6 +378,11 @@ Lockfile:
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/node@^14.14.37":
version "14.14.37"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e"
integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==
"@typescript-eslint/eslint-plugin@^4.20.0": "@typescript-eslint/eslint-plugin@^4.20.0":
version "4.20.0" version "4.20.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92"
@ -1338,6 +1334,18 @@ Lockfile:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
eslint-config-prettier@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.1.0.tgz#4ef1eaf97afe5176e6a75ddfb57c335121abc5a6"
integrity sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw==
eslint-plugin-prettier@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz#7079cfa2497078905011e6f82e8dd8453d1371b7"
integrity sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ==
dependencies:
prettier-linter-helpers "^1.0.0"
eslint-plugin-vue@^7.8.0: eslint-plugin-vue@^7.8.0:
version "7.8.0" version "7.8.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.8.0.tgz#cb0e85d65b65fa8d15e783fbb03c049d2c4cfdae" resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.8.0.tgz#cb0e85d65b65fa8d15e783fbb03c049d2c4cfdae"
@ -1535,6 +1543,11 @@ Lockfile:
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154"
integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig== integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==
fast-diff@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
fast-glob@^3.1.1: fast-glob@^3.1.1:
version "3.2.5" version "3.2.5"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
@ -2719,6 +2732,13 @@ Lockfile:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
prettier-linter-helpers@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
dependencies:
fast-diff "^1.1.2"
prettier@^2.2.1: prettier@^2.2.1:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5"

View File

@ -299,6 +299,16 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/lodash@^4.14.168":
version "4.14.168"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==
"@types/node@^14.14.37":
version "14.14.37"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e"
integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==
"@typescript-eslint/eslint-plugin@^4.20.0": "@typescript-eslint/eslint-plugin@^4.20.0":
version "4.20.0" version "4.20.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92"