Browse Source

update

main
wangshaoping 6 months ago
parent
commit
447d15ff49
  1. 2
      .gitattributes
  2. 4
      io.sc.engine.rule.frontend/package.json
  3. 3
      io.sc.engine.rule.frontend/src/views/resources/Resources.vue
  4. 1
      io.sc.platform.core.frontend/.editorconfig
  5. 93
      io.sc.platform.core.frontend/.eslintrc.cjs
  6. 95
      io.sc.platform.core.frontend/package.json
  7. BIN
      io.sc.platform.core.frontend/public/images/point.gif
  8. 49
      io.sc.platform.core.frontend/public/index.html
  9. 52
      io.sc.platform.core.frontend/src/platform/components/graph/PlatformGraph.ts
  10. 109
      io.sc.platform.core.frontend/src/platform/components/graph/WGraph.vue
  11. 13
      io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformConstraintHandler.ts
  12. 48
      io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformDragAndDropHandler.ts
  13. 57
      io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformEdgeDefineHandler.ts
  14. 13
      io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformSelectedCellHandler.ts
  15. 2
      io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformVertexDefineHandler.ts
  16. 14
      io.sc.platform.core.frontend/src/platform/components/graph/handler/index.ts
  17. 125
      io.sc.platform.core.frontend/src/platform/plugin/quasar-components.ts
  18. 1
      io.sc.platform.core.frontend/src/platform/plugin/quasar-directives.ts
  19. 14
      io.sc.platform.core.frontend/src/platform/plugin/quasar-plugins.ts
  20. 40
      io.sc.platform.core.frontend/src/platform/plugin/quasar.ts
  21. 8
      io.sc.platform.core.frontend/src/platform/utils/JavascriptLoader.ts
  22. 16
      io.sc.platform.core.frontend/src/platform/utils/Tools.ts
  23. 1
      io.sc.platform.core.frontend/src/shims-vue.d.ts
  24. 40
      io.sc.platform.core.frontend/src/views/testcase/maxgraph/maxgraph.vue
  25. 1
      io.sc.platform.core.frontend/template-project/.editorconfig
  26. 91
      io.sc.platform.core.frontend/template-project/.eslintrc.cjs
  27. 97
      io.sc.platform.core.frontend/template-project/package.json
  28. 49
      io.sc.platform.core.frontend/template-project/public/index.html
  29. 2
      io.sc.platform.core.frontend/template-project/src/components/index.ts
  30. 16
      io.sc.platform.core.frontend/template-project/src/routes/routes.json
  31. 1
      io.sc.platform.core.frontend/template-project/src/shims-vue.d.ts
  32. 88
      io.sc.platform.core.frontend/template-project/src/views/Editor.vue
  33. 42
      io.sc.platform.core.frontend/template-project/src/views/likm/Dialog.vue
  34. 112
      io.sc.platform.core.frontend/template-project/src/views/likm/Drawer.vue
  35. 428
      io.sc.platform.core.frontend/template-project/src/views/likm/Form.vue
  36. 566
      io.sc.platform.core.frontend/template-project/src/views/likm/Grid.vue
  37. 2
      io.sc.platform.core.frontend/template-project/src/views/likm/InfoPanel.vue
  38. 22
      io.sc.platform.core.frontend/template-project/src/views/likm/Toolbar.vue
  39. 65
      io.sc.platform.core.frontend/template-project/src/views/likm/TreeGrid.vue
  40. 224
      io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/Maxgraph.vue
  41. 25
      io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs
  42. 25
      io.sc.platform.core.frontend/webpack.config.mf.cjs
  43. 1
      io.sc.platform.core.frontend/webpack.env.lib.cjs

2
.gitattributes

@ -0,0 +1,2 @@
# 所有文本文件的行结束符为: 换行符
* text=auto

4
io.sc.engine.rule.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.312",
"platform-core": "8.1.320",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",
@ -113,4 +113,4 @@
"pinia-undo": "0.2.4",
"xml-formatter": "3.6.3"
}
}
}

3
io.sc.engine.rule.frontend/src/views/resources/Resources.vue

@ -345,7 +345,8 @@
},
}"
@row-db-click="
(e, row) => {
(args) => {
console.log(args);
if (row.type !== 'FOLDER') {
designerDialogRef.open(row);
}

1
io.sc.platform.core.frontend/.editorconfig

@ -10,5 +10,6 @@ root = true
charset = utf-8 # 字符集: utf-8
indent_size = 2 # 缩进大小: 2
indent_style = space # 缩进风格: 空格
end_of_line = lf # 行结束符: 换行符
insert_final_newline = true # 是否在文件的最后插入一个空行
trim_trailing_whitespace = true # 是否删除行尾的空格

93
io.sc.platform.core.frontend/.eslintrc.cjs

@ -1,37 +1,68 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
ecmaFeatures: {
jsx : false
}
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
"@typescript-eslint/no-this-alias": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
},
};

95
io.sc.platform.core.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.317",
"version": "8.1.321",
"description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件",
"main": "dist/platform-core.js",
@ -52,93 +52,94 @@
"no-git-checks": true
},
"devDependencies": {
"@babel/core": "7.24.7",
"@babel/preset-env": "7.24.7",
"@babel/core": "7.25.2",
"@babel/preset-env": "7.25.4",
"@babel/preset-typescript": "7.24.7",
"@babel/plugin-transform-class-properties": "7.24.7",
"@babel/plugin-transform-class-properties": "7.25.4",
"@babel/plugin-transform-object-rest-spread": "7.24.7",
"@quasar/app-webpack": "3.13.2",
"@quasar/app-webpack": "4.0.0-beta.16",
"@quasar/cli": "2.4.1",
"@types/mockjs": "1.0.10",
"@types/node": "20.14.10",
"@typescript-eslint/eslint-plugin": "7.15.0",
"@typescript-eslint/parser": "7.15.0",
"@vue/compiler-sfc": "3.4.31",
"@types/node": "22.5.4",
"@typescript-eslint/eslint-plugin": "8.5.0",
"@typescript-eslint/parser": "8.5.0",
"@vue/compiler-sfc": "3.5.3",
"@webpack-cli/serve": "2.0.5",
"autoprefixer": "10.4.19",
"autoprefixer": "10.4.20",
"babel-loader": "9.1.3",
"clean-webpack-plugin": "4.0.0",
"copy-webpack-plugin": "12.0.2",
"cross-env": "7.0.3",
"css-loader": "7.1.2",
"eslint": "8.56.0",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-vue": "9.27.0",
"eslint-plugin-prettier": "5.2.1",
"eslint-plugin-vue": "9.28.0",
"eslint-webpack-plugin": "4.2.0",
"html-webpack-plugin": "5.6.0",
"json5": "2.2.3",
"mini-css-extract-plugin": "2.9.0",
"mini-css-extract-plugin": "2.9.1",
"nodemon": "3.1.4",
"postcss": "8.4.39",
"postcss": "8.4.45",
"postcss-import": "16.1.0",
"postcss-loader": "8.1.1",
"postcss-preset-env": "9.6.0",
"prettier": "3.3.2",
"sass": "1.77.6",
"sass-loader": "14.2.1",
"typescript": "5.5.3",
"postcss-preset-env": "10.0.3",
"prettier": "3.3.3",
"sass": "1.78.0",
"sass-loader": "16.0.1",
"typescript": "5.5.4",
"vue-loader": "17.4.2",
"webpack": "5.92.1",
"webpack": "5.94.0",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4",
"webpack-dev-server": "5.1.0",
"webpack-merge": "6.0.1",
"@vue/babel-plugin-jsx": "1.2.2"
"@vue/babel-plugin-jsx": "1.2.4"
},
"dependencies": {
"@codemirror/autocomplete": "6.17.0",
"@codemirror/commands": "6.6.0",
"@codemirror/autocomplete": "6.18.0",
"@codemirror/commands": "6.6.1",
"@codemirror/lang-html": "6.4.9",
"@codemirror/lang-java": "6.0.1",
"@codemirror/lang-javascript": "6.2.2",
"@codemirror/lang-json": "6.0.1",
"@codemirror/lang-sql": "6.7.0",
"@codemirror/lang-sql": "6.7.1",
"@codemirror/lang-xml": "6.1.0",
"@codemirror/language": "6.10.2",
"@codemirror/search": "6.5.6",
"@codemirror/state": "6.4.1",
"@codemirror/view": "6.28.4",
"@codemirror/view": "6.33.0",
"@maxgraph/core": "0.13.0",
"@quasar/extras": "1.16.12",
"@vueuse/core": "10.11.0",
"axios": "1.7.2",
"@vueuse/core": "11.0.3",
"axios": "1.7.7",
"codemirror": "6.0.1",
"dayjs": "1.11.11",
"dayjs": "1.11.13",
"echarts": "5.5.1",
"exceljs": "4.4.0",
"file-saver": "2.0.5",
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"quasar": "2.15.4",
"pinia": "2.2.2",
"quasar": "2.16.11",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.4",
"vue": "3.4.31",
"tailwindcss": "3.4.10",
"vue": "3.4.38",
"vue-dompurify-html": "5.1.0",
"vue-i18n": "9.13.1",
"vue-router": "4.4.0",
"vue-i18n": "10.0.0",
"vue-router": "4.4.3",
"xml-formatter": "3.6.3",
"@univerjs/core": "0.2.0",
"@univerjs/design": "0.2.0",
"@univerjs/docs": "0.2.0",
"@univerjs/docs-ui": "0.2.0",
"@univerjs/engine-formula": "0.2.0",
"@univerjs/engine-render": "0.2.0",
"@univerjs/facade": "0.2.0",
"@univerjs/sheets": "0.2.0",
"@univerjs/sheets-formula": "0.2.0",
"@univerjs/sheets-ui": "0.2.0",
"@univerjs/ui": "0.2.0"
"@univerjs/core": "0.2.12",
"@univerjs/design": "0.2.12",
"@univerjs/docs": "0.2.12",
"@univerjs/docs-ui": "0.2.12",
"@univerjs/engine-formula": "0.2.12",
"@univerjs/engine-render": "0.2.12",
"@univerjs/facade": "0.2.12",
"@univerjs/sheets": "0.2.12",
"@univerjs/sheets-formula": "0.2.12",
"@univerjs/sheets-ui": "0.2.12",
"@univerjs/thread-comment": "0.2.12",
"@univerjs/ui": "0.2.12"
}
}

BIN
io.sc.platform.core.frontend/public/images/point.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 B

49
io.sc.platform.core.frontend/public/index.html

@ -29,27 +29,34 @@
<script>
(function () {
"use strict";
window.addEventListener("load", function () {
var box, div, link, namespaceURI;
// First check whether the page contains any <math> element.
namespaceURI = "http://www.w3.org/1998/Math/MathML";
if (document.body.getElementsByTagNameNS(namespaceURI, "math")[0]) {
// Create a div to test mspace, using Kuma's "offscreen" CSS
document.body.insertAdjacentHTML("afterbegin", "<div style='border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px;'><math xmlns='" + namespaceURI + "'><mspace height='23px' width='77px'></mspace></math></div>");
div = document.body.firstChild;
box = div.firstChild.firstChild.getBoundingClientRect();
document.body.removeChild(div);
if (Math.abs(box.height - 23) > 1 || Math.abs(box.width - 77) > 1) {
// Insert the mathml.css stylesheet.
link = document.createElement("link");
link.href = '[(@{/webjars/mathfonts/1.0.0/mathml.css})]'.startsWith('[')? 'http://localhost:8080/webjars/mathfonts/1.0.0/mathml.css' : '[(@{/webjars/mathfonts/1.0.0/mathml.css})]';
link.rel = "stylesheet";
document.head.appendChild(link);
}
}
});
}());
'use strict';
window.addEventListener('load', function () {
var box, div, link, namespaceURI;
// First check whether the page contains any <math> element.
namespaceURI = 'http://www.w3.org/1998/Math/MathML';
if (document.body.getElementsByTagNameNS(namespaceURI, 'math')[0]) {
// Create a div to test mspace, using Kuma's "offscreen" CSS
document.body.insertAdjacentHTML(
'afterbegin',
"<div style='border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px;'><math xmlns='" +
namespaceURI +
"'><mspace height='23px' width='77px'></mspace></math></div>",
);
div = document.body.firstChild;
box = div.firstChild.firstChild.getBoundingClientRect();
document.body.removeChild(div);
if (Math.abs(box.height - 23) > 1 || Math.abs(box.width - 77) > 1) {
// Insert the mathml.css stylesheet.
link = document.createElement('link');
link.href = '[(@{/webjars/mathfonts/1.0.0/mathml.css})]'.startsWith('[')
? 'http://localhost:8080/webjars/mathfonts/1.0.0/mathml.css'
: '[(@{/webjars/mathfonts/1.0.0/mathml.css})]';
link.rel = 'stylesheet';
document.head.appendChild(link);
}
}
});
})();
</script>
</head>
<body>

