打包插件

This commit is contained in:
猴赛雷 2024-04-23 13:45:48 +08:00
parent 020542062a
commit 0bd8966bf4
54 changed files with 203 additions and 4745 deletions

View File

@ -2,7 +2,6 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="hoslay,3697355039@qq.com"> <meta name="author" content="hoslay,3697355039@qq.com">
<meta name="copyright" content="hoslay"> <meta name="copyright" content="hoslay">
@ -11,7 +10,7 @@
<meta name="description" content="DDei在线设计器——简单、好用、免费的在线绘图和流程编排工具。流程设计、UML、思维导图、数据库设计、泳道图、时序图、类图、在线绘图、二次开发、API接口、协作!"> <meta name="description" content="DDei在线设计器——简单、好用、免费的在线绘图和流程编排工具。流程设计、UML、思维导图、数据库设计、泳道图、时序图、类图、在线绘图、二次开发、API接口、协作!">
<meta name="Keywords" content="流程设计,UML,思维导图,数据库设计,泳道图,时序图,类图,在线绘图,免费,二次开发,API接口,协作"> <meta name="Keywords" content="流程设计,UML,思维导图,数据库设计,泳道图,时序图,类图,在线绘图,免费,二次开发,API接口,协作">
<meta name="replace"> <meta name="replace">
<title>DDei-在线设计器V1.0.4</title> <title>DDei-在线设计器V1.2.0</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

