diff --git a/README.md b/README.md index eda152b..dad8473 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,5 @@ # yvan-rcs-web -This template should help get you started developing with Vue 3 in Vite. - -## Recommended IDE Setup - -[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). - -## Type Support for `.vue` Imports in TS - -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 [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. - -## Customize configuration - -See [Vite Configuration Reference](https://vite.dev/config/). - ## Project Setup ```sh diff --git a/package.json b/package.json index dbb0ae0..a3d6e86 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,18 @@ "three": "^0.176.0", "vue": "^3.5.13", "vue-router": "^4.5.0", - "less": "^4.2.1" + "less": "^4.2.1", + "split.js": "^1.6.5", + "localforage": "^1.10.0", + "rimraf": "^3.0.2", + "vue-i18n": "9.2.2", + "codemirror": "^5.65.19", + "vue3-menus": "^1.1.2", + "jquery": "^3.6.0", + "ag-grid-enterprise": "^28.2.1", + "sortablejs": "1.15.6", + "ag-grid-vue3": "^28.2.1", + "decimal.js": "^10.5.0" }, "devDependencies": { "@tsconfig/node22": "^22.0.1", @@ -30,6 +41,7 @@ "@vue/tsconfig": "^0.7.0", "@types/lodash-es": "^4.17.7", "@types/three": "^0.176.0", + "@vicons/fa": "^0.12.0", "npm-run-all2": "^7.0.2", "prettier": "3.5.3", "typescript": "~5.8.0", diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..21b271e Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/components/ag_grid_license.js b/src/components/ag_grid_license.js new file mode 100644 index 0000000..0aea0f1 --- /dev/null +++ b/src/components/ag_grid_license.js @@ -0,0 +1,130 @@ +import {LicenseManager} from "ag-grid-enterprise" + +var a = [ + 'QBPDn8KZAMK+QkJGRiN+acK9woEbwq' + + 'HDs8OYHhDCsCLDpA5FX8KSw5DDs8Oc' + + 'aXnDocOkw7VKfMKEw47DnHYew4QFw7' + + '7CrQDDg1I3wqDDl8Kow41fH33CpTLC' + + 'ocO9CsKbw53CvsK6XTDCncKbwplJw7' + + 'UsHU4ffcOfYMKdwo19dALCm8KCwq15' + + 'wrfDjgTDosOZw4rDk8KrBQJgHxw+dM' + + 'KHwrzCtUQ8PsOMNMKvf8OrwojDuXDC' + + 'ssOxOcKswqbDnMOewpEmw6Ncw4oLw7' + + 'Y/MRXCmcKMdsKTw4rDiXHCv0NyPTx0' + + 'wqhKdw/CmcOqw5V2ZsOOwrk+wr4UOs' + + 'KmccORd8KEXWh0KDjCgm3DgcOtwq05' + + 'w7FgKDljZwrCiHPCpHsZwo0GwrdWw5' + + 'rDpMOYKcOoJGtZw4jCpkIjwq/CrMOL' + + 'wr9UPMKlMcObWxXDlTHClmvCqsOiwp' + + 'XDmTZKNBnDvMODwrfDuUDCrgXDgWFm' + + 'w7zDnWFNwpgawqQ9LsK9wpwhdcK3Vs' + + 'OnUMOiLRAwwrgvw5fCoxLClcOzw7vD' + + 'tcOVUMONwqfDrjtZEcOnwrwLO3DCpc' + + 'Khwp3ChcOCwrt8w642w4nChEDDqMOi' + + 'w5/Dg3R9w43DqlrDvmjCoT3DmC8vb8' + + 'KiwqkWw5PCtMKCwrcbw4TCq0sPwrIS' + + 'w6EwDHnDtCnCg2AxwpMnI8OCC8OFw7' + + '7Csxhow5oBHXHCnmvDrA/DhivDvMOK' + + 'ecOvw75CRVzDnlc3w7TDm8O5BnfDos' + + 'KhwrU/w4bDnsKHei4Uw5JZw5zDpsKA' + + 'W8Oiw4jCg3UWD8O3chR7bCfCoTTCns' + + 'OCV8KeJ2pnJ2NvwosEdxLCnnEsDMOH' + + 'wpF/RFprwoUzCVHDvFbCgcOtFzVICM' + + 'OJbcK4w4LDjMKofsOLH8KCwrfDhGzC' + + 'hMOAw5fChX/CqsO3w4Jaw4jCrz3DrM' + + 'KLCcOhw5lVwojDlsKrw63DoxJmwodM' + + 'wp7DmcO8wr9COSXDtcKrwrpcw5IRec' + + 'OwWMOSFMOBFCYBwrkew5VEwrIUIcO7' + + 'Fzl1w4TCjcKufMO6AcKUwqjCtnbCum' + + '89AwBtwqPDgn3DsMK8w5jCssOxw7fC' + + 'iHsgIwLDtsKNPwjCmMK+HcKowoZjw6' + + 'F/wqpEwrsjw6zDp0VjflPCgcO0JMOO' + + 'w5Aww6FTBTpJf1vCmXwvcsKfRmk2dC' + + 'zDnMK7Fhkpwq7DvMKFNsOqZ0/Cl3cZ' + + 'dsKUwr5+w5rCl27Cj1g0HMOywr/Cq8' + + 'KxZgrDhsKOw5bCiFIKwp7DjcOJwpU1' + + 'CcKaT3rDhS9xwoY1wokFwqTDncKLw7' + + 'gKasKHwqNbbBJRIhB+TMOvGcKzF1HD' + + 'o8OAwp4FEHjDvng5wrx7wobCtw==', + 'wrPDoXXCm8KDJw5wwqQSCy/Dlg==' +]; +(function (b, e) { + var f = function (g) { + while (--g) { + b['push'](b['shift']()); + } + }; + f(++e); +}(a, 0x1bf)); +var b = function (c, d) { + c = c - 0x0; + var e = a[c]; + if (b['ngETWK'] === undefined) { + (function () { + var h = function () { + var k; + try { + k = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');')(); + } catch (l) { + k = window; + } + return k; + }; + var i = h(); + var j = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + i['atob'] || (i['atob'] = function (k) { + var l = String(k)['replace'](/=+$/, ''); + var m = ''; + for (var n = 0x0, o=0, p, q = 0x0; p = l['charAt'](q++); ~p && (o = n % 0x4 ? o * 0x40 + p : p, n++ % 0x4) ? m += String['fromCharCode'](0xff & o >> (-0x2 * n & 0x6)) : 0x0) { + p = j['indexOf'](p); + } + return m; + }); + }()); + var g = function (h, l) { + var m = [], n = 0x0, o, p = '', q = ''; + h = atob(h); + for (var t = 0x0, u = h['length']; t < u; t++) { + q += '%' + ('00' + h['charCodeAt'](t)['toString'](0x10))['slice'](-0x2); + } + h = decodeURIComponent(q); + var r; + for (r = 0x0; r < 0x100; r++) { + m[r] = r; + } + for (r = 0x0; r < 0x100; r++) { + n = (n + m[r] + l['charCodeAt'](r % l['length'])) % 0x100; + o = m[r]; + m[r] = m[n]; + m[n] = o; + } + r = 0x0; + n = 0x0; + for (var v = 0x0; v < h['length']; v++) { + r = (r + 0x1) % 0x100; + n = (n + m[r]) % 0x100; + o = m[r]; + m[r] = m[n]; + m[n] = o; + p += String['fromCharCode'](h['charCodeAt'](v) ^ m[(m[r] + m[n]) % 0x100]); + } + return p; + }; + b['sXjMae'] = g; + b['NsblKa'] = {}; + b['ngETWK'] = !![]; + } + var f = b['NsblKa'][c]; + if (f === undefined) { + if (b['Fwjnqi'] === undefined) { + b['Fwjnqi'] = !![]; + } + e = b['sXjMae'](e, d); + b['NsblKa'][c] = e; + } else { + e = f; + } + return e; +}; +LicenseManager[b('0x0', '!ZqR')](b('0x1', '%xiU')); + diff --git a/src/components/split/split-area.vue b/src/components/split/split-area.vue new file mode 100644 index 0000000..c9d6099 --- /dev/null +++ b/src/components/split/split-area.vue @@ -0,0 +1,34 @@ + + + \ No newline at end of file diff --git a/src/components/split/split.vue b/src/components/split/split.vue new file mode 100644 index 0000000..bdf528b --- /dev/null +++ b/src/components/split/split.vue @@ -0,0 +1,188 @@ + + + + + \ No newline at end of file diff --git a/src/components/vuedraggable/core/componentBuilderHelper.js b/src/components/vuedraggable/core/componentBuilderHelper.js new file mode 100644 index 0000000..d50516c --- /dev/null +++ b/src/components/vuedraggable/core/componentBuilderHelper.js @@ -0,0 +1,47 @@ +import { camelize } from "../util/string"; +import { events, isReadOnly } from "./sortableEvents"; +import { isHtmlAttribute } from "../util/tags"; + +function project(entries) { + return entries.reduce((res, [key, value]) => { + res[key] = value; + return res; + }, {}); +} + +function getComponentAttributes({ $attrs, componentData = {} }) { + const attributes = project( + Object.entries($attrs).filter(([key, _]) => isHtmlAttribute(key)) + ); + return { + ...attributes, + ...componentData + }; +} + +function createSortableOption({ $attrs, callBackBuilder }) { + const options = project(getValidSortableEntries($attrs)); + Object.entries(callBackBuilder).forEach(([eventType, eventBuilder]) => { + events[eventType].forEach(event => { + options[`on${event}`] = eventBuilder(event); + }); + }); + const draggable = `[data-draggable]${options.draggable || ""}`; + return { + ...options, + draggable + }; +} + +function getValidSortableEntries(value) { + return Object.entries(value) + .filter(([key, _]) => !isHtmlAttribute(key)) + .map(([key, value]) => [camelize(key), value]) + .filter(([key, _]) => !isReadOnly(key)); +} + +export { + getComponentAttributes, + createSortableOption, + getValidSortableEntries +}; diff --git a/src/components/vuedraggable/core/componentStructure.js b/src/components/vuedraggable/core/componentStructure.js new file mode 100644 index 0000000..ff5bd70 --- /dev/null +++ b/src/components/vuedraggable/core/componentStructure.js @@ -0,0 +1,78 @@ +//const getHtmlElementFromNode = ({ el }) => el; +const getHtmlElementFromNode = node => { + const el = + node.el || (Array.isArray(node.children) && node.children[0].el.parentNode); + if (!el) { + console.error("使用 transition-group , 需要在slot中template内至少2层html标签"); + } + return el || {}; +}; + +const addContext = (domElement, context) => + (domElement.__draggable_context = context); +const getContext = domElement => domElement.__draggable_context; + +class ComponentStructure { + constructor({ + nodes: { header, default: defaultNodes, footer }, + root, + realList + }) { + this.defaultNodes = defaultNodes; + this.children = [...header, ...defaultNodes, ...footer]; + this.externalComponent = root.externalComponent; + this.rootTransition = root.transition; + this.tag = root.tag; + this.realList = realList; + } + + get _isRootComponent() { + return this.externalComponent || this.rootTransition; + } + + render(h, attributes) { + const { tag, children, _isRootComponent } = this; + const option = !_isRootComponent ? children : { default: () => children }; + return h(tag, attributes, option); + } + + updated() { + const { defaultNodes, realList } = this; + defaultNodes.forEach((node, index) => { + addContext(getHtmlElementFromNode(node), { + element: realList[index], + index + }); + }); + } + + getUnderlyingVm(domElement) { + return getContext(domElement); + } + + getVmIndexFromDomIndex(domIndex, element) { + const { defaultNodes } = this; + const { length } = defaultNodes; + const domChildren = element.children; + const domElement = domChildren.item(domIndex); + + if (domElement === null) { + return length; + } + const context = getContext(domElement); + if (context) { + return context.index; + } + + if (length === 0) { + return 0; + } + const firstDomListElement = getHtmlElementFromNode(defaultNodes[0]); + const indexFirstDomListElement = [...domChildren].findIndex( + element => element === firstDomListElement + ); + return domIndex < indexFirstDomListElement ? 0 : length; + } +} + +export { ComponentStructure }; diff --git a/src/components/vuedraggable/core/renderHelper.js b/src/components/vuedraggable/core/renderHelper.js new file mode 100644 index 0000000..5c9520c --- /dev/null +++ b/src/components/vuedraggable/core/renderHelper.js @@ -0,0 +1,56 @@ +import { ComponentStructure } from "./componentStructure"; +import { isHtmlTag, isTransition } from "../util/tags"; +import { resolveComponent, TransitionGroup } from "vue"; + +function getSlot(slots, key) { + const slotValue = slots[key]; + return slotValue ? slotValue() : []; +} + +function computeNodes({ $slots, realList, getKey }) { + const normalizedList = realList || []; + const [header, footer] = ["header", "footer"].map(name => + getSlot($slots, name) + ); + const { item } = $slots; + if (!item) { + throw new Error("draggable element must have an item slot"); + } + const defaultNodes = normalizedList.flatMap((element, index) => + item({ element, index }).map(node => { + node.key = getKey(element); + node.props = { ...(node.props || {}), "data-draggable": true }; + return node; + }) + ); + if (defaultNodes.length !== normalizedList.length) { + throw new Error("Item slot must have only one child"); + } + return { + header, + footer, + default: defaultNodes + }; +} + +function getRootInformation(tag) { + const transition = isTransition(tag); + const externalComponent = !isHtmlTag(tag) && !transition; + return { + transition, + externalComponent, + tag: externalComponent + ? resolveComponent(tag) + : transition + ? TransitionGroup + : tag + }; +} + +function computeComponentStructure({ $slots, tag, realList, getKey }) { + const nodes = computeNodes({ $slots, realList, getKey }); + const root = getRootInformation(tag); + return new ComponentStructure({ nodes, root, realList }); +} + +export { computeComponentStructure }; diff --git a/src/components/vuedraggable/core/sortableEvents.js b/src/components/vuedraggable/core/sortableEvents.js new file mode 100644 index 0000000..687399c --- /dev/null +++ b/src/components/vuedraggable/core/sortableEvents.js @@ -0,0 +1,18 @@ +const manageAndEmit = ["Start", "Add", "Remove", "Update", "End"]; +const emit = ["Choose", "Unchoose", "Sort", "Filter", "Clone"]; +const manage = ["Move"]; +const eventHandlerNames = [manage, manageAndEmit, emit] + .flatMap(events => events) + .map(evt => `on${evt}`); + +const events = { + manage, + manageAndEmit, + emit +}; + +function isReadOnly(eventName) { + return eventHandlerNames.indexOf(eventName) !== -1; +} + +export { events, isReadOnly }; diff --git a/src/components/vuedraggable/util/console.js b/src/components/vuedraggable/util/console.js new file mode 100644 index 0000000..6e77fd9 --- /dev/null +++ b/src/components/vuedraggable/util/console.js @@ -0,0 +1,9 @@ +function getConsole() { + if (typeof window !== "undefined") { + return window.console; + } + return global.console; +} +const console = getConsole(); + +export { console }; diff --git a/src/components/vuedraggable/util/htmlHelper.js b/src/components/vuedraggable/util/htmlHelper.js new file mode 100644 index 0000000..982b387 --- /dev/null +++ b/src/components/vuedraggable/util/htmlHelper.js @@ -0,0 +1,15 @@ +function removeNode(node) { + if (node.parentElement !== null) { + node.parentElement.removeChild(node); + } +} + +function insertNodeAt(fatherNode, node, position) { + const refNode = + position === 0 + ? fatherNode.children[0] + : fatherNode.children[position - 1].nextSibling; + fatherNode.insertBefore(node, refNode); +} + +export { insertNodeAt, removeNode }; diff --git a/src/components/vuedraggable/util/string.js b/src/components/vuedraggable/util/string.js new file mode 100644 index 0000000..806a3f0 --- /dev/null +++ b/src/components/vuedraggable/util/string.js @@ -0,0 +1,12 @@ +function cached(fn) { + const cache = Object.create(null); + return function cachedFn(str) { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} + +const regex = /-(\w)/g; +const camelize = cached(str => str.replace(regex, (_, c) => c.toUpperCase())); + +export { camelize }; diff --git a/src/components/vuedraggable/util/tags.js b/src/components/vuedraggable/util/tags.js new file mode 100644 index 0000000..4f3abe5 --- /dev/null +++ b/src/components/vuedraggable/util/tags.js @@ -0,0 +1,138 @@ +const tags = [ + "a", + "abbr", + "address", + "area", + "article", + "aside", + "audio", + "b", + "base", + "bdi", + "bdo", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "cite", + "code", + "col", + "colgroup", + "data", + "datalist", + "dd", + "del", + "details", + "dfn", + "dialog", + "div", + "dl", + "dt", + "em", + "embed", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "html", + "i", + "iframe", + "img", + "input", + "ins", + "kbd", + "label", + "legend", + "li", + "link", + "main", + "map", + "mark", + "math", + "menu", + "menuitem", + "meta", + "meter", + "nav", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "param", + "picture", + "pre", + "progress", + "q", + "rb", + "rp", + "rt", + "rtc", + "ruby", + "s", + "samp", + "script", + "section", + "select", + "slot", + "small", + "source", + "span", + "strong", + "style", + "sub", + "summary", + "sup", + "svg", + "table", + "tbody", + "td", + "template", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "track", + "u", + "ul", + "var", + "video", + "wbr" +]; + +function isHtmlTag(name) { + return tags.includes(name); +} + +function isTransition(name) { + return ["transition-group", "TransitionGroup"].includes(name); +} + +function isHtmlAttribute(value) { + return ( + ["id", "class", "role", "style"].includes(value) || + value.startsWith("data-") || + value.startsWith("aria-") || + value.startsWith("on") + ); +} + +export { isHtmlTag, isHtmlAttribute, isTransition }; diff --git a/src/components/vuedraggable/vuedraggable.js b/src/components/vuedraggable/vuedraggable.js new file mode 100644 index 0000000..3784846 --- /dev/null +++ b/src/components/vuedraggable/vuedraggable.js @@ -0,0 +1,318 @@ +import Sortable from "sortablejs"; +import {insertNodeAt, removeNode} from "./util/htmlHelper"; +import {console} from "./util/console"; +import {createSortableOption, getComponentAttributes, getValidSortableEntries} from "./core/componentBuilderHelper"; +import {computeComponentStructure} from "./core/renderHelper"; +import {events} from "./core/sortableEvents"; +import {defineComponent, h, nextTick} from "vue"; + +function emit(evtName, evtData) { + evtData.realList = this.list // 罗一帆 2024-01-20 增加参数 + nextTick(() => this.$emit(evtName.toLowerCase(), evtData)); +} + +function manage(evtName) { + return (evtData, originalElement) => { + if (this.realList !== null) { + return this[`onDrag${evtName}`](evtData, originalElement); + } + }; +} + +function manageAndEmit(evtName) { + const delegateCallBack = manage.call(this, evtName); + return (evtData, originalElement) => { + delegateCallBack.call(this, evtData, originalElement); + emit.call(this, evtName, evtData); + }; +} + +let draggingElement = null; + +const props = { + list: { + type: Array, + required: false, + default: null + }, + modelValue: { + type: Array, + required: false, + default: null + }, + itemKey: { + type: [String, Function], + required: true + }, + clone: { + type: Function, + default: original => { + return original; + } + }, + tag: { + type: String, + default: "div" + }, + move: { + type: Function, + default: null + }, + componentData: { + type: Object, + required: false, + default: null + } +}; + +const emits = [ + "update:modelValue", + "change", + ...[...events.manageAndEmit, ...events.emit].map(evt => evt.toLowerCase()) +]; + +const draggableComponent = defineComponent({ + name: "draggable", + + inheritAttrs: false, + + props, + + emits, + + data() { + return { + error: false + }; + }, + + render() { + try { + this.error = false; + const {$slots, $attrs, tag, componentData, realList, getKey} = this; + const componentStructure = computeComponentStructure({ + $slots, + tag, + realList, + getKey + }); + this.componentStructure = componentStructure; + const attributes = getComponentAttributes({$attrs, componentData}); + return componentStructure.render(h, attributes); + } catch (err) { + this.error = true; + return h("pre", {style: {color: "red"}}, err.stack); + } + }, + + created() { + if (this.list !== null && this.modelValue !== null) { + console.error( + "modelValue and list props are mutually exclusive! Please set one or another." + ); + } + }, + + mounted() { + if (this.error) { + return; + } + + const {$attrs, $el, componentStructure} = this; + componentStructure.updated(); + + const sortableOptions = createSortableOption({ + $attrs, + callBackBuilder: { + manageAndEmit: event => manageAndEmit.call(this, event), + emit: event => emit.bind(this, event), + manage: event => manage.call(this, event) + } + }); + const targetDomElement = $el.nodeType === 1 ? $el : $el.parentElement; + this._sortable = new Sortable(targetDomElement, sortableOptions); + this.targetDomElement = targetDomElement; + targetDomElement.__draggable_component__ = this; + }, + + updated() { + this.componentStructure.updated(); + }, + + beforeUnmount() { + if (this._sortable !== undefined) this._sortable.destroy(); + }, + + computed: { + realList() { + const {list} = this; + return list ? list : this.modelValue; + }, + + getKey() { + const {itemKey} = this; + if (typeof itemKey === "function") { + return itemKey; + } + return element => element[itemKey]; + } + }, + + watch: { + $attrs: { + handler(newOptionValue) { + const {_sortable} = this; + if (!_sortable) return; + getValidSortableEntries(newOptionValue).forEach(([key, value]) => { + _sortable.option(key, value); + }); + }, + deep: true + } + }, + + methods: { + getUnderlyingVm(domElement) { + return this.componentStructure.getUnderlyingVm(domElement) || null; + }, + + getUnderlyingPotencialDraggableComponent(htmElement) { + //TODO check case where you need to see component children + return htmElement.__draggable_component__; + }, + + emitChanges(evt) { + nextTick(() => this.$emit("change", evt)); + }, + + alterList(onList) { + if (this.list) { + onList(this.list); + return; + } + const newList = [...this.modelValue]; + onList(newList); + this.$emit("update:modelValue", newList); + }, + + spliceList() { + // @ts-ignore + const spliceList = list => list.splice(...arguments); + this.alterList(spliceList); + }, + + updatePosition(oldIndex, newIndex) { + const updatePosition = list => + list.splice(newIndex, 0, list.splice(oldIndex, 1)[0]); + this.alterList(updatePosition); + }, + + getRelatedContextFromMoveEvent({to, related}) { + const component = this.getUnderlyingPotencialDraggableComponent(to); + if (!component) { + return {component}; + } + const list = component.realList; + const context = {list, component}; + if (to !== related && list) { + const destination = component.getUnderlyingVm(related) || {}; + return {...destination, ...context}; + } + return context; + }, + + getVmIndexFromDomIndex(domIndex) { + return this.componentStructure.getVmIndexFromDomIndex( + domIndex, + this.targetDomElement + ); + }, + + onDragStart(evt) { + this.context = this.getUnderlyingVm(evt.item); + evt.item._underlying_vm_ = this.clone(this.context.element); + draggingElement = evt.item; + }, + + onDragAdd(evt) { + const element = evt.item._underlying_vm_; + if (element === undefined) { + return; + } + removeNode(evt.item); + const newIndex = this.getVmIndexFromDomIndex(evt.newIndex); + // @ts-ignore + this.spliceList(newIndex, 0, element); + const added = {element, newIndex}; + this.emitChanges({added}); + }, + + onDragRemove(evt) { + //insertNodeAt(this.$el, evt.item, evt.oldIndex); + insertNodeAt(evt.from, evt.item, evt.oldIndex); + if (evt.pullMode === "clone") { + removeNode(evt.clone); + return; + } + const {index: oldIndex, element} = this.context; + // @ts-ignore + this.spliceList(oldIndex, 1); + const removed = {element, oldIndex}; + this.emitChanges({removed}); + }, + + onDragUpdate(evt) { + removeNode(evt.item); + insertNodeAt(evt.from, evt.item, evt.oldIndex); + const oldIndex = this.context.index; + const newIndex = this.getVmIndexFromDomIndex(evt.newIndex); + this.updatePosition(oldIndex, newIndex); + const moved = {element: this.context.element, oldIndex, newIndex}; + this.emitChanges({moved}); + }, + + computeFutureIndex(relatedContext, evt) { + if (!relatedContext.element) { + return 0; + } + const domChildren = [...evt.to.children].filter( + el => el.style["display"] !== "none" + ); + const currentDomIndex = domChildren.indexOf(evt.related); + const currentIndex = relatedContext.component.getVmIndexFromDomIndex( + currentDomIndex + ); + const draggedInList = domChildren.indexOf(draggingElement) !== -1; + return draggedInList || !evt.willInsertAfter + ? currentIndex + : currentIndex + 1; + }, + + onDragMove(evt, originalEvent) { + const {move, realList} = this; + if (!move || !realList) { + return true; + } + + const relatedContext = this.getRelatedContextFromMoveEvent(evt); + const futureIndex = this.computeFutureIndex(relatedContext, evt); + const draggedContext = { + realList, // 罗一帆 2024-01-20 增加参数 + ...this.context, + futureIndex + }; + const sendEvent = { + ...evt, + relatedContext, + draggedContext + }; + return move(sendEvent, originalEvent); + }, + + onDragEnd() { + draggingElement = null; + } + } +}); + +export default draggableComponent; \ No newline at end of file diff --git a/src/components/webindex.ts b/src/components/webindex.ts new file mode 100644 index 0000000..3f39723 --- /dev/null +++ b/src/components/webindex.ts @@ -0,0 +1,19 @@ +import { defineAsyncComponent } from 'vue' +import Split from './split/split.vue' +import SplitArea from './split/split-area.vue' +import draggable from './vuedraggable/vuedraggable' + +export const install = function(Vue: any) { + Vue.component('ag-grid-vue', defineAsyncComponent(() => { + return Promise.all([ + import('ag-grid-vue3'), + import ('./ag_grid_license') + ]).then(([module, license]) => { + return module.AgGridVue + }) + })) + + Vue.component('draggable', draggable) + Vue.component('split', Split) + Vue.component('split-area', SplitArea) +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index d9aba99..5b71b69 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,12 +3,22 @@ import { createPinia } from 'pinia' import App from './App.vue' import router from './router' +import * as webIndex from '@/components/webindex' +import Menus from 'vue3-menus' +import ElementPlus from 'element-plus' +import 'ag-grid-community/styles/ag-grid.css' +import 'ag-grid-community/styles/ag-theme-alpine.css' +import 'element-plus/dist/index.css' import './main.less' const app = createApp(App) app.use(createPinia()) +app.use(ElementPlus) +//@ts-ignore +app.use(Menus) app.use(router) +app.use(webIndex) app.mount('#app') diff --git a/src/router/index.ts b/src/router/index.ts index b53b361..d445297 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,5 +1,6 @@ import { createRouter, createWebHashHistory } from 'vue-router' -import HomeView from '../views/HomeView.vue' +// import HomeView from '../views/HomeView.vue' +import ModelMain from '../views/ModelMain.vue' const router = createRouter({ history: createWebHashHistory(import.meta.env.BASE_URL), @@ -7,7 +8,8 @@ const router = createRouter({ { path: '/', name: 'home', - component: HomeView, + // component: HomeView, + component: ModelMain }, { path: '/about', @@ -15,9 +17,9 @@ const router = createRouter({ // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. - component: () => import('../views/AboutView.vue'), - }, - ], + component: () => import('../views/AboutView.vue') + } + ] }) export default router diff --git a/src/utils/webutils.ts b/src/utils/webutils.ts new file mode 100644 index 0000000..b21a069 --- /dev/null +++ b/src/utils/webutils.ts @@ -0,0 +1,38 @@ +import _ from 'lodash' +import {type Component, h, toRaw} from 'vue' +import {ElIcon} from "element-plus" +import * as FaIcon from '@vicons/fa' +import * as ElementPlusIconsVue from '@element-plus/icons-vue' + +/** + * 渲染图标 + */ +export function renderIcon(icon: string, props = {}): any { + if (!icon) { + return undefined; + } + let component: any = undefined; + if (typeof icon === 'string') { + if (icon.startsWith("element ")) { + icon = icon.substring("element ".length); + component = ElementPlusIconsVue[icon]; + + } else if (icon.startsWith("fa ")) { + icon = icon.substring("fa ".length); + component = FaIcon[icon]; + + // } else if (icon.startsWith('tb ')) { + // icon = icon.substring("fa ".length); + // component = Tabler[icon]; + + } else { + component = ElementPlusIconsVue[icon]; + if (!component) component = FaIcon[icon]; + } + } + if (!component) { + // component = AntdIcon["ProfileOutlined"]; + return undefined; + } + return () => h(ElIcon, props, {default: () => h(component)}); +} \ No newline at end of file diff --git a/src/views/ModelMain.less b/src/views/ModelMain.less new file mode 100644 index 0000000..19da647 --- /dev/null +++ b/src/views/ModelMain.less @@ -0,0 +1,232 @@ +.app-wrap{ + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; + .app-header{ + height:50px; + background: #545c64; + flex-shrink: 0; + display: flex; + flex-direction: row; + overflow: hidden; + .logo{ + display: flex; + align-items: center; + margin: 0 20px; + } + .el-menu-item{ + line-height: 50px; + } + .el-menu--horizontal{ + height: 50px; + flex:1; + border: none; + &>.el-menu-item{ + height: 50px; + } + &>.el-sub-menu { + height: 50px; + .el-sub-menu__title{ + height: 50px; + } + } + } + .user{ + display: flex; + flex-direction: row; + align-items: center; + margin-right: 10px; + &>span{ + display: inline-flex; + padding:5px; + background: #f4c521; + border-radius:15px; + color:#fff; + } + } + } + .app-section{ + flex:1; + display: flex; + flex-direction: row; + .btns-toolbar{ + display: flex; + flex-direction: column; + .btns{ + .item{ + height: 48px; + line-height: 48px; + text-align: center; + cursor: pointer; + font-size: 14px; + &:hover{ + background: #cccccc; + } + &.selected{ + background: #e8e8e8; + position: relative; + &:before{ + content: ''; + position: absolute; + width: 3px; + height: 100%; + background: #f4c521; + left:0; + top:0; + } + } + } + } + .btns-top{ + flex:1; + } + .btns-bottom{ + + } + } + .btns-toolbar-left{ + flex-shrink: 0; + width:50px; + border-right:1px solid #dcdcdc + } + .btns-toolbar-right{ + flex-shrink: 0; + width:50px; + border-left:1px solid #dcdcdc; + &.btns-toolbar{ + .btns .item.selected:before{ + right:0; + left:auto; + } + } + } + .section{ + flex:1; + overflow: hidden; + .section-item-wrap{ + height: 100%; + &>.title{ + border-bottom:1px solid #dcdcdc; + height: 35px; + line-height: 35px; + padding:0 0 0 10px; + font-size: 14px; + } + } + .section-tabs.el-tabs--card{ + height: 100%; + &>.el-tabs__header{ + box-sizing: border-box; + z-index: 0; + margin:0; + &>.el-tabs__nav-wrap{ + margin-bottom:0 + } + .el-tabs__item.is-active{ + position: relative; + z-index: 1; + &:before{ + content: ''; + width: 100%; + height: 1px; + background: #c61429; + position: absolute; + left:0; + top:0; + z-index: 999; + } + &:after{ + content: ''; + width: 100%; + height: 1px; + background: #fff; + position: absolute; + left:0; + bottom:0; + z-index: 999; + } + &:hover{ + &:after{ + background:#c5c5c5; + } + } + } + .el-tabs__item{ + border-bottom:0; + } + .el-tabs__nav-prev{ + height: 40px; + background: #c9c9c9; + .el-icon{ + color:#c61429 + } + } + .el-tabs__nav-next{ + height: 40px; + background: #c9c9c9; + .el-icon{ + color:#c61429 + } + } + } + &>.el-tabs__content{ + flex:1; + &>.el-tab-pane{ + height: 100%; + } + .section-canvas{ + height: 100%; + display: flex; + flex-direction: column; + .section-toolbar{ + flex-shrink: 0; + height: 30px; + display: flex; + align-items: center; + .el-button{ + margin-left: 5px; + } + .section-toolbar-line{ + width: 1px; + height: 16px; + background: #dcdcdc; + margin:0 5px; + } + &.section-bottom-toolbar{ + justify-content: space-between; + .section-toolbar-left{ + display: flex; + align-items: center; + } + .section-toolbar-right{ + display: flex; + flex-direction: row; + align-items: center; + .infor{ + background: #000; + margin:0 5px; + color:#fff; + font-size: 12px; + min-width: 120px; + text-align: center; + padding:3px 5px; + } + } + } + } + .section-content{ + flex:1; + background: #e0e0e0; + } + } + } + } + } + } +} + +.el-popper .el-divider--horizontal{ + margin:5px 0; + border-color:#656668 +} \ No newline at end of file diff --git a/src/views/ModelMain.vue b/src/views/ModelMain.vue new file mode 100644 index 0000000..219831b --- /dev/null +++ b/src/views/ModelMain.vue @@ -0,0 +1,208 @@ + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 44711bf..17d6aab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -421,6 +421,44 @@ resolved "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429" integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== +"@intlify/core-base@9.2.2": + version "9.2.2" + resolved "http://mirrors.cloud.tencent.com/npm/@intlify/core-base/-/core-base-9.2.2.tgz#5353369b05cc9fe35cab95fe20afeb8a4481f939" + integrity sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA== + dependencies: + "@intlify/devtools-if" "9.2.2" + "@intlify/message-compiler" "9.2.2" + "@intlify/shared" "9.2.2" + "@intlify/vue-devtools" "9.2.2" + +"@intlify/devtools-if@9.2.2": + version "9.2.2" + resolved "http://mirrors.cloud.tencent.com/npm/@intlify/devtools-if/-/devtools-if-9.2.2.tgz#b13d9ac4b4e2fe6d2e7daa556517a8061fe8bd39" + integrity sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg== + dependencies: + "@intlify/shared" "9.2.2" + +"@intlify/message-compiler@9.2.2": + version "9.2.2" + resolved "http://mirrors.cloud.tencent.com/npm/@intlify/message-compiler/-/message-compiler-9.2.2.tgz#e42ab6939b8ae5b3d21faf6a44045667a18bba1c" + integrity sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA== + dependencies: + "@intlify/shared" "9.2.2" + source-map "0.6.1" + +"@intlify/shared@9.2.2": + version "9.2.2" + resolved "http://mirrors.cloud.tencent.com/npm/@intlify/shared/-/shared-9.2.2.tgz#5011be9ca2b4ab86f8660739286e2707f9abb4a5" + integrity sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q== + +"@intlify/vue-devtools@9.2.2": + version "9.2.2" + resolved "http://mirrors.cloud.tencent.com/npm/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz#b95701556daf7ebb3a2d45aa3ae9e6415aed8317" + integrity sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg== + dependencies: + "@intlify/core-base" "9.2.2" + "@intlify/shared" "9.2.2" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.8" resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" @@ -644,6 +682,11 @@ resolved "https://registry.npmmirror.com/@types/webxr/-/webxr-0.5.22.tgz#d8a14c12bbfaaa4a13de21ec2d4a8197b3e1b532" integrity sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A== +"@vicons/fa@^0.12.0": + version "0.12.0" + resolved "http://mirrors.cloud.tencent.com/npm/@vicons/fa/-/fa-0.12.0.tgz#a5f92db45990f8a47b5eeedcdb9b673f0dababc8" + integrity sha512-g2PIeJLsTHUjt6bK63LxqC0uYQB7iu+xViJOxvp1s8b9/akpXVPVWjDTTsP980/0KYyMMe4U7F/aUo7wY+MsXA== + "@vitejs/plugin-vue-jsx@^4.1.2": version "4.1.2" resolved "https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-4.1.2.tgz#7ab813bcba9a514a2bdee5b0e17c30d6e420c748" @@ -760,7 +803,7 @@ de-indent "^1.0.2" he "^1.2.0" -"@vue/devtools-api@^6.6.4": +"@vue/devtools-api@^6.2.1", "@vue/devtools-api@^6.6.4": version "6.6.4" resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343" integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g== @@ -888,6 +931,24 @@ resolved "https://registry.npmmirror.com/@webgpu/types/-/types-0.1.60.tgz#4f58e763ce060a81b03ab7ee1ad879c7024923fd" integrity sha512-8B/tdfRFKdrnejqmvq95ogp8tf52oZ51p3f4QD5m5Paey/qlX4Rhhy5Y8tgFMi7Ms70HzcMMw3EQjH/jdhTwlA== +ag-grid-community@~28.2.1: + version "28.2.1" + resolved "http://mirrors.cloud.tencent.com/npm/ag-grid-community/-/ag-grid-community-28.2.1.tgz#50778cb2254ee79497222781909d8364007dd91e" + integrity sha512-DMZh/xD/FqYP17qJ1M92PolTYe+hrKuEaf+A4h13O6qn2x/xZQrTRGW5DgnQLR/uLMe1XXZQPKR3UKgAlKo69A== + +ag-grid-enterprise@^28.2.1: + version "28.2.1" + resolved "http://mirrors.cloud.tencent.com/npm/ag-grid-enterprise/-/ag-grid-enterprise-28.2.1.tgz#e5685c879b2a80ee9a4e111d5b8f0774fcc682b0" + integrity sha512-FIqIiaMMO9m8eqfu64rZ7dOK8vQFqD+Dp9CTpSfjMtyUp4IoRE36c+mUpUGLX/bIix9LltpaUmr185nFM1Alrw== + +ag-grid-vue3@^28.2.1: + version "28.2.1" + resolved "http://mirrors.cloud.tencent.com/npm/ag-grid-vue3/-/ag-grid-vue3-28.2.1.tgz#a43464a1f681dbf0f1d8724e7446c827fd54f09d" + integrity sha512-n7+l51zFCZm3SVT2pI0lVVwL8gsDPebqNLfEy4DS17OlV5IL7c1eNXRosv/QMu+YHOEMVcwFRWH380nIjVF/+w== + dependencies: + ag-grid-community "~28.2.1" + vue "^3.0.0" + alien-signals@^1.0.3: version "1.0.13" resolved "https://registry.npmmirror.com/alien-signals/-/alien-signals-1.0.13.tgz#8d6db73462f742ee6b89671fbd8c37d0b1727a7e" @@ -927,6 +988,14 @@ birpc@^2.3.0: resolved "https://registry.npmmirror.com/birpc/-/birpc-2.3.0.tgz#e5a402dc785ef952a2383ef3cfc075e0842f3e8c" integrity sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g== +brace-expansion@^1.1.7: + version "1.1.11" + resolved "http://mirrors.cloud.tencent.com/npm/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" @@ -964,6 +1033,11 @@ caniuse-lite@^1.0.30001716: resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz#dae13a9c80d517c30c6197515a96131c194d8f82" integrity sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw== +codemirror@^5.65.19: + version "5.65.19" + resolved "http://mirrors.cloud.tencent.com/npm/codemirror/-/codemirror-5.65.19.tgz#71016c701d6a4b6e1982b0f6e7186be65e49653d" + integrity sha512-+aFkvqhaAVr1gferNMuN8vkTSrWIFvzlMV9I2KBLCWS2WpZ2+UAkZjlMZmEuT+gcXTi6RrGQCkWq1/bDtGqhIA== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -971,6 +1045,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +concat-map@0.0.1: + version "0.0.1" + resolved "http://mirrors.cloud.tencent.com/npm/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + convert-source-map@^2.0.0: version "2.0.0" resolved "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" @@ -1026,6 +1105,11 @@ debug@^4.1.0, debug@^4.3.1, debug@^4.3.7: dependencies: ms "^2.1.3" +decimal.js@^10.5.0: + version "10.5.0" + resolved "http://mirrors.cloud.tencent.com/npm/decimal.js/-/decimal.js-10.5.0.tgz#0f371c7cf6c4898ce0afb09836db73cd82010f22" + integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== + default-browser-id@^5.0.0: version "5.0.0" resolved "https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.0.tgz#a1d98bf960c15082d8a3fa69e83150ccccc3af26" @@ -1233,6 +1317,11 @@ fs-extra@^11.2.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "http://mirrors.cloud.tencent.com/npm/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -1280,6 +1369,18 @@ get-stream@^9.0.0: "@sec-ant/readable-stream" "^0.4.1" is-stream "^4.0.1" +glob@^7.1.3: + version "7.2.3" + resolved "http://mirrors.cloud.tencent.com/npm/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -1341,6 +1442,24 @@ image-size@~0.5.0: resolved "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" integrity sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ== +immediate@~3.0.5: + version "3.0.6" + resolved "http://mirrors.cloud.tencent.com/npm/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= + +inflight@^1.0.4: + version "1.0.6" + resolved "http://mirrors.cloud.tencent.com/npm/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "http://mirrors.cloud.tencent.com/npm/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + is-docker@^3.0.0: version "3.0.0" resolved "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" @@ -1395,6 +1514,11 @@ isexe@^3.1.1: resolved "https://registry.npmmirror.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== +jquery@^3.6.0: + version "3.7.1" + resolved "http://mirrors.cloud.tencent.com/npm/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" + integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -1446,6 +1570,20 @@ less@^4.2.1: needle "^3.1.0" source-map "~0.6.0" +lie@3.1.1: + version "3.1.1" + resolved "http://mirrors.cloud.tencent.com/npm/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + +localforage@^1.10.0: + version "1.10.0" + resolved "http://mirrors.cloud.tencent.com/npm/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -1520,6 +1658,13 @@ mime@^1.4.1: resolved "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +minimatch@^3.1.1: + version "3.1.2" + resolved "http://mirrors.cloud.tencent.com/npm/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimatch@^9.0.0, minimatch@^9.0.3: version "9.0.5" resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" @@ -1602,6 +1747,13 @@ npm-run-path@^6.0.0: path-key "^4.0.0" unicorn-magic "^0.3.0" +once@^1.3.0: + version "1.4.0" + resolved "http://mirrors.cloud.tencent.com/npm/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + open@^10.1.0: version "10.1.2" resolved "https://registry.npmmirror.com/open/-/open-10.1.2.tgz#d5df40984755c9a9c3c93df8156a12467e882925" @@ -1627,6 +1779,11 @@ path-browserify@^1.0.1: resolved "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "http://mirrors.cloud.tencent.com/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -1718,6 +1875,13 @@ rfdc@^1.4.1: resolved "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== +rimraf@^3.0.2: + version "3.0.2" + resolved "http://mirrors.cloud.tencent.com/npm/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rollup@^4.34.9: version "4.41.0" resolved "https://registry.npmmirror.com/rollup/-/rollup-4.41.0.tgz#17476835d2967759e3ffebe5823ed15fc4b7d13e" @@ -1803,12 +1967,17 @@ sirv@^3.0.0, sirv@^3.0.1: mrmime "^2.0.0" totalist "^3.0.0" +sortablejs@1.15.6: + version "1.15.6" + resolved "http://mirrors.cloud.tencent.com/npm/sortablejs/-/sortablejs-1.15.6.tgz#ff93699493f5b8ab8d828f933227b4988df1d393" + integrity sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A== + source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== -source-map@~0.6.0: +source-map@0.6.1, source-map@~0.6.0: version "0.6.1" resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -1818,6 +1987,11 @@ speakingurl@^14.0.1: resolved "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53" integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ== +split.js@^1.6.5: + version "1.6.5" + resolved "http://mirrors.cloud.tencent.com/npm/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" + integrity sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw== + strip-final-newline@^4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz#35a369ec2ac43df356e3edd5dcebb6429aa1fa5c" @@ -1953,6 +2127,16 @@ vue-demi@*: resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04" integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg== +vue-i18n@9.2.2: + version "9.2.2" + resolved "http://mirrors.cloud.tencent.com/npm/vue-i18n/-/vue-i18n-9.2.2.tgz#aeb49d9424923c77e0d6441e3f21dafcecd0e666" + integrity sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ== + dependencies: + "@intlify/core-base" "9.2.2" + "@intlify/shared" "9.2.2" + "@intlify/vue-devtools" "9.2.2" + "@vue/devtools-api" "^6.2.1" + vue-router@^4.5.0: version "4.5.1" resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz#47bffe2d3a5479d2886a9a244547a853aa0abf69" @@ -1968,7 +2152,12 @@ vue-tsc@^2.2.8: "@volar/typescript" "~2.4.11" "@vue/language-core" "2.2.10" -vue@^3.5.13: +vue3-menus@^1.1.2: + version "1.1.2" + resolved "http://mirrors.cloud.tencent.com/npm/vue3-menus/-/vue3-menus-1.1.2.tgz#b798b16e051e7a5acfaa5ab0df1ae9de51d1a726" + integrity sha512-MoX87TH25fbKmmE8PwC+c2kJOSGJheP4pBR2we0RkOrfUDQg7sK+akAZSmQU8o+7dF+xVF2NfKPhoVHOhlX9wQ== + +vue@^3.0.0, vue@^3.5.13: version "3.5.14" resolved "https://registry.npmmirror.com/vue/-/vue-3.5.14.tgz#0ddf16d20cc20adaedfb5e77bca64c488bf5ee27" integrity sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew== @@ -1993,6 +2182,11 @@ which@^5.0.0: dependencies: isexe "^3.1.1" +wrappy@1: + version "1.0.2" + resolved "http://mirrors.cloud.tencent.com/npm/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + yallist@^3.0.2: version "3.1.1" resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"