52
io.sc.platform.core.frontend/src/platform/components/graph/PlatformGraph.ts

@ -1,5 +1,19 @@
import type { GraphPluginConstructor } from '@maxgraph/core';
import { constants, Client, Graph, Point, Cell, Geometry, CellState, ConnectionConstraint, ModelXmlSerializer, styleUtils, eventUtils } from '@maxgraph/core';
import {
constants,
Client,
Graph,
Point,
Cell,
Geometry,
ImageBox,
CellState,
ConnectionConstraint,
ModelXmlSerializer,
styleUtils,
eventUtils,
xmlUtils,
} from '@maxgraph/core';
import {
CellEditorHandler,
@ -13,6 +27,7 @@ import {
} from '@maxgraph/core'; // 默认插件
import {
PlatformConstraintHandler,
PlatformDragAndDropHandler,
PlatformEdgeDefineHandler,
PlatformKeyBindHandler,
@ -38,6 +53,7 @@ const plugins: GraphPluginConstructor[] = [
SelectionCellsHandler,
SelectionHandler,
PlatformConstraintHandler,
PlatformDragAndDropHandler,
PlatformEdgeDefineHandler,
PlatformKeyBindHandler,
@ -52,9 +68,6 @@ class PlatformGraph extends Graph {
this.setConnectable(true);
this.setPanning(true);
this.setHtmlLabels(true);
// this.isCellEditable = function (cell) {
// return !cell.isEdge();
// };
// 禁止节点直接连接
const connectionHandler: ConnectionHandler = this.getPlugin<ConnectionHandler>('ConnectionHandler');
@ -100,32 +113,29 @@ class PlatformGraph extends Graph {
convertValueToString(cell) {
if (cell.isVertex()) {
const dom = cell.value;
const type = dom.nodeName.toLowerCase();
const type = dom.nodeName;
const vertexDefineHandler: PlatformVertexDefineHandler = this.getPlugin<PlatformVertexDefineHandler>('PlatformVertexDefineHandler');
if (vertexDefineHandler) {
const value = vertexDefineHandler.getValue(type, dom);
return vertexDefineHandler.getLabel(type, value);
}
} else if (cell.isEdge()) {
const dom = cell.value;
const type = dom.nodeName;
const edgeDefineHandler: PlatformEdgeDefineHandler = this.getPlugin<PlatformEdgeDefineHandler>('PlatformEdgeDefineHandler');
if (edgeDefineHandler) {
const value = edgeDefineHandler.getValue(type, dom);
return edgeDefineHandler.getLabel(type, value);
}
} else {
return null;
}
return null;
}
createEdge(parent = null, id, value, source = null, target = null, style = {}) {
const sourceCell: Cell = source;
const targetCell: Cell = target;
const sourceType = sourceCell.value.nodeName.toLowerCase();
const targetType = targetCell.value.nodeName.toLowerCase();
const ddgeDefineHandler: PlatformEdgeDefineHandler = this.getPlugin<PlatformEdgeDefineHandler>('PlatformEdgeDefineHandler');
if (ddgeDefineHandler) {
const type = ddgeDefineHandler.getType(sourceType, targetType);
const dom = document.createElement(type);
dom.setAttribute('wsp', 'wsp');
const edge = new Cell(dom, new Geometry(), style);
edge.setId(id);
edge.setEdge(true);
edge.geometry.relative = true;
return edge;
const edgeDefineHandler: PlatformEdgeDefineHandler = this.getPlugin<PlatformEdgeDefineHandler>('PlatformEdgeDefineHandler');
if (edgeDefineHandler) {
return edgeDefineHandler.createEdge(parent, id, value, source, target, style);
}
}

109
io.sc.platform.core.frontend/src/platform/components/graph/WGraph.vue

@ -1,7 +1,7 @@
<template>
<div class="border border-gray-200" style="height: 100%">
<q-toolbar class="border-b border-gray-200" style="height: 50px; padding-top: 6px; padding-bottom: 6px">
<q-btn :title="$t('save')" stretch flat no-caps icon="bi-floppy" padding="4px 6px" />
<q-btn :title="$t('save')" stretch flat no-caps icon="bi-floppy" padding="4px 6px" @click="save" />
<q-separator vertical inset spaced="sm" />
<q-btn :title="$t('xml')" stretch flat no-caps icon="bi-filetype-xml" padding="4px 6px" @click="showXml"></q-btn>
<q-separator vertical inset spaced="sm" />
@ -15,18 +15,8 @@
<q-btn :title="$t('paste')" stretch flat no-caps icon="fa-regular fa-paste" padding="4px 6px" @click="paste"></q-btn>
<q-btn :title="$t('cut')" stretch flat no-caps icon="bi-scissors" padding="4px 6px" @click="cut"></q-btn>
<q-btn :title="$t('delete')" stretch flat no-caps icon="bi-trash" padding="4px 6px" @click="remove"></q-btn>
<q-separator vertical inset spaced="sm" />
<q-btn :title="$t('graph.toolbar.actions.top')" stretch flat no-caps icon="bi-front" padding="4px 6px"></q-btn>
<q-btn :title="$t('graph.toolbar.actions.bottom')" stretch flat no-caps icon="bi-subtract" padding="4px 6px"></q-btn>
<q-separator vertical inset spaced="sm" />
<q-btn-dropdown :title="$t('graph.toolbar.actions.connection')" stretch flat icon="bi-arrow-right" padding="4px 6px">
<q-list>
<q-item-label header>Folders</q-item-label>
</q-list>
</q-btn-dropdown>
<q-btn-dropdown :title="$t('graph.toolbar.actions.path')" stretch flat icon="bi-bezier2" padding="4px 6px"> </q-btn-dropdown>
</q-toolbar>
<q-splitter v-model="vertexPanelWidthRef" unit="px" style="height: calc(100% - 50px)">
<q-splitter v-model="vertexPanelWidthRef" :unit="vertexPanelWidthUnitRef" style="height: calc(100% - 50px)">
<template #before>
<div class="flex items-center p-1">
<div v-for="(vertexDefine, index) in vertexDefines" :key="index">
@ -38,7 +28,7 @@
</template>
<template #after>
<q-splitter v-model="propertiesPanelWidthRef" unit="px" reverse style="height: 100%">
<q-splitter v-model="propertiesPanelWidthRef" :unit="propertiesPanelWidthUnitRef" reverse style="height: 100%">
<template #before>
<div style="height: 100%">
<div
@ -55,12 +45,12 @@
</template>
<template #after>
<div class="px-1" style="height: 100%">
<q-tabs v-model="currentSelectedTabNameRef" inline-label shrink outside-arrows mobile-arrows>
<q-tabs v-model="currentSelectedTabNameRef" inline-label shrink outside-arrows mobile-arrows align="left" :breakpoint="0">
<q-tab name="properties" no-caps :label="$t('graph.setting.panel.properties.title')" />
</q-tabs>
<q-tab-panels v-model="currentSelectedTabNameRef" animated swipeable keep-alive style="height: calc(100% - 48px)">
<q-tab-panel name="properties" class="px-0 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
<w-form v-model="selectedCellReactive.modelValue" :cols-num="1" :fields="selectedCellReactive.fields" @update-value="onUpdateValue"></w-form>
<w-form v-model="selectedCellReactive.modelValue" :cols-num="1" :fields="selectedCellReactive.fields" @update-value="updateValue"></w-form>
</q-tab-panel>
</q-tab-panels>
</div>
@ -75,41 +65,80 @@
import { ref, onMounted, nextTick, reactive } from 'vue';
import { InternalEvent, CellAttributeChange } from '@maxgraph/core';
import { Tools } from '@/platform';
import { FormFieldProps, FormFieldMethods } from '@/platform/components/form/FormField';
import { PlatformSelectedCellHandler } from './handler/SelectedCellHandler';
import { PlatformGraph } from './PlatformGraph';
import XmlDialog from './dialog/XmlDialog.vue';
const modelValueRef = defineModel({ type: String, default: '' });
const props = defineProps({
vertexPanelWidth: {
type: Number,
default: 65,
},
propertiesPanelWidth: {
type: Number,
default: 400,
},
vertexDefines: {
type: Array,
default: () => {
return [];
},
interface FieldProps extends FormFieldProps {
//
vertexPanelWidth?: number;
//
vertexPanelWidthUnit: string;
//
propertiesPanelWidth?: number;
//
propertiesPanelWidthUnit?: string;
//
vertexDefines: [];
//
edgeDefines: [];
}
const props = withDefaults(defineProps<FieldProps>(), {
vertexPanelWidth: 65,
vertexPanelWidthUnit: 'px',
propertiesPanelWidth: 400,
propertiesPanelWidthUnit: 'px',
vertexDefines: () => {
return [];
},
edgeDefines: {
type: Array,
default: () => {
return [];
},
edgeDefines: () => {
return [];
},
});
const vertexPanelWidthRef = ref(props.vertexPanelWidth);
const propertiesPanelWidthRef = ref(props.propertiesPanelWidth);
const emit = defineEmits<{
//
(e: 'save', value: string): void;
}>();
class FieldMethods extends FormFieldMethods {
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({
value: value_,
form: props['form'],
});
}
};
validate = () => {
return true;
};
setValue = (value_) => {
modelValueRef.value = value_;
};
getValue = () => {
return modelValueRef.value;
};
clearValue = () => {
modelValueRef.value = '';
};
}
const fieldMethodsClass = new FieldMethods();
const vertexPanelWidthRef = ref<number>(props.vertexPanelWidth);
const vertexPanelWidthUnitRef = ref(props.vertexPanelWidthUnit);
const propertiesPanelWidthRef = ref<number>(props.propertiesPanelWidth);
const propertiesPanelWidthUnitRef = ref(props.propertiesPanelWidthUnit);
const currentSelectedTabNameRef = ref('properties');
const graphContainerRef = ref();
const selectedCellReactive = reactive({
modelValue: {},
fields: [],
});
const graphContainerRef = ref();
const xmlDialogRef = ref();
let graph: PlatformGraph;
@ -131,6 +160,10 @@ const generateSvg = (vertexDefine) => {
return svg;
};
const save = () => {
emit('save', graph.getXml());
};
const showXml = () => {
modelValueRef.value = graph.getXml();
nextTick(() => {
@ -179,7 +212,7 @@ const dragstart = (event, thumbnail) => {
event.dataTransfer.setData('data', Tools.object2Json(data));
};
const onUpdateValue = (arg) => {
const updateValue = (arg) => {
const selectedCellHandler = graph.getPlugin<PlatformSelectedCellHandler>('PlatformSelectedCellHandler');
if (selectedCellHandler) {
selectedCellHandler.updateCell(arg);

13
io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformConstraintHandler.ts

@ -0,0 +1,13 @@
import { Graph, GraphPlugin, ConstraintHandler, ImageBox } from '@maxgraph/core';
export class PlatformConstraintHandler extends ConstraintHandler implements GraphPlugin {
public static pluginId: string = 'PlatformConstraintHandler';
constructor(graph: Graph) {
super(graph);
const pointImage = new ImageBox('data:image/gif;base64,R0lGODlhBQAFAJECAAAA/////////wAAACH5BAEAAAIALAAAAAAFAAUAAAIIRBSml7yGQAEAOw==', 5, 5);
ConstraintHandler.prototype.getImageForConstraint = (state, constraint, point) => {
return pointImage;
};
}
}

48
io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformDragAndDropHandler.ts

@ -1,4 +1,4 @@
import { Graph, VertexParameters, GraphPlugin, InternalEvent, styleUtils, eventUtils, CellState } from '@maxgraph/core';
import { Graph, VertexParameters, GraphPlugin, InternalEvent, styleUtils, eventUtils, xmlUtils, CellState } from '@maxgraph/core';
import { PlatformVertexDefineHandler } from './PlatformVertexDefineHandler';
import { Tools } from '@/platform';
@ -21,33 +21,29 @@ export class PlatformDragAndDropHandler implements GraphPlugin {
event.stopPropagation();
event.preventDefault();
const view = this.graph.getView();
const pt = styleUtils.convertPoint(this.graph.getContainer(), eventUtils.getClientX(event), eventUtils.getClientY(event));
const tr = view.getTranslate();
const scale = view.getScale();
const x = pt.x / scale - tr.x;
const y = pt.y / scale - tr.y;
const pt = this.graph.getPointForEvent(event);
this.graph.batchUpdate(() => {
const data = Tools.json2Object(event.dataTransfer.getData('data'));
const type = data.type;
const element = document.createElement(type);
const vertexDefineHandler: PlatformVertexDefineHandler = this.graph.getPlugin<PlatformVertexDefineHandler>('PlatformVertexDefineHandler');
if (vertexDefineHandler) {
const value = vertexDefineHandler.getValue(type) || {};
for (const fieldName in value) {
element.setAttribute(fieldName, value[fieldName]);
}
const data = Tools.json2Object(event.dataTransfer.getData('data'));
const type = data.type;
const doc = xmlUtils.createXmlDocument();
const element = doc.createElement(type);
const vertexDefineHandler: PlatformVertexDefineHandler = this.graph.getPlugin<PlatformVertexDefineHandler>('PlatformVertexDefineHandler');
if (vertexDefineHandler) {
const value = vertexDefineHandler.getValue(type) || {};
for (const fieldName in value) {
element.setAttribute(fieldName, value[fieldName]);
}
const vertexParameters: VertexParameters = {
value: element,
parent: this.graph.getDefaultParent(),
size: data.size,
position: [x - data.size[0] / 2, y - data.size[1] / 2],
style: {
shape: data.shape,
},
};
}
const vertexParameters: VertexParameters = {
value: element,
parent: this.graph.getDefaultParent(),
size: data.size,
position: [pt.x - data.size[0] / 2, pt.y - data.size[1] / 2],
style: {
shape: data.shape,
},
};
this.graph.batchUpdate(() => {
const vertex = this.graph.insertVertex(vertexParameters);
this.graph.setSelectionCell(vertex);
});

57
io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformEdgeDefineHandler.ts

@ -1,13 +1,42 @@
import { Graph, GraphPlugin } from '@maxgraph/core';
import { Graph, GraphPlugin, Cell, Geometry, xmlUtils } from '@maxgraph/core';
export class PlatformEdgeDefineHandler implements GraphPlugin {
public static pluginId: string = 'PlatformEdgeDefineHandler';
private graph: Graph;
private defines = {};
private defines = {
Connection: {
type: 'Connection',
fromVertexType: null,
toVertexType: null,
getLabel: (value) => {
return value.label;
},
getValue: (dom) => {
if (dom) {
return {
label: dom.getAttribute('label'),
};
} else {
return {
label: '',
};
}
},
getFormFields: () => {
return [
{
name: 'label',
label: 'label',
type: 'w-text',
},
];
},
},
};
setDefines(configures) {
for (const configure of configures) {
this.defines[configure.type.toLowerCase()] = {
this.defines[configure.type] = {
fromVertexType: configure.fromVertexType,
toVertexType: configure.toVertexType,
getLabel: configure.getLabel,
@ -17,12 +46,25 @@ export class PlatformEdgeDefineHandler implements GraphPlugin {
}
}
createEdge(parent = null, id, value, source = null, target = null, style = {}) {
const sourceType = source.value.nodeName;
const targetType = target.value.nodeName;
const type = this.getType(sourceType, targetType);
const doc = xmlUtils.createXmlDocument();
const element = doc.createElement(type);
const edge = new Cell(element, new Geometry(), style);
edge.setEdge(true);
return edge;
}
getType(fromType, toType) {
for (const define in this.defines) {
if (define.fromVertexType === fromType && define.toType === toType) {
return define;
for (const type in this.defines) {
const define = this.defines[type];
if ((define.fromVertexType === fromType && define.toVertexType === toType) || define.fromVertexType === fromType || define.toVertexType === toType) {
return type;
}
}
return 'Connection';
}
getLabel(type, value) {
@ -33,6 +75,7 @@ export class PlatformEdgeDefineHandler implements GraphPlugin {
}
getValue(type, dom) {
console.log(type, dom);
if (this.defines[type]?.getValue) {
return this.defines[type]?.getValue(dom);
} else {
@ -56,7 +99,5 @@ export class PlatformEdgeDefineHandler implements GraphPlugin {
}
}
createEdge(parent = null, id, value, source = null, target = null, style = {}) {}
onDestroy() {}
}

13
io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformSelectedCellHandler.ts

@ -22,7 +22,7 @@ export class PlatformSelectedCellHandler implements GraphPlugin {
}
if (cell.isVertex()) {
const dom = cell.value;
const type = dom.nodeName.toLowerCase();
const type = dom.nodeName;
const vertexDefineHandler: PlatformVertexDefineHandler = this.graph.getPlugin<PlatformVertexDefineHandler>('PlatformVertexDefineHandler');
if (vertexDefineHandler) {
const value = vertexDefineHandler.getValue(type, cell);
@ -35,7 +35,7 @@ export class PlatformSelectedCellHandler implements GraphPlugin {
}
} else {
const dom = cell.value;
const type = dom.nodeName.toLowerCase();
const type = dom.nodeName;
const edgeDefineHandler: PlatformEdgeDefineHandler = this.graph.getPlugin<PlatformEdgeDefineHandler>('PlatformEdgeDefineHandler');
if (edgeDefineHandler) {
const value = edgeDefineHandler.getValue(type, cell);
@ -58,16 +58,17 @@ export class PlatformSelectedCellHandler implements GraphPlugin {
updateCell(arg) {
this.graph.batchUpdate(() => {
let cell = this.graph.getSelectionCell();
if (Tools.isArray(cell)) {
cell = cell[0];
const cell = this.graph.getSelectionCell();
if (!cell) {
return;
}
const dom = cell.value;
const formData = arg.form.getData();
for (const field in formData) {
dom.setAttribute(field, formData[field]);
}
const edit = new ValueChange(this.graph.getDataModel(), this.graph.getSelectionCell(), dom);
console.log(dom);
const edit = new ValueChange(this.graph.getDataModel(), cell, dom);
this.graph.getDataModel().execute(edit);
//this.graph.updateCellSize(cell);
});

2
io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformVertexDefineHandler.ts

@ -11,7 +11,7 @@ export class PlatformVertexDefineHandler implements GraphPlugin {
setDefines(configures) {
for (const configure of configures) {
this.defines[configure.type.toLowerCase()] = {
this.defines[configure.type] = {
getLabel: configure.getLabel,
getValue: configure.getValue,
getFormFields: configure.getFormFields,

14
io.sc.platform.core.frontend/src/platform/components/graph/handler/index.ts

@ -1,11 +1,13 @@
import { PlatformDragAndDropHandler } from '@/platform/components/graph/handler/PlatformDragAndDropHandler';
import { PlatformEdgeDefineHandler } from '@/platform/components/graph/handler/PlatformEdgeDefineHandler';
import { PlatformKeyBindHandler } from '@/platform/components/graph/handler/PlatformKeyBindHandler';
import { PlatformSelectedCellHandler } from '@/platform/components/graph/handler/PlatformSelectedCellHandler';
import { PlatformVertexDefineHandler } from '@/platform/components/graph/handler/PlatformVertexDefineHandler';
import { PlatformUndoManagerHandler } from '@/platform/components/graph/handler/PlatformUndoManagerHandler';
import { PlatformConstraintHandler } from './PlatformConstraintHandler';
import { PlatformDragAndDropHandler } from './PlatformDragAndDropHandler';
import { PlatformEdgeDefineHandler } from './PlatformEdgeDefineHandler';
import { PlatformKeyBindHandler } from './PlatformKeyBindHandler';
import { PlatformSelectedCellHandler } from './PlatformSelectedCellHandler';
import { PlatformVertexDefineHandler } from './PlatformVertexDefineHandler';
import { PlatformUndoManagerHandler } from './PlatformUndoManagerHandler';
export {
PlatformConstraintHandler,
PlatformDragAndDropHandler,
PlatformEdgeDefineHandler,
PlatformKeyBindHandler,

125
io.sc.platform.core.frontend/src/platform/plugin/quasar-components.ts

@ -0,0 +1,125 @@
export {
QAjaxBar,
QAvatar,
QBadge,
QBanner,
QBar,
QBreadcrumbs,
QBreadcrumbsEl,
QBtn,
QBtnDropdown,
QBtnGroup,
QBtnToggle,
QCard,
QCardSection,
QCardActions,
QCarousel,
QCarouselSlide,
QCarouselControl,
QChatMessage,
QCheckbox,
QChip,
QCircularProgress,
QColor,
QDate,
QDialog,
QDrawer,
QEditor,
QExpansionItem,
QFab,
QFabAction,
QField,
QFile,
QFooter,
QForm,
QFormChildMixin,
QHeader,
QIcon,
QImg,
QInfiniteScroll,
QInnerLoading,
QInput,
QIntersection,
QList,
QItem,
QItemSection,
QItemLabel,
QKnob,
QLayout,
QLinearProgress,
QMarkupTable,
QMenu,
QNoSsr,
QOptionGroup,
QPage,
QPageContainer,
QPageScroller,
QPageSticky,
QPagination,
QParallax,
QPopupEdit,
QPopupProxy,
QPullToRefresh,
QRadio,
QRange,
QRating,
QResizeObserver,
QResponsive,
QScrollArea,
QScrollObserver,
QSelect,
QSeparator,
QSkeleton,
QSlideItem,
QSlideTransition,
QSlider,
QSpace,
QSpinner,
QSpinnerAudio,
QSpinnerBall,
QSpinnerBars,
QSpinnerBox,
QSpinnerClock,
QSpinnerComment,
QSpinnerCube,
QSpinnerDots,
QSpinnerFacebook,
QSpinnerGears,
QSpinnerGrid,
QSpinnerHearts,
QSpinnerHourglass,
QSpinnerInfinity,
QSpinnerIos,
QSpinnerOrbit,
QSpinnerOval,
QSpinnerPie,
QSpinnerPuff,
QSpinnerRadio,
QSpinnerRings,
QSpinnerTail,
QSplitter,
QStep,
QStepper,
QStepperNavigation,
QTabPanels,
QTabPanel,
QTable,
QTh,
QTr,
QTd,
QTabs,
QTab,
QRouteTab,
QTime,
QTimeline,
QTimelineEntry,
QToggle,
QToolbar,
QToolbarTitle,
QTooltip,
QTree,
QUploader,
QUploaderAddTrigger,
QVideo,
QVirtualScroll,
} from 'quasar';

1
io.sc.platform.core.frontend/src/platform/plugin/quasar-directives.ts

@ -0,0 +1 @@
export { ClosePopup, Intersection, Morph, Mutation, Ripple, ScrollFire, Scroll, TouchHold, TouchPan, TouchRepeat, TouchSwipe } from 'quasar';

14
io.sc.platform.core.frontend/src/platform/plugin/quasar-plugins.ts

@ -0,0 +1,14 @@
export {
AddressbarColor,
AppFullscreen,
AppVisibility,
BottomSheet,
Cookies,
Dialog,
Loading,
LoadingBar,
LocalStorage,
SessionStorage,
Meta,
Notify,
} from 'quasar';

40
io.sc.platform.core.frontend/src/platform/plugin/quasar.ts

@ -1,27 +1,18 @@
import type { App } from 'vue';
import { EventBus } from 'quasar';
import type { I18nMessageLocaleType } from '@/platform/types';
import { EventBus } from 'quasar';
import { Environment } from '@/platform/plugin/environment';
import { I18nMessageManager } from '@/platform/plugin/manager';
import { Tools } from '@/platform/utils/Tools';
const gc = Environment.getConfigure();
const eventBus: any = new EventBus();
import {
Quasar,
AddressbarColor,
AppFullscreen,
AppVisibility,
BottomSheet,
Cookies,
Dialog,
Loading,
LoadingBar,
LocalStorage,
SessionStorage,
Meta,
Notify,
} from 'quasar';
import { Quasar } from 'quasar';
import * as quasarComponents from './quasar-components';
import * as quasarDirectives from './quasar-directives';
import * as quasarPlugins from './quasar-plugins';
export default {
install: (app: App) => {
@ -41,20 +32,9 @@ export default {
},
},
},
plugins: {
AddressbarColor,
AppFullscreen,
AppVisibility,
BottomSheet,
Cookies,
Dialog,
Loading,
LoadingBar,
LocalStorage,
SessionStorage,
Meta,
Notify,
},
components: quasarComponents,
directives: quasarDirectives,
plugins: quasarPlugins,
});
// 初始化 quasar 语言

8
io.sc.platform.core.frontend/src/platform/utils/JavascriptLoader.ts

@ -25,7 +25,9 @@ class JavascriptLoader {
const element = this.#urlMap.get(url);
if (element) {
element.onerror = element.onload = null;
element.parentNode && element.parentNode.removeChild(element);
if (element.parentNode) {
element.parentNode.removeChild(element);
}
}
this.#urlMap.delete(url);
if (this.#urlMap.size <= 0 && !this.#failed) {
@ -38,7 +40,9 @@ class JavascriptLoader {
const element = this.#urlMap.get(url);
if (element) {
element.onerror = element.onload = null;
element.parentNode && element.parentNode.removeChild(element);
if (element.parentNode) {
element.parentNode.removeChild(element);
}
}
this.#urlMap.delete(url);
if (!this.#failed) {

16
io.sc.platform.core.frontend/src/platform/utils/Tools.ts

@ -123,6 +123,22 @@ class Tools {
return `${h % 12 === 0 ? 12 : h % 12}${h < 12 ? ' am.' : ' pm.'}`;
}
/**
* 使线,. :'getElementById'=>'get-element-by-id'
* @param str
* @returns
*/
public static getKebabCase(str: string): string {
const result = str.replace(/[A-Z]/g, function (i) {
return '-' + i.toLowerCase();
});
if (result.startsWith('-')) {
return result.substring(1);
} else {
return result;
}
}
/**
*
* @param param0

1
io.sc.platform.core.frontend/src/shims-vue.d.ts

@ -1,3 +1,4 @@
/* eslint-disable */
import type { AppType } from '@/platform/types';
declare global {

40
io.sc.platform.core.frontend/src/views/testcase/maxgraph/maxgraph.vue

@ -7,8 +7,8 @@ import { $t } from '@/platform';
const edgeDefines = [
{
type: 'condition',
fromVertexType: 'condition',
type: 'ConditionBranch',
fromVertexType: 'Condition',
toVertexType: null,
getLabel: (value) => {
return value.value;
@ -16,7 +16,9 @@ const edgeDefines = [
getValue: (dom) => {
if (dom) {
return {
condition: dom.getAttribute('condition'),
valueType: dom.getAttribute('valueType'),
value: dom.getAttribute('value'),
commands: dom.getAttribute('commands'),
};
} else {
return {
@ -55,31 +57,43 @@ const edgeDefines = [
const vertexDefines = [
{
type: 'start',
type: 'Start',
thumbnail: { shape: 'ellipse', label: $t('start'), rx: 8, ry: 8, strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'ellipse',
size: [50, 50],
},
getLabel: (value) => {
return $t('start');
return value.label;
},
getValue: (dom) => {
return {};
if (dom) {
return {
label: dom.getAttribute('label'),
};
} else {
return { label: $t('start') };
}
},
getFormFields: () => {
return [];
return [
{
name: 'label',
label: 'label',
type: 'w-text',
},
];
},
},
{
type: 'condition',
type: 'Condition',
thumbnail: { shape: 'rhombus', label: $t('condition'), strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'rhombus',
size: [120, 60],
},
getLabel: (value) => {
return value.condition;
return value.condition ? value.condition : $t('condition');
},
getValue: (dom) => {
if (dom) {
@ -88,7 +102,7 @@ const vertexDefines = [
};
} else {
return {
condition: $t('condition'),
condition: '',
};
}
},
@ -108,7 +122,7 @@ const vertexDefines = [
},
},
{
type: 'expression',
type: 'Expression',
thumbnail: { shape: 'rectangle', label: $t('expression'), strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'rectangle',
@ -151,8 +165,8 @@ const vertexDefines = [
},
},
{
type: 'resourceabstract',
thumbnail: { shape: 'ellipse', label: '资源摘要', rx: 10, ry: 6, strokeColor: 'black', strokeWidth: 1 },
type: 'ResourceAbstract',
thumbnail: { shape: 'ellipse', label: '资源摘要', rx: 11, ry: 6, strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'ellipse',
size: [120, 60],

1
io.sc.platform.core.frontend/template-project/.editorconfig

@ -10,5 +10,6 @@ root = true
charset = utf-8 # 字符集: utf-8
indent_size = 2 # 缩进大小: 2
indent_style = space # 缩进风格: 空格
end_of_line = lf # 行结束符: 换行符
insert_final_newline = true # 是否在文件的最后插入一个空行
trim_trailing_whitespace = true # 是否删除行尾的空格

91
io.sc.platform.core.frontend/template-project/.eslintrc.cjs

@ -1,35 +1,68 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
ecmaFeatures: {
jsx : false
}
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
'no-prototype-builtins': 'off',
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
},
};

97
io.sc.platform.core.frontend/template-project/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.316",
"version": "8.1.321",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -24,94 +24,95 @@
"no-git-checks": true
},
"devDependencies": {
"@babel/core": "7.24.7",
"@babel/preset-env": "7.24.7",
"@babel/core": "7.25.2",
"@babel/preset-env": "7.25.4",
"@babel/preset-typescript": "7.24.7",
"@babel/plugin-transform-class-properties": "7.24.7",
"@babel/plugin-transform-class-properties": "7.25.4",
"@babel/plugin-transform-object-rest-spread": "7.24.7",
"@quasar/app-webpack": "3.13.2",
"@quasar/app-webpack": "4.0.0-beta.16",
"@quasar/cli": "2.4.1",
"@types/mockjs": "1.0.10",
"@types/node": "20.14.10",
"@typescript-eslint/eslint-plugin": "7.15.0",
"@typescript-eslint/parser": "7.15.0",
"@vue/compiler-sfc": "3.4.31",
"@types/node": "22.5.4",
"@typescript-eslint/eslint-plugin": "8.5.0",
"@typescript-eslint/parser": "8.5.0",
"@vue/compiler-sfc": "3.5.3",
"@webpack-cli/serve": "2.0.5",
"autoprefixer": "10.4.19",
"autoprefixer": "10.4.20",
"babel-loader": "9.1.3",
"clean-webpack-plugin": "4.0.0",
"copy-webpack-plugin": "12.0.2",
"cross-env": "7.0.3",
"css-loader": "7.1.2",
"eslint": "8.56.0",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-vue": "9.27.0",
"eslint-plugin-prettier": "5.2.1",
"eslint-plugin-vue": "9.28.0",
"eslint-webpack-plugin": "4.2.0",
"html-webpack-plugin": "5.6.0",
"json5": "2.2.3",
"mini-css-extract-plugin": "2.9.0",
"mini-css-extract-plugin": "2.9.1",
"nodemon": "3.1.4",
"postcss": "8.4.39",
"postcss": "8.4.45",
"postcss-import": "16.1.0",
"postcss-loader": "8.1.1",
"postcss-preset-env": "9.6.0",
"prettier": "3.3.2",
"sass": "1.77.6",
"sass-loader": "14.2.1",
"typescript": "5.5.3",
"postcss-preset-env": "10.0.3",
"prettier": "3.3.3",
"sass": "1.78.0",
"sass-loader": "16.0.1",
"typescript": "5.5.4",
"vue-loader": "17.4.2",
"webpack": "5.92.1",
"webpack": "5.94.0",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.0.4",
"webpack-dev-server": "5.1.0",
"webpack-merge": "6.0.1",
"@vue/babel-plugin-jsx": "1.2.2"
"@vue/babel-plugin-jsx": "1.2.4"
},
"dependencies": {
"@codemirror/autocomplete": "6.17.0",
"@codemirror/commands": "6.6.0",
"@codemirror/autocomplete": "6.18.0",
"@codemirror/commands": "6.6.1",
"@codemirror/lang-html": "6.4.9",
"@codemirror/lang-java": "6.0.1",
"@codemirror/lang-javascript": "6.2.2",
"@codemirror/lang-json": "6.0.1",
"@codemirror/lang-sql": "6.7.0",
"@codemirror/lang-sql": "6.7.1",
"@codemirror/lang-xml": "6.1.0",
"@codemirror/language": "6.10.2",
"@codemirror/search": "6.5.6",
"@codemirror/state": "6.4.1",
"@codemirror/view": "6.28.4",
"@codemirror/view": "6.33.0",
"@maxgraph/core": "0.13.0",
"@quasar/extras": "1.16.12",
"@univerjs/core": "0.2.0",
"@univerjs/design": "0.2.0",
"@univerjs/docs": "0.2.0",
"@univerjs/docs-ui": "0.2.0",
"@univerjs/engine-formula": "0.2.0",
"@univerjs/engine-render": "0.2.0",
"@univerjs/facade": "0.2.0",
"@univerjs/sheets": "0.2.0",
"@univerjs/sheets-formula": "0.2.0",
"@univerjs/sheets-ui": "0.2.0",
"@univerjs/ui": "0.2.0",
"@vueuse/core": "10.11.0",
"axios": "1.7.2",
"@univerjs/core": "0.2.12",
"@univerjs/design": "0.2.12",
"@univerjs/docs": "0.2.12",
"@univerjs/docs-ui": "0.2.12",
"@univerjs/engine-formula": "0.2.12",
"@univerjs/engine-render": "0.2.12",
"@univerjs/facade": "0.2.12",
"@univerjs/sheets": "0.2.12",
"@univerjs/sheets-formula": "0.2.12",
"@univerjs/sheets-ui": "0.2.12",
"@univerjs/thread-comment": "0.2.12",
"@univerjs/ui": "0.2.12",
"@vueuse/core": "11.0.3",
"axios": "1.7.7",
"codemirror": "6.0.1",
"dayjs": "1.11.11",
"dayjs": "1.11.13",
"echarts": "5.5.1",
"exceljs": "4.4.0",
"file-saver": "2.0.5",
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.316",
"quasar": "2.15.4",
"pinia": "2.2.2",
"platform-core": "8.1.321",
"quasar": "2.16.11",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.4",
"vue": "3.4.31",
"tailwindcss": "3.4.10",
"vue": "3.4.38",
"vue-dompurify-html": "5.1.0",
"vue-i18n": "9.13.1",
"vue-router": "4.4.0",
"vue-i18n": "10.0.0",
"vue-router": "4.4.3",
"xml-formatter": "3.6.3"
}
}

49
io.sc.platform.core.frontend/template-project/public/index.html

@ -29,27 +29,34 @@
<script>
(function () {
"use strict";
window.addEventListener("load", function () {
var box, div, link, namespaceURI;
// First check whether the page contains any <math> element.
namespaceURI = "http://www.w3.org/1998/Math/MathML";
if (document.body.getElementsByTagNameNS(namespaceURI, "math")[0]) {
// Create a div to test mspace, using Kuma's "offscreen" CSS
document.body.insertAdjacentHTML("afterbegin", "<div style='border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px;'><math xmlns='" + namespaceURI + "'><mspace height='23px' width='77px'></mspace></math></div>");
div = document.body.firstChild;
box = div.firstChild.firstChild.getBoundingClientRect();
document.body.removeChild(div);
if (Math.abs(box.height - 23) > 1 || Math.abs(box.width - 77) > 1) {
// Insert the mathml.css stylesheet.
link = document.createElement("link");
link.href = '[(@{/webjars/mathfonts/1.0.0/mathml.css})]'.startsWith('[')? 'http://localhost:8080/webjars/mathfonts/1.0.0/mathml.css' : '[(@{/webjars/mathfonts/1.0.0/mathml.css})]';
link.rel = "stylesheet";
document.head.appendChild(link);
}
}
});
}());
'use strict';
window.addEventListener('load', function () {
var box, div, link, namespaceURI;
// First check whether the page contains any <math> element.
namespaceURI = 'http://www.w3.org/1998/Math/MathML';
if (document.body.getElementsByTagNameNS(namespaceURI, 'math')[0]) {
// Create a div to test mspace, using Kuma's "offscreen" CSS
document.body.insertAdjacentHTML(
'afterbegin',
"<div style='border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px;'><math xmlns='" +
namespaceURI +
"'><mspace height='23px' width='77px'></mspace></math></div>",
);
div = document.body.firstChild;
box = div.firstChild.firstChild.getBoundingClientRect();
document.body.removeChild(div);
if (Math.abs(box.height - 23) > 1 || Math.abs(box.width - 77) > 1) {
// Insert the mathml.css stylesheet.
link = document.createElement('link');
link.href = '[(@{/webjars/mathfonts/1.0.0/mathml.css})]'.startsWith('[')
? 'http://localhost:8080/webjars/mathfonts/1.0.0/mathml.css'
: '[(@{/webjars/mathfonts/1.0.0/mathml.css})]';
link.rel = 'stylesheet';
document.head.appendChild(link);
}
}
});
})();
</script>
</head>
<body>

2
io.sc.platform.core.frontend/template-project/src/components/index.ts

@ -5,7 +5,6 @@
import component_testcase_openNoMenuRoute from '@/views/testcase/route/OpenNoMenuRoute.vue';
import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue';
import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue';
import component_testcase_mathEditorForm from '@/views/testcase/math/MathEditorForm.vue';
import component_testcase_form from '@/views/testcase/form/form.vue';
import component_testcase_codemirror from '@/views/testcase/code-mirror/code-mirror.vue';
import component_testcase_loading from '@/views/testcase/loading/loading.vue';
@ -26,7 +25,6 @@ const localComponents = {
'component.testcase.openNoMenuRoute': component_testcase_openNoMenuRoute,
'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor,
'component.testcase.mathEditorForm': component_testcase_mathEditorForm,
'component.testcase.form': component_testcase_form,
'component.testcase.codemirror': component_testcase_codemirror,
'component.testcase.loading': component_testcase_loading,

16
io.sc.platform.core.frontend/template-project/src/routes/routes.json

@ -20,7 +20,7 @@
"priority": 0,
"component": "component.testcase.noMenuRoute",
"componentPath": "@/views/testcase/route/NoMenuRoute.vue",
"redirect": null,
"redirect": null,
"meta": {
"permissions": ["/testcase/route/**/*"]
}
@ -38,20 +38,6 @@
"permissions": ["/testcase/math/**/*"]
}
},
{
"name": "route.testcase.mathEditorForm",
"path": "testcase/mathEditorForm",
"parent": "/",
"priority": 0,
"component": "component.testcase.mathEditorForm",
"componentPath": "@/views/testcase/math/MathEditorForm.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/math/**/*"]
}
},
{
"name": "route.testcase.form",
"path": "testcase/form",

1
io.sc.platform.core.frontend/template-project/src/shims-vue.d.ts

@ -1,3 +1,4 @@
/* eslint-disable */
import type { AppType } from 'platform-core/types';
declare global {

88
io.sc.platform.core.frontend/template-project/src/views/Editor.vue

@ -2,52 +2,52 @@
<div ref="containerRef"></div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { type CellStyle, Graph, InternalEvent } from '@maxgraph/core';
// import { ref, onMounted } from 'vue';
// import { type CellStyle, Graph, InternalEvent } from '@maxgraph/core';
const containerRef = ref();
// const containerRef = ref();
onMounted(() => {
//const container = <HTMLElement>document.getElementById('graph-container');
// Disables the built-in context menu
InternalEvent.disableContextMenu(containerRef.value);
// onMounted(() => {
// //const container = <HTMLElement>document.getElementById('graph-container');
// // Disables the built-in context menu
// InternalEvent.disableContextMenu(containerRef.value);
const graph = new Graph(containerRef.value);
graph.setPanning(true); // Use mouse right button for panning
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
const parent = graph.getDefaultParent();
// const graph = new Graph(containerRef.value);
// graph.setPanning(true); // Use mouse right button for panning
// // Gets the default parent for inserting new cells. This
// // is normally the first child of the root (ie. layer 0).
// const parent = graph.getDefaultParent();
// Adds cells to the model in a single step
graph.batchUpdate(() => {
const vertex01 = graph.insertVertex({
parent,
position: [10, 10],
size: [100, 100],
value: 'rectangle',
});
const vertex02 = graph.insertVertex({
parent,
position: [350, 90],
size: [50, 50],
style: {
fillColor: 'orange',
shape: 'ellipse',
verticalAlign: 'top',
verticalLabelPosition: 'bottom',
},
value: 'ellipse',
});
graph.insertEdge({
parent,
source: vertex01,
target: vertex02,
value: 'edge',
style: {
edgeStyle: 'orthogonalEdgeStyle',
rounded: true,
},
});
});
});
// // Adds cells to the model in a single step
// graph.batchUpdate(() => {
// const vertex01 = graph.insertVertex({
// parent,
// position: [10, 10],
// size: [100, 100],
// value: 'rectangle',
// });
// const vertex02 = graph.insertVertex({
// parent,
// position: [350, 90],
// size: [50, 50],
// style: {
// fillColor: 'orange',
// shape: 'ellipse',
// verticalAlign: 'top',
// verticalLabelPosition: 'bottom',
// },
// value: 'ellipse',
// });
// graph.insertEdge({
// parent,
// source: vertex01,
// target: vertex02,
// value: 'edge',
// style: {
// edgeStyle: 'orthogonalEdgeStyle',
// rounded: true,
// },
// });
// });
// });
</script>

42
io.sc.platform.core.frontend/template-project/src/views/likm/Dialog.vue

@ -2,37 +2,33 @@
<div>
<w-dialog
ref="dialogRef"
title="标题"
width="60%"
height="60%"
:buttons="[
{
label: '测试',
click: aaaaa,
icon: 'beenhere',
label: '保存',
loading: false,
click: () => {},
},
]"
@hide="aaaaa"
>
<q-splitter v-model="aa" style="height: 100%">
<template #before>
<q-input></q-input><q-input></q-input><q-input></q-input><q-input></q-input><q-input></q-input><q-input></q-input><q-input></q-input
><q-input></q-input><q-input></q-input><q-input></q-input><q-input></q-input>
</template>
<template #after> 22222 </template>
</q-splitter>
<template #buttons> <q-btn label="xxx"></q-btn> </template
></w-dialog>
我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />
我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />我是窗口内容 <br />
</w-dialog>
<q-btn
label="弹出窗口"
@click="
() => {
dialogRef.show();
}
"
></q-btn>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { ref } from 'vue';
const dialogRef = ref();
const aa = ref(50);
const aaaaa = (e) => {
console.info('dddddddddddddd', e);
};
onMounted(() => {
console.info('dialogRef====', dialogRef);
dialogRef.value.show();
});
</script>

112
io.sc.platform.core.frontend/template-project/src/views/likm/Drawer.vue

@ -1,34 +1,88 @@
<template>
<div>
<q-btn label="弹出" @click="click"></q-btn>
<w-drawer
ref="drawerRef"
title="xxx"
:maximized="false"
:buttons="[
{
label: '测试',
<div class="w-[500px] h-[300px]">
<w-echarts
:option="{
title: {
left: 'center',
text: '资产余额',
},
]"
>
1111
<template #buttons> <q-btn label="xxx"></q-btn> </template>
</w-drawer>
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
dataZoom: [
{
type: 'slider',
show: true, //
borderColor: '#2563eb', //
showDetail: false, // detail
startValue: 0, //
endValue: 10, //
filterMode: 'empty',
width: '80%', //
height: 8, //
left: 'center', //
zoomLoxk: true, //
handleSize: 0, //
bottom: 0, //
},
{
type: 'inside',
zoomOnMouseWheel: false, //
moveOnMouseMove: true, //
moveOnMouseWheel: true, //
},
],
xAxis: [
{
type: 'category',
data: [
'黄浦支行',
'徐汇支行',
'长宁支行',
'静安支行',
'普陀支行',
'虹口支行',
'杨浦支行',
'浦东支行',
'闵行支行',
'宝山支行',
'嘉定支行',
'金山支行',
'松江支行',
'青浦支行',
'奉贤支行',
'崇明支行',
],
axisTick: {
alignWithLabel: true,
},
},
],
yAxis: [
{
type: 'value',
name: '单位:万元',
},
],
series: [
{
type: 'bar',
barWidth: '10%',
data: [1700, 1600, 1500, 1400, 1300, 1200, 1100, 1000, 900, 800, 600, 500, 400, 300, 200, 100],
},
],
}"
></w-echarts>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { IconEnum } from '@/platform/enums';
const drawerRef = ref();
const aa = ref(50);
const aaaaa = (e) => {
console.info('dddddddddddddd', e);
};
const click = () => {
drawerRef.value.show();
};
onMounted(() => {});
</script>
<script setup lang="ts"></script>

428
io.sc.platform.core.frontend/template-project/src/views/likm/Form.vue

@ -1,169 +1,287 @@
<template>
<div>
<w-form ref="formRef" :fields="aaaa.fields" :cols-x-gap="8"> </w-form>
<br />
<br />
<br />
<br />
<br />
<div class="flex justify-center">
<div class="w-[800px]">
<w-text-editor label="富文本组件" :required-if="true"></w-text-editor>
<br />
</div>
<!-- <div class="pl-[20px]">自定义表格选择值: {{ arr1ModelValue }} <br /><br /><br /></div> -->
</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<w-form
ref="formRef"
:fields="[
{
name: 'test1',
label: '文本框',
type: 'w-text',
requiredIf: true,
rules: [
(value) => {
console.info('value====', value);
return true;
},
],
},
{
name: 'test2',
label: '下拉框',
type: 'w-select',
requiredIf: true,
multiple: true,
options: [
{ label: '男', value: 1 },
{ label: '女', value: 0 },
],
onUpdateValue: (args) => {},
},
{
name: 'test2.5',
label: '可输入可选择下拉框',
type: 'w-input-select',
requiredIf: true,
defaultValue: 'wowowo',
options: [
{ label: 'java', value: '1' },
{ label: 'python', value: '2' },
],
},
{
name: 'test3',
label: '复选框',
type: 'w-checkbox',
onUpdateValue: (args) => {
console.info('value========', args);
},
},
{
name: 'test4',
label: '日期',
type: 'w-date',
clearable: true,
requiredIf: true,
},
{
name: 'test4.5',
label: '日期范围',
type: 'w-date-range',
clearable: true,
requiredIf: true,
},
{
name: 'test5',
label: '文件',
type: 'w-file',
requiredIf: true,
},
{
name: 'test6',
label: '数字',
type: 'w-number',
precision: 2,
requiredIf: (args) => {
return true;
},
onUpdateValue: (args) => {
// console.info('value========', args);
},
},
{
name: 'test7',
label: '密码',
type: 'w-password',
requiredIf: true,
},
{
name: 'test8',
label: '头像',
type: 'w-icon',
requiredIf: true,
},
{
name: 'test9',
label: '页面位置',
type: 'w-position',
requiredIf: true,
},
{
name: 'test10',
label: '颜色',
type: 'w-color-input',
requiredIf: true,
},
{
name: 'test11',
label: '颜色2',
type: 'w-color-input-palette',
requiredIf: true,
},
{
name: 'test12',
label: '复选框组',
requiredIf: true,
type: 'w-checkbox-group',
simple: false,
options: [
{ label: '唱歌', value: '1' },
{ label: '跳舞', value: '2' },
{ label: '运动', value: '3' },
{ label: '看书', value: '4' },
],
},
{
name: 'test12.5',
label: '单选按钮',
type: 'w-radio',
requiredIf: true,
simple: false,
options: [
{ label: '已婚', value: 1 },
{ label: '单身', value: 2 },
{ label: '离异', value: 3 },
],
},
{
name: 'test13',
label: '自定义下拉表格',
type: 'w-grid-select',
requiredIf: true,
multiple: true,
displayValue: 'name',
grid: {
title: '应用列表',
dataUrl: Environment.apiContextPath('/api/system/application'),
sortBy: ['order'],
queryFormColsNum: 3,
queryFormFields: [
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'enable', label: $t('isEnable') },
],
toolbarActions: ['query', 'separator', 'reset'],
columns: [
{ name: 'order', label: $t('order') },
{ name: 'code', label: $t('code') },
{
name: 'name',
label: $t('name'),
format: (val, row) => {
return val;
},
},
{ name: 'enable', label: $t('status'), format: Formater.enableTag() },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
],
},
},
{
name: 'test14',
label: '用户选择',
type: 'w-user-select',
multiple: true,
requiredIf: true,
},
{
name: 'test15',
label: '机构选择',
type: 'w-org-select',
requiredIf: true,
},
{
name: 'test16',
label: 'cron表达式',
type: 'w-cron',
requiredIf: true,
},
{
name: 'test98',
label: '代码编辑器',
type: 'w-code-mirror',
requiredIf: true,
colsFirst: true,
colSpan: '2',
rows: 3,
onUpdateValue: (args) => {
console.info('args====', args);
},
},
{
name: 'test99',
label: '文本域',
type: 'w-textarea',
requiredIf: true,
colSpan: '2',
rows: 7,
},
{
name: 'test100',
label: '富文本编辑器',
type: 'w-text-editor',
required: true,
colsFirst: true,
colSpan: 'full',
},
]"
:cols-x-gap="8"
@update-value="
(args) => {
console.info('form.updateValue=====', args);
}
"
>
</w-form>
<q-btn label="提交" @click="submit"></q-btn>&nbsp; <q-btn label="重置" @click="reset"></q-btn>&nbsp;
<q-btn label="初始化值" @click="setValue"></q-btn>&nbsp;
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { EnumTools, Options } from '@/platform';
import { FormValidators } from '@/platform/components';
import { useI18n } from 'vue-i18n';
import { ref } from 'vue';
import { Environment, Formater } from '@/platform';
const booleanModelValue = ref(false);
const string1ModelValue = ref('');
const string2ModelValue = ref('');
const numberModelValue = ref(1);
const objectModelValue = ref(undefined);
const arr1ModelValue = ref([]);
const arr2ModelValue = ref([]);
const arr3ModelValue = ref([]);
const UrlOpenTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.UrlOpenType');
const { t } = useI18n();
const formRef = ref();
const aaaa = {
fields: [
{
label: t('theme.main'),
name: 'name',
type: 'password',
// maxlength: 10,
requiredIf: (form) => {
console.info('form====', form.getData().age);
return false;
},
rules: [
() => {
return true;
},
],
colspan: 2,
// requiredIf: () => false,
// 'onUpdate:modelValue': (value) => {
// formRef.value.data.ah = '111';
// },
onFocus: () => {
// console.info('33333333');
},
},
// {
// label: '',
// name: 'org',
// type: 'w-text-btn',
// requiredIf: () => true,
// // buttonPosition: 'prepend',
// button: {
// icon: 'home',
// click: () => {
// console.info('');
// },
// },
// },
{
name: 'urlOpenType',
label: 'urlOpenType',
type: 'select',
options: Options.enum(UrlOpenTypeEnum, false),
defaultValue: 'NEW_WINDOW',
},
{
label: '年龄',
name: 'age',
type: 'w-number',
defaultValue: 111,
precision: 0,
requiredIf: () => true,
},
{
label: '出生日期',
name: 'cs',
type: 'w-date',
requiredIf: () => true,
},
{
label: '爱好',
name: 'ah',
type: 'w-text',
rules: [],
reactiveRules: true,
requiredIf: () => true,
},
{
label: '性别',
name: 'sex',
type: 'select',
defaultValue: '0',
options: ['1', '0'],
requiredIf: () => true,
'onUpdate:modelValue': (value) => {
// if (value === 1) {
// formRef.value.fields.addr.label = '2222';
// } else {
// formRef.value.fields.addr.label = '3333';
// }
},
},
{
label: '地址',
name: 'addr',
rows: 2,
colspan: 'full',
type: 'w-textarea',
// hideIf: () => {
// if (formRef.value) {
// if (formRef.value.data.sex && formRef.value.data.sex === 1) {
// return true;
// } else {
// return false;
// }
// }
// return false;
// },
requiredIf: () => true,
// readonlyIf: () => {
// return true;
// },
disableIf: () => {
return false;
},
},
{
label: '是否可用1',
name: 'ky1',
colsFirst: true,
colspan: 2,
type: 'w-checkbox',
// showIf: (form) => {
// if (form.getFieldValue('sex') === '1') {
// return true;
// } else {
// return false;
// }
// },
// disableIf: () => {
// return true;
// },
},
{
label: '是否可用2',
name: 'ky2',
type: 'w-checkbox',
},
{
label: '是否可用3',
name: 'ky3',
type: 'w-checkbox',
},
],
};
const submit = async () => {
// aaaa.fields[1].required = false;
// const validateResult = await formRef.value.validate();
// console.info('', validateResult);
const errors = [
{ fieldName: 'name', errorMessage: '个数必须在1和4之间' },
{ fieldName: 'name', errorMessage: '不能包含@符号' },
{ fieldName: 'age', errorMessage: '年龄不能为负数' },
];
formRef.value.setValidationErrors(errors);
// console.info('', formRef.value.getData());
// formRef.value.fieldsMap.get('name').required = false;
// console.info('xxx===', formRef.value.fieldsMap.get('ah'));
// const validateResult = await formRef.value.validate();
console.info('表单数据:', formRef.value.getData());
const validateResult = await formRef.value.validate();
console.info('表单验证结果:', validateResult);
};
const reset = () => {
formRef.value.reset();

566
io.sc.platform.core.frontend/template-project/src/views/likm/Grid.vue

@ -1,570 +1,44 @@
<template>
<div style="height: 100%">
<!-- <q-splitter v-model="splitterModel">
<template #before>
<q-tabs v-model="tab" vertical class="text-teal">
<q-tab name="mails" icon="mail" label="Mails" />
<q-tab name="alarms" icon="alarm" label="Alarms" />
<q-tab name="movies" icon="movie" label="Movies" />
</q-tabs>
</template>
<template #after>
<q-tab-panels v-model="tab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up">
<q-tab-panel name="mails">
</q-tab-panel>
<q-tab-panel name="alarms">
<w-grid
ref="grid2"
:title="testGrid.title"
draggable
dense
:data-url="testGrid.tableDataUrl"
:checkbox-selection="true"
selection="multiple"
:query-form-cols-num="2"
:columns="testGrid.tableColumns"
:toolbar-actions="testGrid.toolbar"
:query-form-fields="testGrid.queryForm"
:editor="{
form: {
colsNum: 1,
fields: [
{ label: '登录名', name: 'loginName', type: 'w-text' },
{ label: '用户名', name: 'userName', type: 'w-text' },
{ label: '密码', name: 'password', type: 'w-text' },
{ label: '是否可用1111', name: 'enable', type: 'w-checkbox' },
{
name: 'urlOpenType',
label: 'urlOpenType',
type: 'select',
options: Options.enum(UrlOpenTypeEnum, false),
defaultValue: 'NEW_WINDOW',
},
],
},
}"
:viewer="testGrid.view"
></w-grid>
</q-tab-panel>
<q-tab-panel name="movies">
<div class="text-h4 q-mb-md">Movies</div>
<w-form ref="form" :fields="[{ name: 'a', label: 'a', type: 'text' }]"></w-form>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter> -->
<!-- <w-grid
ref="gridRef"
:title="testGrid.title"
draggable
:dense="state.dense"
:hide-bottom="false"
:data-url="testGrid.tableDataUrl"
:auto-fetch-data="true"
:checkbox-selection="true"
selection="multiple"
:query-form-cols-num="6"
:columns="testGrid.tableColumns"
:toolbar-actions="testGrid.toolbar"
:query-form-fields="testGrid.queryForm"
:editor="{
form: {
colsNum: 1,
fields: [
{ label: '登录名', name: 'loginName', type: 'w-text' },
{ label: '用户名', name: 'userName', type: 'w-text' },
{ label: '密码', name: 'password', type: 'w-text' },
{ label: '是否可用1111', name: 'enable', type: 'w-checkbox' },
{
name: 'urlOpenType',
label: 'urlOpenType',
type: 'select',
options: Options.enum(UrlOpenTypeEnum, false),
defaultValue: 'NEW_WINDOW',
},
],
},
}"
:viewer="testGrid.view"
@update-ticked="updateTicked"
@row-click="rowClick"
@row-db-click="rowDbClick"
@after-request-data="
() => {
}
"
></w-grid> -->
<div class="h-full">
<w-grid
ref="applicationGridRef"
:title="$t('system.application.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:sort-no="true"
:draggable="true"
ref="gridRef"
title="示例列表"
:data-url="Environment.apiContextPath('/api/system/application')"
:sort-by="['order']"
:query-form-cols-num="3"
db-click-operation="rowEdit"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo() },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'query',
'refresh',
'separator',
'rowEdit',
'rowsEdit',
'separator',
'add',
'clone',
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:toolbar-actions="['add', 'edit']"
:columns="[
{ name: 'order', label: $t('order'), type: 'number', attrs: { required: true } },
{ name: 'code', label: $t('code'), type: 'text', attrs: { required: true } },
{ name: 'code', label: '编码', type: 'w-text' },
{ name: 'name', label: '名称', type: 'w-text' },
{
name: 'name',
label: $t('name'),
type: 'text',
format: (val, row) => {
return val;
},
name: 'enable',
label: '状态',
format: Formater.enableTag(),
},
{ width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag(), type: 'checkbox' },
{ width: 120, name: 'lastModifier', label: $t('lastModifier') },
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
{ name: 'lastModifier', label: '最后修改人', align: 'center' },
{ name: 'lastModifyDate', label: '最后修改日期', align: 'center' },
]"
:editor="{
dialog: {
width: '600px',
height: '300px',
width: '80%',
height: '80%',
},
form: {
colsNum: 1,
fields: [
{ name: 'code', label: $t('code'), type: 'text', required: true },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 },
{ name: 'order', label: $t('order'), type: 'number' },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
colsNum: 2,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() },
{ name: 'order', label: $t('order') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
{ name: 'code', label: '编码', type: 'w-text' },
{ name: 'name', label: '名称', type: 'w-text' },
],
},
}"
@row-click="
(evt, row, index) => {
// console.info('rowclick');
}
"
@before-request-data="() => {}"
@after-row-draggable="
(grid, updateDatas) => {
// console.info('grid=====', grid);
// console.info('updateDatas======', updateDatas);
}
"
@after-editor-open="
() => {
console.info('打开窗口');
}
"
@row-click="rowClick"
>
</w-grid>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick, reactive, computed } from 'vue';
import { axios, Environment, EnumTools, Options, Formater } from '@/platform';
import EnableIcon from '@/platform/components/grid/EnableIcon.vue';
import { IconEnum } from '@/platform/enums';
import { ref } from 'vue';
import { Environment, Formater } from '@/platform';
// :query-criteria="{
// operator: 'equals',
// fieldName: 'code',
// value: 'A',
// }"
const dialogRef = ref();
const gridRef = ref();
const grid2 = ref();
const form = ref();
const tab = ref('mails');
const splitterModel = ref(10);
const UrlOpenTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.UrlOpenType');
const updateTicked = (event, row) => {
console.info('grid.updateTicked.event====', event);
console.info('grid.updateTicked.row====', row);
};
const state = reactive({
dense: false,
});
const startY = ref(0);
const endY = ref(0);
const rowClick = (evt, row, index) => {
// if (startY.value === 0) {
// startY.value = evt.clientY;
// } else if (evt.shiftKey && endY.value === 0) {
// endY.value = evt.clientY;
// }
// console.info('startY====', startY.value);
// console.info('endY====', endY.value);
// // startY endY
// if (startY.value > 0 && endY.value > 0) {
// console.info(' startY endY');
// startY.value = 0;
// endY.value = 0;
// }
// startY.value = 0;
// endY.value = 0;
// console.info('grid.rowClick.row====', row);
// tab.value = 'alarms';
// nextTick(() => {
// grid2.value.getQueryForm().setFieldValue('loginName', row.id);
// });
// tab.value = 'movies';
// nextTick(() => {
// form.value.setFieldValue('a', row.id);
// });
console.info('grid.rowClick.row====', row);
};
const rowDbClick = (evt, row, index) => {
console.info('grid.rowDbClick.row====', row);
};
//
const getElementViewPosition = (element) => {
//x
let actualLeft = element.offsetLeft;
let xcurrent = element.offsetParent;
while (xcurrent !== null) {
actualLeft += xcurrent.offsetLeft + xcurrent.clientLeft;
xcurrent = xcurrent.offsetParent;
}
let elementScrollLeft = document.documentElement.scrollLeft;
if (document.compatMode == 'BackCompat') {
elementScrollLeft = document.body.scrollLeft;
}
const left = actualLeft - elementScrollLeft;
//y
let actualTop = element.offsetTop;
let ycurrent = element.offsetParent;
while (ycurrent !== null) {
actualTop += ycurrent.offsetTop + ycurrent.clientTop;
ycurrent = ycurrent.offsetParent;
}
let elementScrollTop = document.documentElement.scrollTop;
if (document.compatMode == 'BackCompat') {
elementScrollTop = document.body.scrollTop;
}
var right = actualTop - elementScrollTop;
//
return { x: left, y: right };
};
// const gridHeightComputed = computed(() => {
// // if (dialogRef?.value && gridRef?.value) {
// // const height = dialogRef.value.getContentHeight();
// // const tableContentY = getElementViewPosition(gridRef.value.$el.getElementsByClassName('q-table__middle')[0]);
// // console.info('height==========', height);
// // console.info('gridRef==============', tableContentY);
// // if (height && tableContentY) {
// // return height.height - (tableContentY.y - height.y);
// // }
// // }
// if (dialogRef?.value && dialogRef.value.getContent()) {
// const height = dialogRef.value.getContent().clientHeight;
// console.info('dialogRef.value.getContent()====', height);
// if (height > 0) {
// return height;
// }
// }
// return 0;
// });
const aaaaaaaaaaaaaaaa = ref(false);
const testGrid = {
hideBottom: false,
autoLoadData: false,
tableLeftColumnStickyNumber: 1,
title: '用户列表',
tableDataUrl: Environment.apiContextPath('api/system/user'),
queryCriteria: {
fieldName: 'loginName',
operator: 'contains',
value: '1',
},
toolbar: [
['query', 'separator', 'moreQuery'],
'reset',
{
extend: 'refresh',
click: () => {
state.dense = !state.dense;
},
},
'separator',
{
extend: 'resetDefaultValues',
icon: undefined,
label: 'aasdfFFF',
loadingIf: (selected, ticked, grid) => {
if (selected.length === 0) {
return true;
}
return false;
},
// enableIf: (selected) => {
// if (selected && selected.length > 0) {
// return true;
// }
// return false;
// },
// beforeClick: (selected, context, grid) => {
// console.info('before');
// context.aaa = '111';
// },
click: (args) => {
// grid.setQueryCriteria({
// fieldName: 'loginName',
// operator: 'contains',
// value: 'admin',
// });
console.info('args=====', args);
args._click();
},
afterClick: (selected, context, grid) => {
// grid.addEditFormRef.setFieldValue('userName', '');
},
},
[
{
name: 'op',
icon: 'difference',
label: '操作',
},
'add',
'edit',
'clone',
'remove',
'separator',
'view',
'export',
],
'separator',
],
tableShowSortNo: true,
queryForm: [
{ label: '登录名', name: 'loginName', type: 'w-text' },
{ label: '用户名', name: 'userName', type: 'w-text' },
{ label: '描述', name: 'description', type: 'w-text' },
{ label: '用户名', name: 'userName1', type: 'w-text' },
{ label: '描述', name: 'description1', type: 'w-text' },
{
label: '是否可用',
name: 'enable',
type: 'select',
options: [{ label: '监管报表-G4B-1表内信用风险加权资产计算表(权重法)', value: '0a981b42-d0df-4f02-94c4-edc20620ba9f' }],
},
// { label: '', name: 'email', type: 'w-text' },
// { label: '', name: 'phone', type: 'w-text' },
// { label: '', name: 'mobile', type: 'w-number' },
// { label: '', name: 'lastModifier', type: 'w-text' },
// { label: '', name: 'lastModifyDate', type: 'w-date' },
],
tableColumns: [
// {
// name: 'info',
// label: '',
// columns: [
// { name: 'loginName', label: '', align: 'right' },
// { name: 'userName', label: '' },
// ],
// },
{ name: 'loginName', label: '登录名', align: 'right' },
{ name: 'userName', label: '用户名' },
// {
// name: 'lxxx',
// label: '',
// columns: [
// {
// name: 'email',
// label: '',
// columns: [
// { width: 100, name: 'auc', label: 'auc' },
// { width: 100, name: 'ar', label: 'ar' },
// { width: 100, name: 'ks', label: 'ks' },
// ],
// },
// {
// name: 'tx',
// label: '',
// columns: [
// { name: 'phone', label: '' },
// { name: 'mobile', label: '' },
// ],
// },
// {
// name: 'qq',
// label: 'QQ',
// // columns: [
// // { width: 100, name: 'aucQualitative', label: 'aucQualitative' },
// // { width: 100, name: 'arQualitative', label: 'arQualitative' },
// // { width: 100, name: 'ksQualitative', label: 'ksQualitative' },
// // ],
// },
// ],
// },
{ name: 'email', label: '邮箱地址' },
{ name: 'phone', label: '电话' },
{ name: 'mobile', label: '手机号' },
{ name: 'qq', label: 'QQ' },
{ name: 'description', label: '描述', width: 400 },
{
name: 'enable',
label: '是否可用',
align: 'center',
width: 400,
format: (val, row) => {
return {
componentType: 'q-checkbox',
bindModelValue: true,
attrs: {
dense: true,
},
};
// return {
// componentType: 'q-icon',
// attrs: {
// name: val ? IconEnum. : IconEnum.,
// color: val ? 'green' : 'red',
// size: 'xs',
// },
// };
},
},
// { name: 'loginName', label: '', align: 'right' },
// { name: 'userName', label: '' },
{ name: 'lastModifier', label: '最后修改人' },
{ name: 'lastModifyDate', label: '最后修改时间' },
],
addEdit: {
dialog: {},
form: {
colsNum: 1,
fields: [
{ label: '登录名', name: 'loginName', type: 'w-text' },
{ label: '用户名', name: 'userName', type: 'w-text' },
{ label: '密码', name: 'password', type: 'w-text' },
{ label: '是否可用1111', name: 'enable', type: 'w-checkbox' },
{
name: 'urlOpenType',
label: 'urlOpenType',
type: 'select',
options: Options.enum(UrlOpenTypeEnum, false),
defaultValue: 'NEW_WINDOW',
},
],
},
},
view: {
panel: {
columnNum: 2,
fields: [
{ name: 'id', label: '主键' },
{ name: 'loginName', label: '登录名' },
{ name: 'userName', label: '用户名' },
{ name: 'description', label: '描述' },
{
name: 'enable',
label: '是否可用',
},
{ name: 'email', label: '邮箱地址' },
{ name: 'phone', label: '电话' },
{ name: 'mobile', label: '手机号' },
{ name: 'lastModifier', label: '最后修改人' },
{ name: 'lastModifyDate', label: '最后修改时间' },
],
},
},
};
onMounted(() => {
// gridRef.value.setLocalData([
// {
// loginName: 'admin1',
// },
// {
// loginName: 'admin2',
// },
// {
// loginName: 'admin3',
// },
// {
// loginName: 'admin4',
// },
// {
// loginName: 'admin5',
// },
// {
// loginName: 'admin6',
// },
// {
// loginName: 'admin7',
// },
// {
// loginName: 'admin8',
// },
// {
// loginName: 'admin9',
// },
// {
// loginName: 'admin10',
// },
// {
// loginName: 'admin11',
// },
// {
// loginName: 'admin12',
// },
// {
// loginName: 'admin13',
// },
// ]);
});
const rowClick = () => {};
</script>

2
io.sc.platform.core.frontend/template-project/src/views/likm/InfoPanel.vue

@ -4,8 +4,6 @@
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
const infoArray = [
{ label: '姓名', value: '张三' },
{ label: '年龄', value: 18 },

22
io.sc.platform.core.frontend/template-project/src/views/likm/Toolbar.vue

@ -9,8 +9,6 @@
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const toolbar = {
xGap: 8,
noIcon: false,
@ -132,22 +130,10 @@ const toolbar = {
console.info('删除');
},
},
// { icon: 'home', label: '1' },
// { separator: true },
// { icon: 'home', label: '2' },
// { icon: 'home', label: '3' },
// { icon: 'home', label: '4' },
// { separator: true },
// { separator: true },
// { icon: 'home', label: '5' },
// { icon: 'home', label: '6' },
// { icon: 'home', label: '7' },
// { icon: 'home', label: '8' },
// { icon: 'home', label: '9' },
// { icon: 'home', label: '10' },
// { icon: 'home', label: '11' },
// { icon: 'home', label: '12' },
// { icon: 'home', label: '13' },
{ name: 'home1', icon: 'home', label: '测试1' },
{ name: 'home2', icon: 'home', label: '测试2' },
{ name: 'home3', icon: 'home', label: '测试3' },
{ name: 'home4', icon: 'home', label: '测试4' },
],
};
</script>

65
io.sc.platform.core.frontend/template-project/src/views/likm/TreeGrid.vue

@ -2,26 +2,41 @@
<div class="h-full">
<w-grid
ref="gridRef"
:title="testGrid.title"
draggable
sort-no
tree
:tree-icon="(row) => {}"
:checkbox-selection="true"
db-click-operation="rowEdit"
:data-url="testGrid.dataUrl"
:fetch-data-url="testGrid.fetchDataUrl"
:columns="testGrid.tableColumns"
:toolbar-actions="testGrid.toolbar"
:query-form-fields="testGrid.queryFormFields"
:query-form-cols-num="3"
@update-ticked="updateTicked"
@after-row-draggable="
(grid, updateDatas) => {
console.info('grid=====', grid);
console.info('updateDatas======', updateDatas);
}
"
title="树形表格示例"
:fetch-data-url="Environment.apiContextPath('api/system/menu/allMenus')"
:tree="true"
db-click-operation="expand"
draggable="local"
:columns="[
{
name: 'name',
label: '菜单名称',
type: 'text',
format: (val, row) => {
return t(row.name);
},
},
{
name: 'icon',
label: '图标',
type: 'icon',
attrs: {
required: true,
},
format: (val, row) => {
return {
componentType: 'q-icon',
attrs: {
name: val,
size: 'xs',
},
};
},
},
{ name: 'type', label: '菜单类型' },
{ name: 'order', label: '排序号' },
]"
:toolbar-actions="['expand']"
></w-grid>
</div>
</template>
@ -82,11 +97,11 @@ const testGrid = {
],
'separator',
],
queryFormFields: [
{ label: '菜单名称', name: 'name', type: 'w-password' },
{ label: '菜单类型', name: 'userName', type: 'select' },
{ label: '是否可用', name: 'enable', type: 'select' },
],
// queryFormFields: [
// { label: '', name: 'name', type: 'w-password' },
// { label: '', name: 'userName', type: 'select' },
// { label: '', name: 'enable', type: 'select' },
// ],
tableColumns: [
{
name: 'name',

224
io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/Maxgraph.vue

@ -1,37 +1,199 @@
<template>
<w-graph v-model="modelValueRef"></w-graph>
<w-graph v-model="modelValueRef" :vertex-defines="vertexDefines" :edge-defines="edgeDefines"></w-graph>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { $t } from '@/platform';
const modelValueRef = ref(`
<GraphDataModel>
<root>
<Cell id="0">
<Object as="style" />
</Cell>
<Cell id="1" parent="0">
<Object as="style" />
</Cell>
<Person firstName="Daffy" lastName="Duck" id="2" >
<Cell vertex="1" parent="1" >
<Geometry _x="40" _y="40" _width="80" _height="30" as="geometry" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;jettySize=auto;orthogonalLoop=1;"/>
<Object as="style" />
</Cell>
</Person>
<Person firstName="Bugs" lastName="Bunny" id="3">
<Cell vertex="1" parent="1">
<Geometry _x="200" _y="150" _width="80" _height="30" as="geometry" />
<Object as="style" />
</Cell>
</Person>
<Knows since="1985" id="4">
<Cell edge="1" parent="1" source="2" target="3">
<Geometry relative="1" as="geometry" />
<Object as="style" />
</Cell>
</Knows>
</root>
</GraphDataModel>
`);
const edgeDefines = [
{
type: 'ConditionBranch',
fromVertexType: 'Condition',
toVertexType: null,
getLabel: (value) => {
return value.value;
},
getValue: (dom) => {
if (dom) {
return {
valueType: dom.getAttribute('valueType'),
value: dom.getAttribute('value'),
commands: dom.getAttribute('commands'),
};
} else {
return {
valueType: 'java.lang.String',
value: '',
commands: '',
};
}
},
getFormFields: () => {
return [
{
name: 'valueType',
label: 'valueType',
type: 'w-select',
},
{
name: 'value',
label: 'value',
type: 'w-text',
},
{
name: 'commands',
label: 'commands',
type: 'w-code-mirror',
lang: 'java',
rows: 10,
lineWrap: true,
lineBreak: false,
placeholder: true,
},
];
},
},
];
const vertexDefines = [
{
type: 'Start',
thumbnail: { shape: 'ellipse', label: $t('start'), rx: 8, ry: 8, strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'ellipse',
size: [50, 50],
},
getLabel: (value) => {
return value.label;
},
getValue: (dom) => {
if (dom) {
return {
label: dom.getAttribute('label'),
};
} else {
return { label: $t('start') };
}
},
getFormFields: () => {
return [
{
name: 'label',
label: 'label',
type: 'w-text',
},
];
},
},
{
type: 'Condition',
thumbnail: { shape: 'rhombus', label: $t('condition'), strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'rhombus',
size: [120, 60],
},
getLabel: (value) => {
return value.condition ? value.condition : $t('condition');
},
getValue: (dom) => {
if (dom) {
return {
condition: dom.getAttribute('condition'),
};
} else {
return {
condition: '',
};
}
},
getFormFields: () => {
return [
{
name: 'condition',
label: 'condition',
type: 'w-code-mirror',
lang: 'java',
rows: 10,
lineWrap: true,
lineBreak: false,
placeholder: true,
},
];
},
},
{
type: 'Expression',
thumbnail: { shape: 'rectangle', label: $t('expression'), strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'rectangle',
size: [120, 60],
},
getLabel: (value) => {
let html = '';
html += '<div style="text-align:center;">' + value.expression + '</div>';
html += '<hr size="0.5"/>';
html += '<div style="text-align:left;">' + value.commands + '</div>';
return html;
},
getValue: (dom) => {
if (dom) {
return {
expression: dom.getAttribute('expression'),
commands: dom.getAttribute('commands'),
};
} else {
return {
expression: 'xxx',
commands: 'kjsdfi=klsjdf="xxx";\na=b;',
};
}
},
getFormFields: () => {
return [
{ name: 'expression', label: 'expression', type: 'w-text' },
{
name: 'commands',
label: 'commands',
type: 'w-code-mirror',
lang: 'java',
rows: 10,
lineWrap: true,
lineBreak: true,
placeholder: true,
},
];
},
},
{
type: 'ResourceAbstract',
thumbnail: { shape: 'ellipse', label: '资源摘要', rx: 11, ry: 6, strokeColor: 'black', strokeWidth: 1 },
cell: {
shape: 'ellipse',
size: [120, 60],
},
getLabel: (value) => {
return value.code;
},
getValue: (dom) => {
if (dom) {
return {
code: dom.getAttribute('code'),
version: dom.getAttribute('version'),
};
} else {
return {
code: '资源摘要',
version: '',
};
}
},
getFormFields: () => {
return [
{ name: 'code', label: 'code', type: 'w-select' },
{ name: 'version', label: 'version', type: 'w-select' },
];
},
},
];
const modelValueRef = ref('');
</script>

25
io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs

@ -61,18 +61,19 @@ module.exports = {
'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true },
'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true },
'vue-router': { requiredVersion: deps['vue-router'], singleton: true },
"xml-formatter": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/core": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/design": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/docs": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/docs-ui": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/engine-formula": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/engine-render": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/facade": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/sheets": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/sheets-formula": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/sheets-ui": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/ui": { requiredVersion: deps['vue-router'], singleton: true }
"xml-formatter": { requiredVersion: deps['xml-formatter'], singleton: true },
"@univerjs/core": { requiredVersion: deps['@univerjs/core'], singleton: true },
"@univerjs/design": { requiredVersion: deps['@univerjs/design'], singleton: true },
"@univerjs/docs": { requiredVersion: deps['@univerjs/docs'], singleton: true },
"@univerjs/docs-ui": { requiredVersion: deps['@univerjs/docs-ui'], singleton: true },
"@univerjs/engine-formula": { requiredVersion: deps['@univerjs/engine-formula'], singleton: true },
"@univerjs/engine-render": { requiredVersion: deps['@univerjs/engine-render'], singleton: true },
"@univerjs/facade": { requiredVersion: deps['@univerjs/facade'], singleton: true },
"@univerjs/sheets": { requiredVersion: deps['@univerjs/sheets'], singleton: true },
"@univerjs/sheets-formula": { requiredVersion: deps['@univerjs/sheets-formula'], singleton: true },
"@univerjs/sheets-ui": { requiredVersion: deps['@univerjs/sheets-ui'], singleton: true },
"@univerjs/thread-comment": { requiredVersion: deps['@univerjs/thread-comment'], singleton: true },
"@univerjs/ui": { requiredVersion: deps['@univerjs/ui'], singleton: true }
}
}),
]

25
io.sc.platform.core.frontend/webpack.config.mf.cjs

@ -61,18 +61,19 @@ module.exports = {
'vue-dompurify-html':{ requiredVersion: deps['vue-dompurify-html'], singleton: true },
'vue-i18n': { requiredVersion: deps['vue-i18n'], singleton: true },
'vue-router': { requiredVersion: deps['vue-router'], singleton: true },
"xml-formatter": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/core": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/design": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/docs": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/docs-ui": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/engine-formula": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/engine-render": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/facade": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/sheets": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/sheets-formula": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/sheets-ui": { requiredVersion: deps['vue-router'], singleton: true },
"@univerjs/ui": { requiredVersion: deps['vue-router'], singleton: true }
"xml-formatter": { requiredVersion: deps['xml-formatter'], singleton: true },
"@univerjs/core": { requiredVersion: deps['@univerjs/core'], singleton: true },
"@univerjs/design": { requiredVersion: deps['@univerjs/design'], singleton: true },
"@univerjs/docs": { requiredVersion: deps['@univerjs/docs'], singleton: true },
"@univerjs/docs-ui": { requiredVersion: deps['@univerjs/docs-ui'], singleton: true },
"@univerjs/engine-formula": { requiredVersion: deps['@univerjs/engine-formula'], singleton: true },
"@univerjs/engine-render": { requiredVersion: deps['@univerjs/engine-render'], singleton: true },
"@univerjs/facade": { requiredVersion: deps['@univerjs/facade'], singleton: true },
"@univerjs/sheets": { requiredVersion: deps['@univerjs/sheets'], singleton: true },
"@univerjs/sheets-formula": { requiredVersion: deps['@univerjs/sheets-formula'], singleton: true },
"@univerjs/sheets-ui": { requiredVersion: deps['@univerjs/sheets-ui'], singleton: true },
"@univerjs/thread-comment": { requiredVersion: deps['@univerjs/thread-comment'], singleton: true },
"@univerjs/ui": { requiredVersion: deps['@univerjs/ui'], singleton: true }
}
}),
]

1
io.sc.platform.core.frontend/webpack.env.lib.cjs

@ -71,6 +71,7 @@ const config =merge(common, {
'@univerjs/sheets': '@univerjs/sheets',
'@univerjs/sheets-formula': '@univerjs/sheets-formula',
'@univerjs/sheets-ui': '@univerjs/sheets-ui',
"@univerjs/thread-comment":"@univerjs/thread-comment",
'@univerjs/ui': '@univerjs/ui'
}
],

Loading…
Cancel
Save