751
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "ddei-editor", "name": "ddei-editor",
"version": "1.2.0", "version": "1.2.1",
"private": false, "private": false,
"type": "module", "type": "module",
"author": "hoslay <3697355039@qq.com>", "author": "hoslay <3697355039@qq.com>",
@ -22,7 +22,7 @@
"url": "https://gitee.com/hoslay/ddei-editor.git" "url": "https://gitee.com/hoslay/ddei-editor.git"
}, },
"files": [ "files": [
"src/*", "dist/*",
"README.md", "README.md",
"package.json" "package.json"
], ],
@ -30,12 +30,12 @@
"url": "https://gitee.com/hoslay/ddei-editor", "url": "https://gitee.com/hoslay/ddei-editor",
"email": "3697355039@qq.com" "email": "3697355039@qq.com"
}, },
"main": "./dist/ddei-framework.umd.cjs", "main": "./dist/ddei-editor.js",
"module": "./dist/ddei-framework.js", "module": "./dist/ddei-framework.js",
"exports": { "exports": {
".": { ".": {
"import": "./dist/ddei-framework.js", "import": "./dist/ddei-editor.js",
"require": "./dist/ddei-framework.umd.cjs" "require": "./dist/ddei-editor.umd.cjs"
} }
}, },
"engines": { "engines": {
@ -49,16 +49,11 @@
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false" "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^4.2.0", "ddei-framework1": "^1.2.6",
"axios": "^1.6.8", "axios": "^1.6.8",
"ddei-autolink": "^1.1.1",
"ddei-framework": "^1.2.6",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"jspdf": "^2.5.1", "jspdf": "^2.5.1",
"lodash": "^4.17.21", "lodash": "^4.17.21"
"postcss-px2rem": "^0.3.0",
"three": "^0.156.1",
"vue-router": "^4.3.2"
}, },
"devDependencies": { "devDependencies": {
"@tsconfig/node18": "^18.2.0", "@tsconfig/node18": "^18.2.0",

View File

@ -80,9 +80,8 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import {DDeiEditor} from "ddei-framework";
import {DDeiEditorUtil} from "ddei-framework"; import {DDeiEditorUtil} from "ddei-framework";
import { createshortlink } from "@/lib/api/shortlink" import { createshortlink } from "../lib/api/shortlink"
import {DDeiUtil} from "ddei-framework"; import {DDeiUtil} from "ddei-framework";
import DialogBase from "./dialog" import DialogBase from "./dialog"

View File

@ -41,7 +41,7 @@
<script lang="ts"> <script lang="ts">
import {DDeiEditor} from "ddei-framework"; import {DDeiEditor} from "ddei-framework";
import {DDeiEditorUtil} from "ddei-framework"; import {DDeiEditorUtil} from "ddei-framework";
import { login, userinfo } from "@/lib/api/login"; import { login, userinfo } from "../lib/api/login";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import {DDeiEditorState} from "ddei-framework"; import {DDeiEditorState} from "ddei-framework";
import DialogBase from "./dialog" import DialogBase from "./dialog"

View File

@ -23,9 +23,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import {DDeiEditor} from "ddei-framework";
import {DDeiEditorUtil} from "ddei-framework"; import {DDeiEditorUtil} from "ddei-framework";
import DDeiUtil from "../../framework/js/util.ts";
import DialogBase from "./dialog" import DialogBase from "./dialog"
export default { export default {

View File

@ -87,7 +87,7 @@
<script lang="ts"> <script lang="ts">
import {DDeiEditor} from "ddei-framework"; import {DDeiEditor} from "ddei-framework";
import {DDeiEditorUtil} from "ddei-framework"; import {DDeiEditorUtil} from "ddei-framework";
import { register, userinfo } from "@/lib/api/login"; import { register, userinfo } from "../lib/api/login";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import DialogBase from "./dialog" import DialogBase from "./dialog"

View File

@ -4,11 +4,9 @@ import {DDeiEnumBusCommandType} from "ddei-framework";
import {DDeiLineLink} from "ddei-framework"; import {DDeiLineLink} from "ddei-framework";
import {DDeiUtil} from "ddei-framework"; import {DDeiUtil} from "ddei-framework";
import { Matrix3, Vector3 } from 'three'; import { Matrix3, Vector3 } from 'three';
import layer from "../../configs/layer";
import {DDeiEditor} from "ddei-framework"; import {DDeiEditor} from "ddei-framework";
import {DDeiEditorEnumBusCommandType} from "ddei-framework"; import {DDeiEditorEnumBusCommandType} from "ddei-framework";
import {DDeiEditorState} from "ddei-framework"; import {DDeiEditorState} from "ddei-framework";
import {DDeiEditorUtil} from "ddei-framework";
import {DDeiKeyAction} from "ddei-framework"; import {DDeiKeyAction} from "ddei-framework";
import {DDeiEnumOperateState} from "ddei-framework"; import {DDeiEnumOperateState} from "ddei-framework";
import {DDeiAbstractShape} from "ddei-framework"; import {DDeiAbstractShape} from "ddei-framework";

View File

@ -10,7 +10,7 @@
</div> </div>
</div> </div>
<div class="logo"> <div class="logo">
<img src="@/assets/images/logo.png"> <img :src="icons['logo']">
</div> </div>
</div> </div>
<div class="tail"> <div class="tail">
@ -38,6 +38,7 @@ export default {
file: {}, file: {},
fileNameEditing: false, fileNameEditing: false,
fileDescEditing: false, fileDescEditing: false,
icons: DDeiEditorUtil.ICONS
}; };
}, },
computed: {}, computed: {},

View File

@ -59,8 +59,8 @@ import {DDeiEditorEnumBusCommandType} from "ddei-framework";
import {DDeiEditorState} from "ddei-framework"; import {DDeiEditorState} from "ddei-framework";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import {DDeiEditorUtil} from "ddei-framework"; import {DDeiEditorUtil} from "ddei-framework";
import { collfile } from "@/lib/api/file"; import { collfile } from "../../lib/api/file";
import { userinfo } from "@/lib/api/login"; import { userinfo } from "../../lib/api/login";
import {DDeiFileState} from "ddei-framework"; import {DDeiFileState} from "ddei-framework";
import {DDeiUtil} from "ddei-framework"; import {DDeiUtil} from "ddei-framework";

View File

@ -27,31 +27,23 @@
Abc Abc
</div> </div>
<div class="ddei-core-panel-quickstyle-item-box-template-icon"> <div class="ddei-core-panel-quickstyle-item-box-template-icon">
<!-- <img width="16px" height="16px" src="../../icons/icon-to-up.png" />
<img width="16px" height="16px" src="../../icons/icon-to-down.png" />
<img width="11px" height="11px" style="margin-left:10px;" src="../../icons/icon-to-down-double.png" /> -->
</div> </div>
</div> </div>
</div> </div>
<div class="ddei-core-panel-quickstyle-item" style="grid-column: 14/16;"> <div class="ddei-core-panel-quickstyle-item" style="grid-column: 14/16;">
<div class="ddei-core-panel-quickstyle-item-box"> <div class="ddei-core-panel-quickstyle-item-box">
<!-- <img width="14px" height="14px" src="../../icons/icon-fill.png" />
<div>填充</div>
<img width="6px" height="6px" style="margin-top:8px" src="../../icons/toolbox-expanded.png" /> -->
</div> </div>
</div> </div>
<div class="ddei-core-panel-quickstyle-item" style="grid-column: 14/16;"> <div class="ddei-core-panel-quickstyle-item" style="grid-column: 14/16;">
<div class="ddei-core-panel-quickstyle-item-box"> <div class="ddei-core-panel-quickstyle-item-box">
<!-- <img width="14px" height="14px" src="../../icons/icon-style-line.png" />
<div>线条</div>
<img width="6px" height="6px" style="margin-top:8px" src="../../icons/toolbox-expanded.png" /> -->
</div> </div>
</div> </div>
<div class="ddei-core-panel-quickstyle-item" style="grid-column: 14/16"> <div class="ddei-core-panel-quickstyle-item" style="grid-column: 14/16">
<div class="ddei-core-panel-quickstyle-item-box"> <div class="ddei-core-panel-quickstyle-item-box">
<!-- <img width="14px" height="14px" src="../../icons/icon-style-shadow.png" />
<div>阴影</div>
<img width="6px" height="6px" style="margin-top:8px" src="../../icons/toolbox-expanded.png" /> -->
</div> </div>
</div> </div>
<div class="ddei-core-panel-quickstyle-item" style="grid-column:1/16;"> <div class="ddei-core-panel-quickstyle-item" style="grid-column:1/16;">

View File

@ -1,48 +0,0 @@
import {DDeiPluginBase} from "ddei-framework";
import DDeiExtTestStep1Converter from "./teststep1"
import DDeiExtTestStep2Converter from "./teststep2"
class DDeiExtTestConverters extends DDeiPluginBase {
type: string = "package"
/**
*
*/
static defaultIns: DDeiExtTestConverters = new DDeiExtTestConverters(null);
plugins: object[] = [DDeiExtTestStep1Converter, DDeiExtTestStep2Converter]
getConverters(editor) {
let converters = []
this.plugins?.forEach(plugin => {
let ls
if (DDeiPluginBase.isSubclass(plugin, DDeiPluginBase)) {
ls = plugin.defaultIns.getConverters(editor);
} else if (plugin instanceof DDeiPluginBase) {
ls = plugin.getConverters(editor);
}
if (ls?.length > 0) {
converters = converters.concat(ls);
}
})
return converters
}
static configuraton(options) {
if (options) {
//解析options只使用自己相关的
let converters = new DDeiExtTestConverters(options);
for (let i = 0; i < converters.plugins?.length; i++) {
converters.plugins[i] = converters.plugins[i].configuraton(options, true)
}
return converters;
}
return DDeiExtTestConverters;
}
}
export { DDeiExtTestConverters, DDeiExtTestStep1Converter, DDeiExtTestStep2Converter }
export default DDeiExtTestConverters;

View File

@ -1,63 +0,0 @@
import {DDeiConverterBase} from "ddei-framework";
class DDeiExtTestStep1Converter extends DDeiConverterBase {
name: string = "ddei-ext-test-step1-converter"
sort:number = 2
/**
*
*/
static defaultIns: DDeiExtTestStep1Converter = new DDeiExtTestStep1Converter(null);
/**
*
*/
isEnable(fileData: object): boolean{
return true;
}
/**
*
*/
input(fileData: object): object{
console.log("convert1")
return fileData;
}
/**
*
*/
output(fileData: object): object{
console.log("convert3")
return fileData;
}
static configuraton(options, fullConfig: boolean = false) {
//解析options只使用自己相关的
if (options) {
let newOptions = Object.assign({}, {}, DDeiExtTestStep1Converter.defaultIns.defaultOptions)
if (fullConfig) {
if (fullConfig) {
if (options[DDeiExtTestStep1Converter.defaultIns.name]) {
for (let i in options[DDeiExtTestStep1Converter.defaultIns.name]) {
newOptions[i] = options[DDeiExtTestStep1Converter.defaultIns.name][i]
}
}
}
} else {
for (let i in options) {
newOptions[i] = options[i]
}
}
if (newOptions && Object.keys(newOptions).length !== 0) {
let layouts = new DDeiExtTestStep1Converter(newOptions);
return layouts;
}
}
return DDeiExtTestStep1Converter;
}
}
export {DDeiExtTestStep1Converter}
export default DDeiExtTestStep1Converter;

View File

@ -1,62 +0,0 @@
import {DDeiConverterBase} from "ddei-framework";
class DDeiExtTestStep2Converter extends DDeiConverterBase {
name:string = "ddei-ext-test-step2-converter"
sort: number = 1
/**
*
*/
static defaultIns: DDeiExtTestStep2Converter = new DDeiExtTestStep2Converter(null);
/**
*
*/
isEnable(fileData: object): boolean{
return true;
}
/**
*
*/
input(fileData: object): object{
console.log("convert2")
return fileData;
}
/**
*
*/
output(fileData: object): object{
console.log("convert3")
return fileData;
}
static configuraton(options, fullConfig: boolean = false) {
//解析options只使用自己相关的
if (options) {
let newOptions = Object.assign({}, {}, DDeiExtTestStep2Converter.defaultIns.defaultOptions)
if (fullConfig) {
if (fullConfig) {
if (options[DDeiExtTestStep2Converter.defaultIns.name]) {
for (let i in options[DDeiExtTestStep2Converter.defaultIns.name]) {
newOptions[i] = options[DDeiExtTestStep2Converter.defaultIns.name][i]
}
}
}
} else {
for (let i in options) {
newOptions[i] = options[i]
}
}
if (newOptions && Object.keys(newOptions).length !== 0) {
let layouts = new DDeiExtTestStep2Converter(newOptions);
return layouts;
}
}
return DDeiExtTestStep2Converter;
}
}
export {DDeiExtTestStep2Converter}
export default DDeiExtTestStep2Converter;

Binary file not shown.

View File

@ -1,42 +0,0 @@
import {DDeiPluginBase} from "ddei-framework";
class DDeiExtFontTest extends DDeiPluginBase {
/**
*
*/
static defaultIns: DDeiExtFontTest = new DDeiExtFontTest(null);
getFonts(editor) {
let font_ctx = import.meta.glob(
"./fonts/*.ttf", { eager: true }
)
let fontOptions = this.getOptions();
let fonts = []
for (let path in font_ctx) {
let font = font_ctx[path].default
let fontName = font.substring(font.lastIndexOf("/")+1,font.lastIndexOf("."))
if (fontName.indexOf("-") != -1){
fontName = fontName.substring(0, fontName.lastIndexOf("-"))
}
let fontData = { "ch": fontName, "en": fontName, "font": font }
if (fontOptions && fontOptions[fontName]){
for (let x in fontOptions){
fontData[x] = fontOptions[x]
}
}
fonts.push(fontData)
}
return fonts;
}
static configuraton(options) {
let core = new DDeiExtFontTest(options);
return core;
}
}
export {DDeiExtFontTest}
export default DDeiExtFontTest;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,55 +1,7 @@
<template> <script setup lang="ts">
<a-config-provider :locale="locale">
<router-view v-slot="{ Component, route }">
<component :is="Component" :key="route.path" />
</router-view>
</a-config-provider>
</template>
<script lang="ts">
import zhCN from 'ant-design-vue/es/locale/zh_CN';
export default {
name: "APP-DDEI",
extends: null,
mixins: [],
props: {},
//
components: {},
data() {
return {
locale: zhCN,
layers: [],
};
},
computed: {},
watch: {},
created() {
document.body.style.overscrollBehaviorX = "none"
},
mounted() {
},
methods: {},
};
</script> </script>
<style>
body {
display: block;
}
#app { <template>
padding: 0; <div>
margin: 0; </div>
display: block; </template>
max-width: 100%;
touch-action: none;
}
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -5,9 +5,10 @@
<component v-for="(item, index) in editor?.getDialogs()" :is="item.dialog" :options="item.options" <component v-for="(item, index) in editor?.getDialogs()" :is="item.dialog" :options="item.options"
v-bind="item.options"></component> v-bind="item.options"></component>
<MenuDialog v-show="!refreshMenu"></MenuDialog> <MenuDialog v-show="!refreshMenu"></MenuDialog>
<div :id="id + '_dialog_background_div'" class="dialog-background-div"></div>
<div :id="id + '_ddei_cut_img_div'" class="ddei-cut-img-div"></div>
</div> </div>
<div :id="id + '_dialog_background_div'" class="dialog-background-div"></div>
<div :id="id + '_ddei_cut_img_div'" class="ddei-cut-img-div"></div>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -23,7 +24,7 @@ import MenuDialog from "./MenuDialog.vue";
import {DDeiEditorUtil} from "ddei-framework"; import {DDeiEditorUtil} from "ddei-framework";
import DDeiCore from "@ddei/core"; import DDeiCore from "@ddei/core";
import ICONS from "./js/icon"; import ICONS from "./icon";
import { markRaw } from "vue"; import { markRaw } from "vue";
export default { export default {
@ -230,50 +231,27 @@ export default {
min-width: 1700px; min-width: 1700px;
background-color: var(--background); background-color: var(--background);
.icon {
color: var(--icon);
}
} img {
</style> -webkit-user-drag: none;
<style lang="less"> user-drag: none;
.icon { -webkit-user-select: none;
color: var(--icon); -moz-user-select: none;
} -ms-user-select: none;
.ddei-editor img { user-select: none;
-webkit-user-drag: none; }
user-drag: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.ddei-editor div { div {
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
} }
*> {
.ddei-cut-img-div {
width: 0.1px;
height: 0.1px;
display: flex;
}
.dialog-background-div {
width: 100%;
height: 100vh;
opacity: 50%;
z-index: 500;
left: 0;
top: 0;
display: none;
position: absolute;
}
.ddei-editor{
*>{
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 6px; width: 6px;
height: 6px; height: 6px;
@ -305,4 +283,21 @@ export default {
} }
} }
} }
.ddei-cut-img-div {
width: 0.1px;
height: 0.1px;
display: flex;
}
.dialog-background-div {
width: 100%;
height: 100vh;
opacity: 50%;
z-index: 500;
left: 0;
top: 0;
display: none;
position: absolute;
}
</style> </style>
../icon

View File

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 477 B

6
src/editor/index.ts Normal file
View File

@ -0,0 +1,6 @@
import DDeiEditor from "./Editor.vue";
export * from "@ddei/core";
export * from "@ddei/uml";
export * from "./icon";
export default DDeiEditor;

View File

@ -1,11 +1,4 @@
import './utils/flexible.js';
import './assets/main.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import App from '@/App.vue' import App from './App.vue'
import router from '@/router'
import './assets/fonts/iconfont/iconfont.css' createApp(App).mount('#app')
import './assets/fonts/iconfont/iconfont.js'
const app = createApp(App)
app.use(router)
app.mount('#app')
window.$app = app

View File

@ -1,23 +0,0 @@
// import {DDei} from 'ddei-framework'
import { createRouter, createWebHistory } from 'vue-router'
import { routes } from './routes'
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior: () => {
history.pushState(null, null, document.URL)
}
})
router.beforeEach((to, from) => {
// if (from.name == 'Design') {
// for (let i in DDei.INSTANCE_POOL) {
// DDei.INSTANCE_POOL[i]?.render?.destroyed()
// }
// }
return true
})
export default router

View File

@ -1,24 +0,0 @@
export const routes = [
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue')
},
{
path: '/login',
name: 'Login',
component: () => import('@/views/Login.vue')
},
{
path: '/design/:id',
name: 'Design',
component: () => import('@/views/Design.vue')
},
{
path: '/ss/:url',
name: 'Design-SS',
component: () => import('@/views/Design.vue')
},
]

View File

@ -1,131 +0,0 @@
import { debounce } from "lodash";
(function (win, lib) {
const doc = win.document;
const docEl = doc.documentElement;
let metaEl = doc.querySelector('meta[name="viewport"]');
const flexibleEl = doc.querySelector('meta[name="flexible"]');
let dpr = 0;
let scale = 0;
const flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
const match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
const content = flexibleEl.getAttribute('content');
if (content) {
const initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
const maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
const isAndroid = win.navigator.appVersion.match(/android/gi);
const isIPhone = win.navigator.appVersion.match(/iphone/gi);
const devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下对于2和3的屏用2倍的方案其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
const wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
let refreshRem = function () {
let width = docEl.getBoundingClientRect().width;
//转换为图片
let canvas = document.createElement('canvas');
//获得 2d 上下文对象
let context = canvas.getContext('2d');
let backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
let ratio = (window.devicePixelRatio || 1) / backingStore;
if (width / dpr * ratio < 1440) {
width = 1440 * dpr / ratio;
}
// console.log(width + " . " + dpr)
// if (width / dpr >= 2560) {
// width = 2560 * dpr;
// }
const rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
let refreshRemDebounce = debounce(refreshRem, 200)
win.addEventListener('resize', function () {
refreshRemDebounce();
}, false);
win.addEventListener('pageshow', function (e) {
if (e.persisted) {
refreshRemDebounce();
}
}, false);
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function (e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function (d) {
let val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
};
flexible.px2rem = function (d) {
let val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
};
})(window, window.lib || (window.lib = {}));

File diff suppressed because one or more lines are too long

View File

@ -1,112 +0,0 @@
<template>
<div class="ddei_home">
<div class="ddei_home_header">
<Headers />
</div>
<div class="ddei_home_middle">
<div class="ddei_home_middle_left">
<DirTree ref="dirTree" />
</div>
<div class="ddei_home_middle_right">
<FileList ref="fileList" @create-folder="onCreateFolder" />
</div>
</div>
</div>
</template>
<script lang="ts">
import { userinfo } from "@/lib/api/login/index.js";
import Cookies from "js-cookie";
import Headers from "./components/Header.vue";
import FileList from "./components/FileList.vue";
import HomeBar from "./components/HomeBar.vue";
import DirTree from "./components/DirTree.vue";
export default {
props: {},
data() {
return {
refreshFileList: true,
};
},
//
components: {
Headers,
FileList,
HomeBar,
DirTree,
},
mounted() {
this.getUserInfo();
},
methods: {
forceRefreshFileList() {
this.$refs.fileList?.listFile(1)
},
/**
* 获取登录用户信息
*/
getUserInfo() {
userinfo()
.then((response) => {
let userJSON = response.data.data;
let user = JSON.stringify(userJSON, null, 4);
if (userJSON.id == "-99") {
Cookies.remove("token");
this.$router.push({
path: this.$route.query.redirect || "/login",
});
}
Cookies.set("user", user);
})
.catch((e) => {
Cookies.remove("token");
this.$router.push({
path: this.$route.query.redirect || "/login",
});
});
},
onCreateFolder() {
this.$refs.dirTree?.createFolder()
}
},
};
</script>
<style lang="less" scoped>
.ddei_home {
width: 100%;
height: calc(100vh);
background: white;
display: flex;
flex-direction: column;
}
.ddei_home_header {
// flex: 0 0 48px;
}
.ddei_home_bar {
flex: 0 0 48px;
// background: #2c2c2c;
}
.ddei_home_middle {
flex: 1;
// background: #2c2c2c;
display: flex;
}
.ddei_home_middle_left {
// flex: 0 0 300px;
width: 280px;
padding-left: 10px;
}
.ddei_home_middle_right {
flex: 1;
display: flex;
}
</style>

View File

@ -1,648 +0,0 @@
<template>
<div class="login">
<form>
<img src="../assets/images/login-back.jpg" class="bgimg" />
<div class="banquan">
<a href="https://beian.miit.gov.cn/">渝ICP备2024020863号</a>
<img src="../assets/images/gaba.png" />
<a href="https://beian.mps.gov.cn/#/query/webSearch?code=50011302222098" rel="noreferrer"
target="_blank">渝公网安备50011302222098</a>
</div>
<div class="content">
<div class="content_right_login_form" v-show="!regDialogShow">
<div class="content_right_login_form_title">欢迎来到DDei</div>
<div class="content_right_login_form_title_split"></div>
<div class="content_right_form_msg">
{{ form.validMsg.username }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan413"></use>
</svg>
<div class="split"></div>
<input v-model="form.username" placeholder="手机号/邮箱/账号" autofocus />
</div>
<div class="content_right_form_msg">
{{ form.validMsg.password }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan415"></use>
</svg>
<div class="split"></div>
<input v-model="form.password" placeholder="请输入密码" type="password" @keydown.enter="login" />
</div>
<div class="content_right_login_form_chkbox" @click="changeRememberPwd()"
style="user-select: none;cursor:pointer">
<input type="checkbox" v-model="rememberPwd" style="pointer-event:none" />记住密码
</div>
<div class="content_right_login_form_login" @click="login">
<span>登录</span>
</div>
<div class="regbtn" @click="gotoReg">
<span>注册</span>
</div>
</div>
<div class="content_right_login_form reg_form" v-show="regDialogShow">
<div class="content_right_login_form_title">新用户注册</div>
<div class="content_right_login_form_title_split"></div>
<div class="content_right_form_msg">
{{ reg.validMsg.mobile }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan412"></use>
</svg>
<div class="split"></div>
<input v-model="reg.mobile" id="reg_input_id" type="mobile" class="content_right_reg_form_input"
placeholder="手机号" />
<span class="content_right_reg_form_input_required">*</span>
</div>
<div class="content_right_form_msg">
{{ reg.validMsg.username }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan413"></use>
</svg>
<div class="split"></div>
<input v-model="reg.username" class="content_right_reg_form_input" placeholder="用户名,4-20位中文、英文、数字、下划线" />
<span class="content_right_reg_form_input_required">*</span>
</div>
<div class="content_right_form_msg">
{{ reg.validMsg.email }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-youjian-01-01"></use>
</svg>
<div class="split"></div>
<input v-model="reg.email" class="content_right_reg_form_input" placeholder="邮箱地址" type="email" />
</div>
<div class="content_right_form_msg">
{{ reg.validMsg.password }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan415"></use>
</svg>
<div class="split"></div>
<input v-model="reg.password" type="password" autocomplete="on" class="content_right_reg_form_input"
placeholder="密码" />
<span class="content_right_reg_form_input_required">*</span>
</div>
<div class="content_right_form_msg">
{{ reg.validMsg.password1 }}
</div>
<div class="content_right_login_form_input">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan414"></use>
</svg>
<div class="split"></div>
<input v-model="reg.password1" type="password" autocomplete="on" class="content_right_reg_form_input"
placeholder="确认密码" />
<span class="content_right_reg_form_input_required">*</span>
</div>
<div class="content_right_login_form_login" @click="userRegister">
<span>注册并登录</span>
</div>
<div class="regbtn" @click="gotoLogin">
<span>登录</span>
</div>
</div>
</div>
<div class="register_dialog" v-show="false && regDialogShow">
<div class="register_dialog_layer" />
<div class="register_dialog_content">
<div class="content_right_reg_form_title">
新用户注册
</div>
<div class="content_right_form_msg">
{{ reg.validMsg.mobile }}
</div>
<input v-model="reg.mobile" id="reg_input_id" type="mobile" class="content_right_reg_form_input"
placeholder="手机号" />
<span class="content_right_reg_form_input_required">*</span>
<div class="content_right_form_msg">
{{ reg.validMsg.username }}
</div>
<input v-model="reg.username" class="content_right_reg_form_input" placeholder="用户名,4-20位中文、英文、数字、下划线" />
<span class="content_right_reg_form_input_required">*</span>
<div class="content_right_form_msg">
{{ reg.validMsg.email }}
</div>
<input v-model="reg.email" class="content_right_reg_form_input" placeholder="邮箱地址" type="email" />
<div class="content_right_form_msg">
{{ reg.validMsg.password }}
</div>
<input v-model="reg.password" type="password" autocomplete="on" class="content_right_reg_form_input"
placeholder="密码" />
<span class="content_right_reg_form_input_required">*</span>
<div class="content_right_form_msg">
{{ reg.validMsg.password1 }}
</div>
<input v-model="reg.password1" type="password" class="content_right_reg_form_input" placeholder="确认密码" />
<span class="content_right_reg_form_input_required">*</span>
<div class="content_right_login_form_buttons">
<div class="content_right_login_form_login" style="margin-top:20px;" @click="userRegister">
<span>注册并登录</span>
</div>
<div class="content_right_login_form_register" style="margin-top:20px;" @click="showRegDialog">
<span>取消</span>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
<script lang="ts">
import { login, userinfo, register } from "@/lib/api/login";
import Cookies from "js-cookie";
export default {
props: {},
data() {
return {
loginMessage: "",
user: "",
form: {
username: "",
password: "",
validMsg: {},
},
reg: {
username: "",
email: "",
mobile: "",
password: "",
password1: "",
validMsg: {},
},
rememberPwd: false,
regDialogShow: false,
};
},
mounted() {
let remUserName = Cookies.get("remUserName");
let remPassword = Cookies.get("remPassword");
if (remUserName && remPassword) {
this.rememberPwd = true
this.form.username = remUserName;
this.form.password = remPassword;
}
this.getUserInfo();
},
methods: {
changeRememberPwd() {
this.rememberPwd = !this.rememberPwd
},
gotoReg() {
this.regDialogShow = true;
this.reg.username = "";
this.reg.email = "";
this.reg.mobile = "";
this.reg.password = "";
this.reg.password1 = "";
this.reg.validMsg = {};
if (this.regDialogShow) {
setTimeout(() => {
document.getElementById("reg_input_id").focus();
}, 20);
}
},
gotoLogin() {
this.regDialogShow = false;
},
//
async userRegister() {
//
this.reg.validMsg = {};
if (!this.reg.username) {
this.reg.validMsg.username = "请输入用户名";
} else {
let uPattern = /^[\u4e00-\u9fa5a-zA-Z0-9_-]{4,20}$/;
if (!uPattern.test(this.reg.username)) {
this.reg.validMsg.username = "用户名为4至20位,请勿输入特殊字符";
}
}
if (!this.reg.mobile) {
this.reg.validMsg.mobile = "请输入手机号码";
} else {
let mPattern =
/^1([3-9])\d{9}$/
if (!mPattern.test(this.reg.mobile)) {
this.reg.validMsg.mobile = "请输入正确的手机号码";
}
}
if (this.reg.email) {
let ePattern =
/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
if (!ePattern.test(this.reg.email)) {
this.reg.validMsg.email = "请输入正确的邮箱地址";
}
}
if (
!this.reg.password ||
this.reg.password.length < 6 ||
this.reg.password.length > 20
) {
this.reg.validMsg.password = "请输入6-20位密码";
} else if (this.reg.password != this.reg.password1) {
this.reg.validMsg.password1 = "前后输入的密码不一致";
}
if (JSON.stringify(this.reg.validMsg) == "{}") {
//
this.reg.validMsg = {};
let regData = await register(this.reg);
if (regData.status == 200) {
//
if (regData.data?.code == 0) {
this.regDialogShow = false;
this.loginSuccess(regData.data.data);
} else {
this.reg.validMsg = { mobile: regData.data.message };
}
} else {
this.reg.validMsg = { mobile: "服务端请求失败,请联系管理员" };
}
}
},
//
async login() {
//
this.form.validMsg = {};
if (!this.form.username) {
this.form.validMsg.username = "请输入用户名";
} else {
let uPattern = /^[\u4e00-\u9fa5a-zA-Z0-9_-]{4,20}$/;
if (!uPattern.test(this.form.username)) {
this.reg.validMsg.username = "用户名为4至20位,请勿输入特殊字符";
}
}
//
if (
!this.form.password ||
this.form.password.length < 6 ||
this.form.password.length > 20
) {
this.form.validMsg.password = "请输入6-20位密码";
}
if (JSON.stringify(this.form.validMsg) == "{}") {
//
this.form.validMsg = {};
let loginData = await login(this.form);
if (loginData.status == 200) {
//
if (loginData.data?.code == 0) {
this.loginSuccess(loginData.data.data);
} else {
this.form.validMsg = { username: loginData.data.message };
}
} else {
this.form.validMsg = {
username: "服务端请求失败,请联系管理员",
};
}
}
},
loginSuccess(response) {
// token
Cookies.set('token', response.token)
Cookies.set('refreshToken', response.refreshToken)
Cookies.set('tokenExp', response.tokenExp)
this.getUserInfo();
},
/**
* 获取登录用户信息
*/
getUserInfo() {
userinfo()
.then((response) => {
let userJSON = response.data.data;
let user = JSON.stringify(userJSON, null, 4);
Cookies.set("user", user);
//
if (this.rememberPwd) {
Cookies.set("remUserName", this.form.username);
Cookies.set("remPassword", this.form.password);
}
this.$router.push({
path: this.$route.query.redirect || "/",
});
})
.catch((e) => {
Cookies.remove("token");
});
},
},
};
</script>
<style lang="less" scoped>
.login {
width: 100%;
height: calc(100vh);
}
.content {
width: 100%;
height: calc(100vh);
background: url("../assets/images/login-back.jpg");
background-size: 100% 100%;
}
.bgimg {
width: 100%;
height: calc(100vh);
z-index: 99;
left: 0px;
top: 0px;
position: absolute;
}
.banquan {
width: 100%;
z-index: 99;
left: 0px;
bottom: 45px;
text-align: center;
position: absolute;
height: 14px;
font-size: 14px;
font-weight: 500;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
>a {
text-decoration: none;
color: black;
}
>img {
width: 18px;
height: 18px;
margin-left: 20px;
}
}
.content_right_login_form {
width: 440px;
height: 500px;
display: flex;
flex-direction: column;
background: #fff;
text-align: center;
box-shadow: 0px 0px 35px 0px rgba(34, 115, 191, 0.16);
border-radius: 10px;
overflow: hidden;
position: absolute;
right: 363px;
top: 210px;
z-index: 990;
.regbtn {
position: absolute;
-webkit-font-smoothing: antialiased;
background-color: #176EFF;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
right: -60px;
top: -60px;
width: 120px;
height: 120px;
user-select: none;
cursor: pointer;
>span {
font-size: 21px;
line-height: 21px;
position: absolute;
font-weight: bold;
-webkit-font-smoothing: antialiased;
color: #fff;
right: 38px;
bottom: 11px;
}
}
}
.reg_form {
height: 650px;
top: 150px;
.content_right_login_form_login {
margin-top: 25px;
}
}
.content_right_login_form_title {
margin-top: 66px;
text-align: center;
flex: 0 0 38px;
font-size: 24px;
font-family: "Microsoft YaHei";
font-weight: bold;
color: #434343;
}
.content_right_login_form_title_split {
margin: 3px auto 25px auto;
width: 40px;
flex: 0 0 4px;
background-color: #176EFF;
border-radius: 4px;
}
.content_right_login_form_input {
margin: 0px auto 0px auto;
width: 300px;
flex: 0 0 52px;
background: #F2F4F9;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
.split {
height: 26px;
flex: 0 0 1px;
margin-left: 18px;
background: #D6DAE7;
}
.icon {
flex: 0 0 22px;
margin-left: 18px;
color: #a4b3d0;
}
>input {
margin-left: 18px;
flex: 1 1 92px;
height: 26px;
font-size: 16px;
font-family: "Microsoft YaHei";
font-weight: 400;
border: none;
outline: none;
background: none;
&::placeholder {
/* Chrome, Firefox, Opera, Safari 10.1+ */
color: #9CA4AF;
}
&::-webkit-input-placeholder {
/* WebKit browserswebkit内核浏览器 */
color: #9CA4AF
}
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #9CA4AF
}
&::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #9CA4AF
}
&:-ms-input-placeholder {
/* Internet Explorer 10-11 */
color: #9CA4AF
}
&::-ms-input-placeholder {
/* Microsoft Edge */
color: #9CA4AF
}
}
>span {
flex: 0 0 20px;
text-align: center;
}
}
.content_right_login_form_chkbox {
margin: 19px auto 35px auto;
width: 300px;
flex: 0 0 15px;
color: black;
display: flex;
justify-content: start;
align-items: center;
font-size: 14px;
>* {
margin-right: 10px;
}
}
.content_right_form_msg {
width: 300px;
flex: 0 0 23px;
font-size: 14px;
color: red;
text-align: right;
margin: 0 auto;
}
.content_right_login_form_login {
margin: 0 auto;
width: 300px;
flex: 0 0 52px;
background: #176EFF;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.content_right_login_form_login span {
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
}
/**
* 注册弹框
*/
.register_dialog {
z-index: 99;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: calc(100vh);
}
.register_dialog_layer {
width: 100%;
height: calc(100vh);
background-color: black;
opacity: 90%;
}
.register_dialog_content {
position: absolute;
width: 390px;
height: 460px;
left: calc(50% - 195px);
top: calc(50% - 225px);
background: #fff;
margin-right: 139px;
border-radius: 10px;
}
.content_right_reg_form_input_required {
font-size: 19px;
color: red;
text-align: center;
pointer-events: none;
}
.content_right_reg_form_title {
width: 80%;
height: 40px;
font-size: 20px;
color: #3662ec;
text-align: center;
margin-left: 36px;
margin-top: 25px;
}
.content_right_reg_form_input {
width: 80%;
height: 40px;
font-size: 14px;
margin-left: 40px;
}
</style>

View File

@ -1,265 +0,0 @@
<template>
<a-layout class="table">
<a-layout-header class="ant-layout-header--small">
<Header />
</a-layout-header>
<a-layout>
<a-layout-header class="search-container">
<a-layout>
<a-layout-sider width="260">
<span class="title">规则列表</span>
</a-layout-sider>
<a-layout-content>
<Search :data="params"
style="margin-left: 10px;"
@search="searchTable" />
</a-layout-content>
</a-layout>
</a-layout-header>
<a-layout>
<a-layout-sider width="300px"
style="padding-left: 40px;">
<div class="tree-wrapper">
<Tree ref="groupTree"
@selectedTree="selectedTree" />
</div>
</a-layout-sider>
<a-layout-content class="container"
style="padding-right: 40px;">
<div ref="listContainer"
class="list-container">
<a-spin :spinning="loading">
<div class="clearfix">
<TableListAdd :width="listWidth"
@add="createRules" />
<TableList v-for="(item,index) in tableData"
:data="item"
:key="index"
:width="listWidth"
@copy="copy(item)"
@edit="edit(item)"
@delete="deleteItem(item)" />
</div>
<a-pagination class="pagination"
v-model="current"
:pageSize="params.pageSize"
:total="total"
@change="changePage"
show-less-items />
</a-spin>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</a-layout>
</template>
<script>
import Header from './components/Header.vue'
import TableList from './components/TableList.vue'
import TableListAdd from './components/TableListAdd.vue'
import RulesSet from './components/RulesSet.vue'
import Tree from './components/Tree.vue'
import Search from './components/Search.vue'
import { formatDate } from '../../../utils/date'
import Cookies from 'js-cookie'
import {
getEngineListData,
deleteEngineData,
copyEngineData
} from '../../api/table'
import { awaitWrap } from '../../../utils/sugars'
export default {
name: 'Table',
components: {
Header,
TableList,
TableListAdd,
Tree,
Search
},
watch: {
listNum (value) {
this.listWidth = (this.realWidth - value * 10) / value
this.params.pageSize = value * 3 - 1
this.getTableData()
}
},
data () {
return {
loading: false,
total: 1,
current: 1,
listWidth: 298, // list
listNum: 0, // list 5 4
realWidth: 0, //
FORMAT: 'MM-DD HH:mm',
params: {
pageNum: 1,
pageSize: 15
},
tableData: []
}
},
mounted () {
if (Cookies.get('token') == null) {
this.$router.push({
path: this.$route.query.redirect || '/login'
})
}
//
this.initByCache()
this.calcListWidth()
},
methods: {
//
searchTable (obj) {
this.params = Object.assign(this.params, obj)
this.current = 1
this.params.pageNum = 1
//
this.saveCache()
this.getTableData()
},
//
changePage (page, pageSize) {
this.params.pageNum = page
//
this.saveCache()
this.getTableData()
},
//
selectedTree (keys) {
keys = keys.length ? keys : ['']
this.params.groupId = keys[0].toString()
this.current = 1
this.params.pageNum = 1
//
this.saveCache()
this.getTableData()
},
//
createRules () {
let groupId = this.$refs.groupTree.getCurrentNodeKey()
this.dialog({
title: '请设置基础数据',
body: <RulesSet ref="RulesSet" group-id={groupId} />,
theme: 'dark',
beforeClose: async (type, close) => {
if (type === 'confirm') {
const result = await this.$refs.RulesSet.submit()
if (result) {
this.$router.push({
path: '/rule-designer',
query: result
})
close()
}
} else {
close()
}
}
}).then(() => {
this.$nextTick(() => {
this.$refs.RulesSet.focus()
})
})
},
//
edit (item) {
this.$router.push({
path: '/rule-designer',
query: { id: item.id }
})
},
//
deleteItem (item) {
const that = this
this.confirm({
title: '请确认是否删除数据',
async onOk () {
const [err, data] = await awaitWrap(deleteEngineData(item.id))
if (!err) {
that.getTableData()
}
}
})
},
//
copy (item) {
const that = this
this.confirm({
title: '请确认是否拷贝数据',
async onOk () {
const [err, data] = await awaitWrap(copyEngineData(item.id))
if (!err) {
that.getTableData()
}
}
})
},
//
async getTableData () {
this.showLoading()
const [err, data] = await awaitWrap(getEngineListData(this.params))
this.hideLoading()
if (!err) {
const listData = data.data
//
listData.forEach((item) => {
item.create_time = formatDate(item.create_time, this.FORMAT)
item.update_time = formatDate(item.update_time, this.FORMAT)
})
this.tableData = listData
this.total = data.count
} else {
this.message.error('查询错误: ' + err.message)
}
},
//
calcListWidth () {
setTimeout(() => {
const elem = this.$refs.listContainer
this.realWidth = Math.floor(elem.getBoundingClientRect().width) - 6
if (this.realWidth < 1300) {
this.listNum = 4
} else {
this.listNum = 5
}
}, 20)
},
showLoading () {
this.loading = true
},
hideLoading () {
this.loading = false
},
initByCache () {
let params = window.sessionStorage.getItem('params')
if (params) {
try {
params = JSON.parse(params)
} catch (error) {
params = this.params
}
} else {
params = this.params
}
//
this.params = params
this.current = this.params.pageNum || 1
const { groupTree } = this.$refs
groupTree && groupTree.setCurrentNodeKey(+this.params.groupId || '')
},
saveCache () {
//
let storage = window.sessionStorage
storage.setItem('params', JSON.stringify(this.params))
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,448 +0,0 @@
<template>
<div class="ddei_home_dir_tree_wrapper">
<!-- 固定目录 -->
<div class="ddei_home_dir_tree">
<div v-for="folder in menus" class="ddei_home_dir_tree_node" :class="{ 'is-active': folder.id === curMenu?.id }"
@click="setCurrentMenu(folder)">
<svg v-if="folder.icon" class="icon ddei_home_dir_tree_node_icon" aria-hidden="true">
<use :xlink:href="folder.icon"></use>
</svg>
<div class="ddei_home_dir_tree_node_title">{{ folder.name }}</div>
</div>
</div>
<!-- 知识库目录 -->
<ATree v-model:selectedKeys="menuTreeSelectedKeys" v-model:expandedKeys="menuTreeExpandedKeys"
class="ddei_home_dir_tree" block-node :tree-data="folderTreeData" :field-names="treeFieldNames"
@select="setCurrentFolder">
<template #title="folder">
<div class="ddei_home_dir_tree_node">
<svg v-if="folder.icon" class="icon ddei_home_dir_tree_node_icon" aria-hidden="true">
<use :xlink:href="folder.icon"></use>
</svg>
<div v-else class="ddei_home_dir_tree_node_icon__point"></div>
<div class="ddei_home_dir_tree_node_title">{{ folder.name }}</div>
<div class="ddei_home_dir_tree_node_buttons">
<svg aria-hidden="true" class="icon ddei_home_dir_tree_node_button" title="新建子目录"
@click.stop="showFolderDialog(folder, 1)">
<use xlink:href="#icon-a-ziyuan374"></use>
</svg>
<svg v-if="folder.id !== '0'" aria-hidden="true" class="icon ddei_home_dir_tree_node_button" title="修改"
@click.stop="showFolderDialog(folder, 2)">
<use xlink:href="#icon-a-ziyuan484"></use>
</svg>
<svg v-if="folder.id !== '0'" aria-hidden="true" class="icon ddei_home_dir_tree_node_button" title="删除"
@click.stop="deleteFolder(folder)">
<use xlink:href="#icon-a-ziyuan401"></use>
</svg>
</div>
</div>
</template>
</ATree>
</div>
<AModal v-model:open="folderDialog.open" :title="(folderDialog.mod == 1 ? '创建' : '修改') + '目录'"
:ok-button-props="{ loading: folderDialog.saving }" width="400px" @ok="sumbitFolder()">
<AForm ref="form" :model="folderDialog.formData" :rules="folderDialog.formRules" autocomplete="off" class="m-t-20">
<AFormItem name="name">
<AInput v-model:value="folderDialog.formData.name" placeholder="目录名" clearable></AInput>
</AFormItem>
<AFormItem name="parent_id">
<ATreeSelect v-model:value="folderDialog.formData.parent_id" show-search style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="父目录" allow-clear tree-default-expand-all
:tree-data="folderSelectTreeData" :field-names="treeFieldNames" tree-node-filter-prop="label"></ATreeSelect>
</AFormItem>
</AForm>
</AModal>
</template>
<script type="ts">
import { createVNode } from 'vue'
import { loadfolder, createfolder, removefolder, renamefolder } from "@/lib/api/folder"
import { debounce, cloneDeep } from 'lodash'
import { message, Modal } from 'ant-design-vue'
//
// import IconFolderBlack from '@/components/editor/icons/icon-folder-black.png'
// import IconTrash from '@/components/editor/icons/icon-trash.png'
// import IconDocumentBlack from '@/components/editor/icons/icon-document-black.png'
export default {
name: 'DDei-Home-Dir-Tree',
expose: ['createFolder', 'getCurrentFolder', 'setCurrentFolder', 'getFolderTreeData'],
props: {
},
data () {
// let rootFolder = { name: "", id: "0", icon: IconDocumentBlack, isShow: true, allowDelete: false, allowModify: false }
let rootFolder = { name: "我的文件", id: "0", icon: '#icon-a-ziyuan489', isShow: true, allowDelete: false, allowModify: false }
return {
menus: [
// {
// id: 'Main',
// name: '',
// icon: IconHomeBlack,
// visible: true
// },
{
id: 'All',
name: '全部',
icon: '#icon-a-ziyuan384',
visible: true
},
// {
// id: 'MyFile',
// name: '',
// icon: IconFolderBlack,
// visible: true
// },
// todo
// {
// id: 'RecycleBin',
// name: '',
// icon: IconTrash,
// visible: true
// }
],
rootFolder: rootFolder,
folders: [rootFolder],
folderTreeData: [rootFolder],
menuTreeSelectedKeys: [],
menuTreeExpandedKeys: ['0'],
treeFieldNames: { children: 'children', key: 'id', title: 'name', label: 'name', value: 'id' },
curMenu: undefined,
curFolder: undefined,
folderDialogShow: false,
delFolderDialogShow: false,
folderDialog: {
open: false,
saving: false,
mod: 1,
formData: {},
formRules: {
name: [
{
validator: debounce(this.checkDirName)
}
]
}
},
cf: {}
}
},
computed: {
folderSelectTreeData () {
//
let curFolderId = this.folderDialog.formData.id
if (curFolderId) {
let tree = cloneDeep(this.folderTreeData)
let queue = [].concat(tree)
while (queue.length) {
let item = queue.shift()
if (item.children) {
item.children = item.children.filter(item => item.id !== curFolderId)
queue = queue.concat(item.children)
}
}
return tree
}
return this.folderTreeData
}
},
created () { },
mounted () {
},
methods: {
getCurrentFolder () {
return this.curFolder
},
/**
* 设置当前目录
*/
setCurrentFolder ([folderId] = []) {
this.menuTreeSelectedKeys = [folderId]
this.curFolder = this.folders.find(item => item.id === folderId)
this.curMenu = undefined
this.$parent.forceRefreshFileList()
},
setCurrentMenu (menu) {
this.menuTreeSelectedKeys = []
this.curFolder = undefined
this.curMenu = menu
this.$parent.forceRefreshFileList()
},
getFolderTreeData () {
return this.folderTreeData
},
/**
* 弹出新文件夹的弹出框
*/
showFolderDialog (folder, mod) {
this.folderDialog.open = true
this.folderDialog.mod = mod
let formData
if (mod == 1) {
formData = {
//
parent_id: folder?.id || '0'
}
} else if (mod == 2) {
formData = {
parent_id: folder.parent_id,
id: folder.id,
name: folder.name
}
}
this.curFolder = folder
this.folderDialog.formData = formData
},
deleteFolder (folder) {
if (folder.children?.length) {
//
message.warning('当前目录存在下级目录,不能直接删除!')
return
}
Modal.confirm({
title: '是否删除目录',
content: createVNode('div', { style: 'color:red;' }, folder.name),
okType: 'danger',
onOk: async () => {
let folderData = await removefolder({ id: folder.id })
if (folderData.status == 200) {
//
if (folderData.data?.code == 0) {
message.success('删除成功')
this.loadFolder()
}
}
}
})
},
checkDirName (rule, value, cb) {
if (!value) {
cb('请输入目录名')
return
}
let uPattern = /^[\u4e00-\u9fa5a-zA-Z0-9_-]{1,15}$/
if (!uPattern.test(value)) {
cb("目录名为1至15位中文、字母、数字下划线组合")
return
}
cb()
},
/**
* 创建/更新目录
*/
sumbitFolder () {
this.$refs.form.validate().then(async () => {
let folderData = null
this.folderDialog.saving = true
if (this.folderDialog.mod == 1) {
folderData = await createfolder(this.folderDialog.formData)
} else if (this.folderDialog.mod == 2) {
folderData = await renamefolder(this.folderDialog.formData)
}
if (folderData?.status == 200) {
//
if (folderData.data?.code == 0) {
message.success('保存成功')
this.folderDialog.open = false
//
this.loadFolder()
}
}
this.folderDialog.saving = false
}).catch(e => {
console.error(e)
this.folderDialog.saving = false
})
},
/**
* 加载目录
*/
async loadFolder () {
let folderData = await loadfolder()
if (folderData.status == 200) {
//
if (folderData.data?.code == 0) {
let folders = folderData.data.data || []
this.folders = [this.rootFolder].concat(folders)
folders = this.folderToTree(folders)
this.folders[0].children = folders
this.folderTreeData = [this.folders[0]]
}
}
},
/**
* 将folderList转换为树结构并返回
*/
folderToTree (folders) {
// map
let tree = []
let cache = {}
folders.forEach(item => {
cache[item.id] = item
})
folders.forEach(folder => {
folder.parent_id = folder.parent_id || '0'
let parent = cache[folder.parent_id]
if (parent) {
parent.children = parent.children || []
parent.children.push(folder)
} else {
tree.push(folder)
}
})
return tree
},
createFolder () {
this.showFolderDialog(this.curFolder || this.folders[0], 1)
}
},
mounted () {
//
this.loadFolder()
}
}
</script>
<style lang='less' scoped>
.ddei_home_dir_tree_wrapper {
height: calc(100vh - 55px);
overflow-x: hidden;
overflow-y: auto;
background-color: #F9FAFB;
border: 1px solid #E0E3E9;
border-top: 0px;
border-radius: 0 0 4px 4px;
padding: 20px 10px;
}
.ddei_home_dir_tree {
flex: 1;
font-size: 14px;
cursor: pointer;
:deep(&.ant-tree) {
background-color: transparent;
margin-left: -10px;
.ant-tree-treenode {
.ant-tree-switcher,
.ant-tree-node-content-wrapper {
line-height: 40px;
}
.ant-tree-node-content-wrapper {
padding: 0px;
overflow: hidden;
}
.ant-tree-node-content-wrapper {
width: 100%;
&.ant-tree-node-selected {
background: #E4E7EC;
}
}
.ddei_home_dir_tree_node {
padding: 0 6px;
margin-bottom: 0;
}
}
}
}
.ddei_home_dir_tree_node {
width: 100%;
padding: 0 14px 0 20px;
text-align: left;
display: flex;
align-items: center;
height: 40px;
line-height: 40px;
border-radius: 4px;
margin-bottom: 4px;
&:hover {
background: #E4E7EC;
.ddei_home_dir_tree_node_buttons {
display: flex;
}
}
&.is-active {
background: #E4E7EC;
}
}
.ddei_home_dir_tree_node_content {}
.ddei_home_dir_tree_node_icon {
width: 24px;
margin-right: 6px;
flex-shrink: 0;
}
.ddei_home_dir_tree_node_icon__point {
width: 16px;
margin-right: 6px;
flex-shrink: 0;
text-align: center;
&::after {
display: inline-block;
content: ' ';
vertical-align: middle;
width: 4px;
height: 4px;
background: #176EFF;
border-radius: 50%;
}
}
.ddei_home_dir_tree_node_title {
flex: 1;
overflow: hidden;
white-space: nowrap;
color: black;
font-size: 16px !important;
text-overflow: ellipsis;
}
.ddei_home_dir_tree_node_buttons {
display: none;
align-items: center;
height: 20px;
width: auto;
}
.ddei_home_dir_tree_node_button {
display: block;
width: 18px;
height: 18px;
+.ddei_home_dir_tree_node_button {
margin-left: 6px;
}
}
.ddei_home_dir_tree_node_button:hover {
filter: brightness(40%);
}
</style>

View File

@ -1,625 +0,0 @@
<template>
<div class="ddei_home_fileview">
<div class="ddei_home_fileview_operations">
<div v-if="false" class="ddei_home_fileview_operate ddei_home_fileview_operate_dir_add"
@click="onCreateFolderClick">
<div class="ddei_home_fileview_operate_icon">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-add-folder-icon"></use>
</svg>
</div>
<div class="ddei_home_fileview_operate_name">
新建文件组
</div>
<div class="ddei_home_fileview_operate_plus">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan376"></use>
</svg>
</div>
</div>
<div class="ddei_home_fileview_operate ddei_home_fileview_operate_file_add" @click="showFileDialog(null, 1)">
<div class="ddei_home_fileview_operate_icon">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-add-file-icon"></use>
</svg>
</div>
<div class="ddei_home_fileview_operate_name">
新建文件
</div>
<div class="ddei_home_fileview_operate_plus">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan376"></use>
</svg>
</div>
</div>
<div v-if="false" class="ddei_home_fileview_operate ddei_home_fileview_operate_file_draft_add">
<div class="ddei_home_fileview_operate_icon">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-add-file1-icon"></use>
</svg>
</div>
<div class="ddei_home_fileview_operate_name">
新建草稿
</div>
<div class="ddei_home_fileview_operate_plus">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan376"></use>
</svg>
</div>
</div>
</div>
<div class="ddei_home_fileview_divide"></div>
<ASpin wrapper-class-name="ddei_home_fileview_files_spin" :spinning="loading">
<div v-if="files?.length" class="ddei_home_fileview_files">
<div v-for="(file) in files" :key="file.id" class="ddei_home_fileview_file">
<div class="ddei_home_fileview_file_header">
<div class="ddei_home_fileview_file_icon">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-wenjian01"></use>
</svg>
</div>
<div class="ddei_home_fileview_file_name" :title="file.name">{{ file.name }}</div>
<div
:class="{ 'ddei_home_fileview_file_version': true, 'ddei_home_fileview_file_version_published': file.publish == 1 }">
v{{ file.version }}
</div>
<div class="ddei_home_fileview_file_update">
{{ getFileLastTime(file) }}
</div>
</div>
<div class="ddei_home_fileview_file_info" @click="gotoDesign(file)">
<div class="ddei_home_fileview_file_thumbnail">
<img v-if="file.thumb" :src="file.thumb" />
<img v-if="!file.thumb" src="@/assets/images/thumbnail_default.png">
</div>
</div>
<div class="ddei_home_fileview_file_buttons">
<div class="ddei_home_fileview_file_button" @click="showFileDialog(file, 2)">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-icon-edit-file"></use>
</svg>
<span>编辑</span>
</div>
<div class="ddei_home_fileview_file_button_split">
</div>
<div class="ddei_home_fileview_file_button_split">
</div>
<div class="ddei_home_fileview_file_button" @click="copyFile(file)">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-icon-copy-file"></use>
</svg>
<span>复制</span>
</div>
<div class="ddei_home_fileview_file_button_split">
</div>
<div class="ddei_home_fileview_file_button" @click="deleteFile(file)">
<svg class="icon" style="color:red" aria-hidden="true">
<use xlink:href="#icon-a-ziyuan401"></use>
</svg>
<span>删除</span>
</div>
</div>
</div>
</div>
<AEmpty v-else class="m-t-80"></AEmpty>
</ASpin>
<APagination v-model:current="page.num" :total="page.total" show-less-items class="m-h-auto m-t-10"
@change="listFile" />
</div>
<AModal v-model:open="fileDialog.open" :title="(fileDialog.mod == 1 ? '创建' : '修改') + '文件'"
:ok-button-props="{ loading: fileDialog.saving }" width="400px" @ok="submitFile()">
<AForm ref="form" :model="fileDialog.formData" :rules="fileDialog.formRules" autocomplete="off" class="m-t-20">
<AFormItem name="name">
<AInput v-model:value="fileDialog.formData.name" placeholder="文件名" clearable></AInput>
</AFormItem>
<AFormItem name="code">
<AInput v-model:value="fileDialog.formData.code" placeholder="编码" clearable></AInput>
</AFormItem>
<AFormItem name="folder_id">
<ATreeSelect v-model:value="fileDialog.formData.folder_id" show-search style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="所属目录" allow-clear
tree-default-expand-all :tree-data="folderSelectTreeData" :field-names="treeFieldNames"
tree-node-filter-prop="label"></ATreeSelect>
</AFormItem>
<AFormItem name="desc">
<ATextarea v-model:value="fileDialog.formData.desc" placeholder="备注" :rows="4" />
</AFormItem>
</AForm>
</AModal>
</template>
<script type="ts">
import Cookies from 'js-cookie'
import { listfile, createfile, savefilebasic, removefile, copyfile } from "@/lib/api/file"
import ICONS from '@/components/editor/js/icon'
import { debounce } from 'lodash'
import { createVNode } from 'vue'
import { message, Modal } from 'ant-design-vue'
export default {
name: 'DDei-Home-Filelist',
emits: ['createFolder'],
expose: ['listFile'],
props: {
},
data () {
return {
loading: false,
fileDialogShow: false,
delFileDialogShow: false,
fileDialog: {
open: false,
saving: false,
mod: 1,
formData: {},
formRules: {
name: [
{
validator: debounce(this.checkFileName)
}
],
code: [
{
validator: debounce(this.checkFileCode)
}
],
desc: [
{
validator: debounce(this.checkFileDesc)
}
]
}
},
icons: ICONS,
cf: {},
files: [
],
folderSelectTreeData: [],
menuTreeExpandedKeys: ['0'],
treeFieldNames: { children: 'children', key: 'id', title: 'name', label: 'name', value: 'id' },
queryText: "",
page: { size: 10, num: 1, total: 0 }
}
},
created () { },
mounted () {
this.listFile()
},
methods: {
/**
* 跳转到设计页
*/
gotoDesign (file) {
this.$router.push({
path: '/design/' + file.id,
})
},
deleteFile (file) {
Modal.confirm({
title: '是否删除文件',
content: createVNode('div', {}, file.name),
onOk: async () => {
let fileData = await removefile({ id: file.id })
if (fileData.status == 200) {
//
if (fileData.data?.code == 0) {
message.success('删除成功')
this.listFile(this.page.num)
}
}
}
})
},
copyFile (file) {
Modal.confirm({
title: '是否复制文件',
content: file.name,
onOk: async () => {
let fileData = await copyfile({ id: file.id })
if (fileData.status == 200) {
//
if (fileData.data?.code == 0) {
message.success('复制成功')
this.listFile(this.page.num)
}
}
}
})
},
/**
* 加载文件
*/
async listFile (pageNumber) {
if (pageNumber) {
this.page.num = pageNumber
} else if (pageNumber > this.page.count) {
this.page.num = this.page.count
} else if (pageNumber < 1) {
this.page.num = 1
}
let curFolder = this.$parent.$refs["dirTree"]?.getCurrentFolder()
let fid = curFolder?.id ? curFolder.id : "0"
this.loading = true
let fileData
let listData
try {
fileData = await listfile({ folder_id: fid, pageSize: this.page.size, pageNum: this.page.num, text: this.queryText })
listData = fileData.data.data.data
this.page.total = fileData.data.data.count
} catch (e) {
listData = []
this.page.total = 0
}
this.files = listData
this.loading = false
},
checkFileName (rule, value, cb) {
if (!value) {
cb('请输入文件名')
return
}
let uPattern = /^[\u4e00-\u9fa5a-zA-Z0-9_-]{1,15}$/
if (!uPattern.test(value)) {
cb("文件名为1至15位中文、字母、数字下划线组合")
return
}
cb()
},
checkFileCode (rule, value, cb) {
if (!value) {
cb()
return
}
let uPattern = /^[a-zA-Z0-9_.-]{0,20}$/
if (!uPattern.test(value)) {
cb("编码为0至20位字母、数字、_.组合")
return
}
cb()
},
checkFileDesc (rule, value, cb) {
if (!value) {
cb()
return
}
if (value.length > 50) {
cb("描述请稍微简短一点, 不要超过50个字")
return
}
cb()
},
/**
* 创建/更新文件
*/
submitFile () {
this.$refs.form.validate().then(async () => {
let fileData = null
this.fileDialog.saving = true
if (this.fileDialog.mod == 1) {
fileData = await createfile(this.fileDialog.formData)
} else if (this.fileDialog.mod == 2) {
fileData = await savefilebasic(this.fileDialog.formData)
}
if (fileData?.status == 200) {
//
if (fileData.data?.code == 0) {
message.success('保存成功')
//
this.listFile(this.page.num)
this.fileDialog.open = false
}
}
this.fileDialog.saving = false
}).catch(e => {
console.error(e)
this.fileDialog.saving = false
})
},
/**
* 弹出新文件的弹出框
*/
showFileDialog (file, mod) {
this.folderSelectTreeData = this.$parent.$refs["dirTree"]?.getFolderTreeData()
this.fileDialog.open = true
this.fileDialog.mod = mod
let formData = Object.assign({}, file)
this.curFile = file
let curFolder = this.$parent.$refs["dirTree"]?.getCurrentFolder()
let fid = curFolder?.id || "0"
formData.folder_id = fid
this.fileDialog.formData = formData
},
/**
* 获取文件最后更新时间
*/
getFileLastTime (file) {
if (file?.last_update_time) {
let date = file.last_update_time
if (date && date.length > 10 && date.indexOf("-") != -1) {
let d = date.substring(date.indexOf("-") + 1, date.indexOf("T"))
// if (date.indexOf("T") != -1 && date.indexOf(":", date.indexOf(":") + 1) != -1) {
// d += " " + date.substring(date.indexOf("T") + 1, date.indexOf(":", date.indexOf(":") + 1))
// }
return d
}
}
return ""
},
onCreateFolderClick () {
this.$emit('create-folder')
}
}
}
</script>
<style lang='less' scoped>
.ddei_home_fileview {
flex: 1;
display: flex;
flex-direction: column;
padding: 24px 32px;
height: calc(100vh - 55px);
}
.ddei_home_fileview_files_spin {
flex: 1;
height: calc(100% - 105px);
}
.ddei_home_fileview_files {
margin-top: -20px;
margin-left: -20px;
height: 100%;
}
.ddei_home_fileview_file {
width: 295px;
height: 280px;
border-radius: 4px;
display: flex;
flex-direction: column;
background: #FAFAFA;
color: #212121;
margin-left: 20px;
margin-top: 20px;
float: left;
}
.ddei_home_fileview_file_header {
display: flex;
align-items: center;
border-radius: 4px 4px 0 0;
border: 1px solid #CED4DD;
background: #ffffff;
flex: 0 0 48px;
padding: 0 20px;
}
.ddei_home_fileview_file_info {
flex: 0 0 184px;
display: grid;
gap: 2px;
padding: 20px;
border: 1px solid #CED4DD;
border-top: 0;
border-bottom: 0;
cursor: pointer;
overflow: hidden;
}
.ddei_home_fileview_file_thumbnail {
width: 100%;
height: 100%;
overflow: hidden;
text-align: center;
img {
max-width: 100%;
/* 设置图片的最大宽度为父元素宽度的100% */
max-height: 100%;
/* 同上最大高度也为100% */
width: auto;
/* 宽度设为auto使图片按比例缩放 */
height: auto;
/* 高度同上,按比例缩放 */
min-width: 160px;
/* 如果图片小于父元素最小宽度应设置为100px以保持等比缩放效果 */
min-height: 100px;
/* 同上最小高度也应为100px */
}
}
.ddei_home_fileview_file_add {
flex: 1;
color: #3662ec;
border: 1px dashed #3662ec;
border-radius: 6px;
font-size: 60px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.ddei_home_fileview_file_add:hover {
cursor: pointer;
filter: brightness(120%);
border: 2px dashed #3662ec;
}
.ddei_home_fileview_file_code {
color: #d55e43;
font-size: 12px;
grid-column: 2/5;
}
.ddei_home_fileview_file_update {
color: #898989;
font-size: 12px;
grid-column: 5/7;
text-align: right;
}
.ddei_home_fileview_file_name {
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-right: 8px;
font-size: 16px;
}
.ddei_home_fileview_file_version {
color: orange;
text-align: right;
margin-right: 8px;
}
.ddei_home_fileview_file_version_published {
color: green;
}
.ddei_home_fileview_file_desc {
grid-column: 1/7;
grid-row: 3/5;
font-size: 12px;
color: grey;
overflow: hidden;
background: #2c2c2c;
border-radius: 5px;
padding: 2px;
}
.ddei_home_fileview_file_icon .icon {
width: 21px;
height: 21px;
margin-right: 6px;
}
.ddei_home_fileview_file_buttons {
display: flex;
align-items: center;
border-radius: 0 0 4px 4px;
border: 1px solid #CED4DD;
background: #ffffff;
flex: 0 0 48px;
cursor: pointer;
}
.ddei_home_fileview_file_button_split {
flex: 0 0 1px;
height: 22px;
background-color: #5c5c5c;
}
.ddei_home_fileview_file_button {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.ddei_home_fileview_file_button .icon {
width: 24px;
height: 24px;
margin-right: 4px;
margin-left: 4px;
}
.ddei_home_fileview_file_button span {
font-size: 16px;
margin-right: 10px;
}
.ddei_home_fileview_file_button img:hover {
filter: brightness(40%);
cursor: pointer;
}
.ddei_home_fileview_operations {
display: flex;
}
.ddei_home_fileview_divide {
display: block;
margin-top: 20px;
margin-bottom: 20px;
margin-right: 20px;
border-bottom: 1px solid #CED4DD;
}
.ddei_home_fileview_operate {
width: 285px;
height: 64px;
margin-right: 40px;
display: flex;
align-items: center;
padding: 0 20px;
box-sizing: border-box;
cursor: pointer;
border-radius: 4px;
background-repeat: no-repeat;
background-size: contain;
&_dir_add {
background-image: url(@/assets/images/icon-dir-add-bg.png)
}
&_file_add {
background-image: url(@/assets/images/icon-file-add-bg.png)
}
&_file_draft_add {
background-image: url(@/assets/images/icon-file-draft-add-bg.png)
}
&_icon {
width: 48px;
height: 48px;
.icon {
width: 48px;
height: 48px;
}
}
&_name {
font-size: 16px;
color: #FFFFFF;
line-height: 64px;
flex: 1;
}
&_plus {
.icon {
color: #FFFFFF;
font-size: 26px;
font-weight: bold;
filter: brightness(100%);
}
}
}
</style>

View File

@ -1,138 +0,0 @@
<template>
<div class="header">
<div class="header-logo" @click="handleLogoClick">
<img class="header-logo-icon" src="@/assets/images/logo.png" />
<span class="header-title">{{ title + (version ? ' - V' + version : '') }}</span>
</div>
<div class="header-center">
<SearchInput></SearchInput>
</div>
<div class="header-right">
<div class="header-right-avator">
<img v-if="form.avator" :src="form.avator" class="header-right-avator-img" />
<div v-else class="header-right-avator-img header-right-avator-text">{{ form.username.substring(0, 1) }}</div>
</div>
<div class="header-right-username">{{ form.username }}</div>
<div class="header-right-loginout" @click="loginout">注销</div>
</div>
</div>
</template>
<script lang="ts">
import Cookies from 'js-cookie'
import SearchInput from './SearchInput.vue'
export default {
name: 'Header',
components: {
SearchInput
},
props: {
title: { type: String, default: "DDei-在线设计器" },
version: { type: String, default: "1.0.4" }
},
data() {
return {
form: {
username: '',
rolename: ''
}
}
},
created() { },
mounted() {
let userCookie = Cookies.get('user')
//
if (userCookie) {
let user = JSON.parse(userCookie)
this.form.username = user.name
}
},
methods: {
handleLogoClick() {
this.$router.push('/')
},
loginout() {
Cookies.remove('token')
this.$router.push('/login')
}
}
}
</script>
<style lang="less" scoped>
.header {
width: 100%;
height: 50px;
display: flex;
align-items: center;
border-bottom: 1px solid #DDDDDF;
color: black;
}
.header-logo {
margin-left: 20px;
display: flex;
align-items: center;
text-align: left;
cursor: pointer;
line-height: 0px;
min-width: 260px;
}
.header-title {
font-size: 16px;
}
.header-logo-icon {
width: 30px;
height: 30px;
margin-right: 10px;
vertical-align: sub;
}
.header-center {
flex: 1;
}
.header-right {
display: flex;
align-items: center;
padding-right: 20px;
}
.header-right-avator {
width: 32px;
height: 32px;
}
.header-right-avator-img {
width: 100%;
height: 100%;
background: #176EFF;
border-radius: 50%;
}
.header-right-avator-text {
color: #fff;
font-size: 28px;
line-height: 28px;
text-align: center;
}
.header-right-username {
font-size: 16px;
margin-left: 10px;
}
.header-right-loginout {
margin-left: 10px;
cursor: pointer;
font-size: 16px;
&:hover {
color: #3662ec;
}
}
</style>

View File

@ -1,76 +0,0 @@
<template>
<div class="ddei_home_bar_content">
<div class="ddei_home_bar_content_search">
<input v-model="queryText" @keydown.enter="doQuery" autocomplete="off" name="ddei_home_bar_content_search_input"
class="ddei_home_bar_content_search_input" placeholder="名称/编码/备注">
</div>
</div>
</template>
<script >
export default {
name: 'DDei-Home-Bar',
props: {
},
data () {
return {
queryText: ""
}
},
created () {
},
mounted () {
},
methods: {
doQuery () {
this.$parent.$refs["fileList"].queryText = this.queryText;
this.$parent.$refs["fileList"].listFile(1)
}
},
}
</script>
<style scoped>
.ddei_home_bar_content {
width: 100%;
padding-top: 8px;
}
.ddei_home_bar_content_search {
width: 200px;
height: 32px;
margin-right: 27px;
float: right;
justify-content: center;
align-items: center;
display: flex;
background: grey;
border-color: black;
border-radius: 2px;
padding: 2px;
}
.ddei_home_bar_content_search input {
flex: 1;
color: #fff;
background: transparent;
border: none;
outline: none;
}
.ddei_home_bar_content_search input::-webkit-input-placeholder {
color: rgb(210, 210, 210);
}
.ddei_home_bar_content_search img {
height: 18px;
flex: 0 0 18px;
margin: 0px 2px;
filter: brightness(200%);
}
</style>

View File

@ -1,61 +0,0 @@
<script lang="ts" setup>
import { ref, type Ref, } from 'vue'
const emit = defineEmits(['change'])
const queryText: Ref<string | null | undefined> = ref('')
function doQuery() {
emit('change', queryText)
}
</script>
<template>
<div class="ddei_home_bar_content_search">
<svg class="icon" aria-hidden="true" @click="doQuery">
<use xlink:href="#icon-a-ziyuan416"></use>
</svg>
<input v-model="queryText" name="ddei_home_bar_content_search_input" @keydown.enter="doQuery"
class="ddei_home_bar_content_search_input" placeholder="名称/编码/备注" autocomplete="off">
</div>
</template>
<style lang="less" scoped>
.ddei_home_bar_content {
width: 100%;
padding-top: 8px;
}
.ddei_home_bar_content_search {
margin-left: 20px;
width: 260px;
height: 32px;
background: #F2F4F7;
border-radius: 2px;
justify-content: center;
align-items: center;
display: flex;
padding: 2px 10px;
}
.ddei_home_bar_content_search input {
flex: 1;
background: transparent;
border: none;
outline: none;
height: 24px;
}
.ddei_home_bar_content_search input::-webkit-input-placeholder {
color: #B8B8B8;
}
.ddei_home_bar_content_search svg {
flex: 0 0 24px;
margin-right: 6px;
width: 24px;
height: 24px;
cursor: pointer;
filter: brightness(300%);
}
</style>

View File

@ -1,71 +0,0 @@
export const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: '80px',
align: 'center'
},
{
title: '名称',
dataIndex: 'name',
key: 'name',
width: '300px',
align: 'left'
},
{
title: 'Code',
dataIndex: 'code',
key: 'code',
width: '180px',
align: 'left'
},
{
title: '版本号',
dataIndex: 'version',
key: 'version',
width: '80px',
align: 'center'
},
{
title: 'URI',
dataIndex: 'uri',
key: 'uri',
align: 'center'
},
{
title: '描述',
dataIndex: 'desc',
key: 'desc',
ellipsis: true,
width: '150px',
align: 'center'
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
align: 'center'
},
{
title: '修改时间',
dataIndex: 'update_time',
key: 'update_time',
align: 'center'
},
{
title: '发布状态',
dataIndex: 'publish',
align: 'center',
scopedSlots: { customRender: 'publish' }
},
{
title: '操作',
dataIndex: 'operate',
width: '220px',
align: 'center',
scopedSlots: { customRender: 'operate' }
}
]
export const designJsonStr = { "id": "ruledesigner", "containerid": "ruledesign_container", "width": 2028, "height": 1396, "attrs": {}, "controlType": "999", "modelType": "RuleCanvas", "curIndex": 4, "rootModels": { "begin_23_1": { "id": "begin_23_1", "code": "start", "x": 400, "y": 60, "width": 60, "height": 24, "text": "开始", "bindField": "", "feed": "1", "scale": "1", "modelType": "RuleBegin", "baseModelType": "Activity", "attrs": { "id": "begin_23_1", "code": "start", "text": "开始", "x": 400, "y": 60, "width": 60, "height": 24, "controlType": "1000204", "name": "开始", "desc": "", "align": "center", "valign": "bottom", "feed": "1", "scale": "1", "font": "ref:1", "border": "ref:2", "fill": "ref:3", "mouseoverlistener": "", "mouseoutlistener": "" }, "controlType": "1000204", "align": "center", "valign": "bottom", "border": "ref:2", "font": "ref:1", "fill": "ref:3" }, "compute_28_2": { "id": "compute_28_2", "code": "compute_2", "name": "计算", "x": 360, "y": 140, "width": 120, "height": 55, "text": "计算", "descText": "计算节点", "bindField": "", "feed": "1", "scale": "1", "modelType": "RuleCompute", "baseModelType": "Activity", "attrs": { "id": "compute_28_2", "code": "compute_2", "text": "计算", "descText": "计算节点", "x": 360, "y": 140, "width": 120, "height": 55, "controlType": "1000209", "name": "计算", "desc": "", "together": "n", "expression": "(1+2)*2", "align": "center", "valign": "middle", "feed": "1", "scale": "1", "font": "ref:4", "border": "ref:5", "fill": "ref:6", "imageInfo": "{\"path\":\"/test\",\"wight\":30,\"heigth\":30}", "mouseoverlistener": "", "mouseoutlistener": "" }, "controlType": "1000209", "align": "center", "valign": "middle", "expression": "(1+2)*2", "border": "ref:5", "font": "ref:4", "fill": "ref:6" }, "rd_line_3": { "id": "rd_line_3", "start": { "x": 428, "y": 84, "width": 4, "height": 4 }, "end": { "x": 418, "y": 136, "width": 4, "height": 4 }, "lineType": "2", "text": "", "modelType": "RDLine", "baseModelType": "Line", "attrs": { "id": "rd_line_3", "code": "rd_line_3", "lineType": "2", "start": { "x": 428, "y": 84, "width": 4, "height": 4 }, "end": { "x": 418, "y": 136, "width": 4, "height": 4 }, "controlType": "4000001", "text": "", "lineWeight": "2", "lineDash": "0", "lineOpacity": 1, "font": "ref:7", "fill": "ref:8", "mouseoverlistener": "", "mouseoutlistener": "" }, "controlType": "4000001", "startLinkGroupId": "begin_23_1_bottom", "endLinkGroupId": "compute_28_2_top", "lineDash": "0", "lineOpacity": 1, "lineWeight": "2", "font": "ref:7", "fill": "ref:8" } }, "linkGroups": { "begin_23_1_bottom": { "modelId": "begin_23_1", "type": "bottom", "lineIds": ["rd_line_3"] }, "compute_28_2_top": { "modelId": "compute_28_2", "type": "top", "lineIds": ["rd_line_3"] } }, "SAVE_TEMP_STYLE": { "1": "{\"default\":{\"family\":\"Arial Normal\",\"color\":\"white\",\"size\":\"14\"},\"selected\":{\"family\":\"Arial Normal\",\"color\":\"white\",\"size\":\"14\"}}", "2": "{\"default\":{\"left\":{\"width\":\"0\",\"color\":\"black\",\"dash\":\"\"},\"right\":{\"width\":\"0\",\"color\":\"black\",\"dash\":\"\"},\"top\":{\"width\":\"0\",\"color\":\"black\",\"dash\":\"\"},\"bottom\":{\"width\":\"0\",\"color\":\"black\",\"dash\":\"\"}},\"selected\":{\"left\":{\"width\":\"0\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"},\"right\":{\"width\":\"0\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"},\"top\":{\"width\":\"0\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"},\"bottom\":{\"width\":\"0\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"}}}", "3": "{\"default\":{\"color\":\"rgba(217, 0, 27, 1)\"},\"selected\":{\"color\":\"rgba(217, 0, 27, 1)\"}}", "4": "{\"default\":{\"family\":\"Arial Normal\",\"color\":\"black\",\"size\":\"8\"},\"selected\":{\"family\":\"Arial Normal\",\"color\":\"black\",\"size\":\"8\"}}", "5": "{\"default\":{\"left\":{\"width\":\"1\",\"color\":\"black\",\"dash\":\"\"},\"right\":{\"width\":\"1\",\"color\":\"black\",\"dash\":\"\"},\"top\":{\"width\":\"1\",\"color\":\"black\",\"dash\":\"\"},\"bottom\":{\"width\":\"1\",\"color\":\"black\",\"dash\":\"\"}},\"selected\":{\"left\":{\"width\":\"3\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"},\"right\":{\"width\":\"3\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"},\"top\":{\"width\":\"3\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"},\"bottom\":{\"width\":\"3\",\"color\":\"rgba(90, 154, 239, 90)\",\"dash\":\"\"}}}", "6": "{\"default\":{\"color\":\"rgba(255, 255, 255, 255)\"},\"selected\":{\"color\":\"rgba(255, 255, 255, 255)\"}}", "7": "{\"default\":{\"family\":\"STSong-Light\",\"color\":\"red\",\"size\":\"22\"},\"selected\":{\"family\":\"STSong-Light\",\"color\":\"blue\",\"size\":\"24\"}}", "8": "{\"default\":{\"color\":\"grey\"},\"selected\":{\"color\":\"yellow\"}}" } }

View File

@ -1,11 +1,25 @@
{ {
"files": [], "extends": "@vue/tsconfig/tsconfig.dom.json",
"references": [ "include": [
{ "env.d.ts",
"path": "./tsconfig.node.json" "src/**/*",
}, "src/**/*.vue",
{ "plugins/**/*",
"path": "./tsconfig.app.json" "plugins/**/*.vue"
],
"exclude": [
"src/**/__tests__/*"
],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
],
"@ddei/*": [
"./plugins/*"
]
} }
] }
} }

View File

@ -1,69 +1,34 @@
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from 'node:url'
import viteCompression from "vite-plugin-compression";
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import { resolve } from 'node:path'
import px2rem from "postcss-px2rem"
import path from 'path'
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
// https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
vue(), vue(),
Components({
resolvers: [
AntDesignVueResolver({
importStyle: false, // css in js
}),
],
}),
viteCompression({
// gzip静态资源压缩
threshold: 5120, //压缩前最小文件大小
})
], ],
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)), // '@': fileURLToPath(new URL('./src', import.meta.url)),
'@ddei': fileURLToPath(new URL('./plugins', import.meta.url)), '@ddei': fileURLToPath(new URL('./plugins', import.meta.url)),
'ddei-framework': fileURLToPath(new URL('/Users/hoslay/work/ddei/ddei-framework/dist/ddei-framework.js', import.meta.url)), 'ddei-framework': fileURLToPath(new URL('/Users/hoslay/work/ddei/ddei-framework/dist/ddei-framework.js', import.meta.url)),
} }
}, },
css: {
postcss: { build: {
plugins: [ minify: false,
px2rem({ // 这里配置打包打包时要排除Vue的依赖因为我们使用组件库时本地肯定是vue 环境否则会报isCE 的错误
remUnit: 192, rollupOptions: {
}) external: ["vue", "three", "axios", "lodash", "js-cookie","jspdf"],
] output: {
globals: {
vue: "Vue",
},
},
}, },
} lib: {
entry: "./src/editor/index.ts",
name: "ddei-editor",
},
},
// [vite库模式配置](https://cn.vitejs.dev/guide/build.html#library-mode)
// build: {
// outDir: 'lib',
// lib: {
// entry: resolve(__dirname, './packages/index.ts'),
// name: 'WebVue',
// fileName: 'web-vue'
// },
// rollupOptions: {
// // 确保外部化处理那些你不想打包进库的依赖
// external: ['vue'],
// output: {
// // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
// globals: {
// vue: 'Vue'
// }
// }
// }
// }
}) })