diff --git a/packages/model-design/src/components/design-code-editor/design-code-editor.tsx b/packages/model-design/src/components/design-code-editor/design-code-editor.tsx
index d65231e02f87f282529942877c6dd7059f00d81c..33900a2c2d55262afca2c27c6e44385a5a1be4a0 100644
--- a/packages/model-design/src/components/design-code-editor/design-code-editor.tsx
+++ b/packages/model-design/src/components/design-code-editor/design-code-editor.tsx
@@ -32,6 +32,10 @@ export default defineComponent({
type: Boolean,
default: true,
},
+ showToolbar: {
+ type: Boolean,
+ default: true,
+ },
},
emits: {
'update:modelValue': (_value: string) => true,
@@ -225,36 +229,38 @@ export default defineComponent({
class={[this.ns.b(), this.ns.is('full-screen', this.isFullScreen)]}
ref='containerRef'
>
-
);
diff --git a/packages/model-design/src/components/index.ts b/packages/model-design/src/components/index.ts
index 0dba73e70644ff4d0202d16d35386de58e4f4689..927dba4787492079f1b90d78bdb4ecf6d972eb5c 100644
--- a/packages/model-design/src/components/index.ts
+++ b/packages/model-design/src/components/index.ts
@@ -2,15 +2,19 @@ import { App } from 'vue';
import IBizModelClipboard from './model-clipboard/model-clipboard';
import IBizModelClipboardItem from './model-clipboard-item/model-clipboard-item';
import IBizModelClipboardImportView from './model-clipboard-import-view/model-clipboard-import-view';
+import IBizModelClipboardPasteView from './model-clipboard-paste-view/model-clipboard-paste-view';
import IBizDesignCodeEditor from './design-code-editor/design-code-editor';
import IBizModelEditView from './model-edit-view/model-edit-view';
+import IBizModelTree from './model-tree/model-tree';
export default {
install(app: App) {
app.component('IBizModelClipboard', IBizModelClipboard);
app.component('IBizModelClipboardItem', IBizModelClipboardItem);
app.component('IBizModelClipboardImportView', IBizModelClipboardImportView);
+ app.component('IBizModelClipboardPasteView', IBizModelClipboardPasteView);
app.component('IBizDesignCodeEditor', IBizDesignCodeEditor);
app.component('IBizModelEditView', IBizModelEditView);
+ app.component('IBizModelTree', IBizModelTree);
},
};
diff --git a/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.scss b/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.scss
index 39106b94da1c34d1507081fa58b8aa628222b774..4cd9ba810e854c4fa980290c0af2ac3888be5a00 100644
--- a/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.scss
+++ b/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.scss
@@ -174,11 +174,3 @@
font-size: 24px;
font-weight: 700;
}
-
-@include b(model-clipboard-import-view-drawer) {
- .el-drawer__header {
- .el-drawer__close-btn {
- display: none;
- }
- }
-}
diff --git a/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.tsx b/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.tsx
index fd8aea17e93aa946c3569c3336d4862739c58013..888e7e5c667598256dc30c014b1bd29e3779d493 100644
--- a/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.tsx
+++ b/packages/model-design/src/components/model-clipboard-import-view/model-clipboard-import-view.tsx
@@ -3,7 +3,7 @@ import { IModal } from '@ibiz-template/runtime';
import { PropType, computed, defineComponent } from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
import draggable from 'vuedraggable';
-import { ModelData } from '../../model';
+import { ClipboardData } from '../../model';
import './model-clipboard-import-view.scss';
export default defineComponent({
@@ -86,7 +86,8 @@ export default defineComponent({
ibiz.message.warning('编辑框内,模型内容已重新计算!');
c.state.models = [];
c.state.items.forEach(item => {
- c.state.models.push(...item.models);
+ const models = item.models.map(m => m.model).filter(m => !!m);
+ c.state.models.push(...models);
});
try {
initModel(JSON.stringify(c.state.models, null, 2));
@@ -122,6 +123,7 @@ export default defineComponent({
const materialItem = computed(() => {
return modelClipboardController.state.items.filter(item => {
if (
+ item.type !== 'default' ||
!Object.is(c.state.params.codeName, item.codeName) ||
c.state.items.findIndex(self => Object.is(self.uuid, item.uuid)) !==
-1
@@ -168,7 +170,7 @@ export default defineComponent({
params,
props.params,
);
- if (res.status === 200) {
+ if (res.ok && res.data) {
c.state.isModelChange = false;
c.state.importItems.push(item);
} else {
@@ -258,7 +260,7 @@ export default defineComponent({
element,
index,
}: {
- element: ModelData;
+ element: ClipboardData;
index: number;
}) => {
const item = element;
@@ -352,12 +354,7 @@ export default defineComponent({
modelValue={this.materialItem}
>
{{
- item: ({
- element,
- }: {
- element: ModelData;
- index: number;
- }) => {
+ item: ({ element }: { element: ClipboardData }) => {
const item = element;
return (
diff --git a/packages/model-design/src/components/model-clipboard-item/model-clipboard-item.tsx b/packages/model-design/src/components/model-clipboard-item/model-clipboard-item.tsx
index 7a56f162de7178999f7f916b972460c5eccea341..738fe0d078473bcf660ca3f77c2386371dca3398 100644
--- a/packages/model-design/src/components/model-clipboard-item/model-clipboard-item.tsx
+++ b/packages/model-design/src/components/model-clipboard-item/model-clipboard-item.tsx
@@ -1,9 +1,11 @@
+/* eslint-disable no-continue */
/* eslint-disable no-await-in-loop */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable vue/no-mutating-props */
-import { PropType, defineComponent, onUnmounted, ref } from 'vue';
+import { PropType, computed, defineComponent, onUnmounted, ref } from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
-import { ModelData } from '../../model';
+import { ClipboardData } from '../../model';
+import { IModelData } from '../../interface';
import './model-clipboard-item.scss';
export default defineComponent({
@@ -12,7 +14,7 @@ export default defineComponent({
context: { type: Object as PropType, default: () => ({}) },
params: { type: Object as PropType, default: () => ({}) },
data: {
- type: Object as PropType,
+ type: Object as PropType,
required: true,
},
},
@@ -28,6 +30,18 @@ export default defineComponent({
const isDestroyed = ref(false);
+ const stateType = computed(() => {
+ let type: string = 'info';
+ if (props.data.isError) {
+ type = 'danger';
+ } else if (props.data.isExport) {
+ type = 'success';
+ } else if (isLoading.value) {
+ type = 'warning';
+ }
+ return type;
+ });
+
// 初始化
const init = async () => {
if (props.data && !props.data.isExport) {
@@ -45,15 +59,15 @@ export default defineComponent({
entity.id!,
);
const res = await service.exec(
- 'ExportModelV2',
+ props.data.type === 'advanced' ? 'CopyModel' : 'ExportModelV2',
{
...props.context,
[entity.deapicodeName!]: item.srfkey,
},
props.params,
);
- if (res && res.status === 200 && res.data.model) {
- props.data.models.push(res.data.model);
+ if (res && res.status === 200 && res.data) {
+ props.data.models.push(res.data as IModelData);
}
} catch (err: any) {
props.data.isError = true;
@@ -103,26 +117,19 @@ export default defineComponent({
return {
ns,
- modelClipboardController,
+ stateType,
isLoading,
+ modelClipboardController,
remove,
copy,
};
},
render() {
- let type: string = 'info';
- if (this.data.isExport) {
- type = 'success';
- } else if (this.data.isError) {
- type = 'danger';
- } else if (this.isLoading) {
- type = 'warning';
- }
return (
diff --git a/packages/model-design/src/components/model-clipboard-paste-view/model-clipboard-paste-view.scss b/packages/model-design/src/components/model-clipboard-paste-view/model-clipboard-paste-view.scss
new file mode 100644
index 0000000000000000000000000000000000000000..83800af308178809f3156898a4d2185e8dae0d4c
--- /dev/null
+++ b/packages/model-design/src/components/model-clipboard-paste-view/model-clipboard-paste-view.scss
@@ -0,0 +1,187 @@
+/* stylelint-disable selector-class-pattern */
+@include b(model-clipboard-paste-view) {
+ width: 100%;
+ height: 100%;
+ font-size: 14px;
+ line-height: 1.5;
+ color: getCssVar(color, text, 1);
+
+ .el-card__header {
+ padding: 0 10px;
+ }
+
+ .el-card__body {
+ height: calc(100% - 40px);
+ padding: 6px;
+ }
+
+ .el-loading-mask {
+ color: var(--el-color-primary);
+
+ svg {
+ fill: currentcolor;
+ }
+ }
+}
+
+@include b(model-clipboard-paste-view-header) {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 40px;
+}
+
+@include b(model-clipboard-paste-view-content) {
+ display: flex;
+ height: 100%;
+}
+
+@include b(model-clipboard-paste-view-paste-warp) {
+ width: calc(100% - 200px);
+ padding: 0 6px 0 0;
+}
+
+@include b(model-clipboard-paste-view-drop-area) {
+ position: relative;
+ height: 100px;
+ border: 1px solid getCssVar(color, border);
+ border-radius: 5px;
+}
+
+@include b(model-clipboard-paste-view-drop-area-draggable) {
+ display: flex;
+ height: 100%;
+ padding: 6px;
+ overflow: auto;
+
+ @include b(model-clipboard-paste-view-model-material-item) {
+ flex: 0 0 auto;
+ height: 100%;
+ padding: 3px 24px 3px 3px;
+ margin-right: 6px;
+ margin-bottom: 0;
+
+ @include b(model-clipboard-paste-view-model-material-item-title) {
+ font-weight: normal;
+ }
+ }
+}
+
+@include b(model-clipboard-paste-view-model-drag-item) {
+ position: relative;
+ flex: 0 0 auto;
+ height: 100%;
+ padding: 3px 24px 3px 3px;
+ margin-right: 6px;
+ border: 1px solid getCssVar(color, border);
+ border-radius: 5px;
+}
+
+@include b(model-clipboard-paste-view-model-drag-item-actions) {
+ position: absolute;
+ top: 6px;
+ right: 5px;
+ display: flex;
+ align-items: center;
+}
+
+@include b(model-clipboard-paste-view-model-drag-item-action-item) {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 16px;
+ cursor: pointer;
+}
+
+@include b(model-clipboard-paste-view-drop-tooltip) {
+ position: absolute;
+ top: 0;
+ z-index: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ font-size: 24px;
+ font-weight: 700;
+}
+
+@include b(model-clipboard-paste-view-model-edit) {
+ position: relative;
+ height: calc(100% - 106px);
+ margin-top: 6px;
+ border: 1px solid getCssVar(color, border);
+ border-radius: 5px;
+ @include e(tabs) {
+ height: 100%;
+ .el-tabs__content {
+ height: calc(100% - 56px);
+ .el-tab-pane {
+ height: 100%;
+ }
+ }
+ }
+}
+
+@include b(model-clipboard-paste-view-edit-actions) {
+ margin: 0 8px 0 5px;
+ position: absolute;
+ top: 8px;
+ right: 0;
+ .el-button {
+ --el-button-text-color: #{getCssVar(color, text, 3)};
+
+ + .el-button {
+ margin-left: 5px;
+ }
+ }
+}
+
+@include b(model-clipboard-paste-view-model-material-warp) {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 200px;
+ border: 1px solid getCssVar(color, border);
+ border-radius: 5px;
+}
+
+@include b(model-clipboard-paste-view-model-material-title) {
+ flex: 0 0 auto;
+ padding: 6px;
+ font-weight: 700;
+ text-align: center;
+ border-bottom: 1px solid getCssVar(color, border);
+}
+
+@include b(model-clipboard-paste-view-model-material-content) {
+ flex: 1 1 0;
+ padding: 6px;
+ overflow: auto;
+}
+
+@include b(model-clipboard-paste-view-model-material-item) {
+ padding: 3px 5px;
+ margin-bottom: 5px;
+ cursor: move;
+ border: 1px solid getCssVar(color, border);
+ border-radius: 5px;
+}
+
+@include b(model-clipboard-paste-view-model-material-item-title) {
+ font-weight: 700;
+}
+
+@include b(model-clipboard-paste-view-model-material-tooltip) {
+ position: absolute;
+ top: 0;
+ z-index: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ font-size: 24px;
+ font-weight: 700;
+}
diff --git a/packages/model-design/src/components/model-clipboard-paste-view/model-clipboard-paste-view.tsx b/packages/model-design/src/components/model-clipboard-paste-view/model-clipboard-paste-view.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..3d32cc4827b22343e99d4e0a9f3ba4b17f45f2de
--- /dev/null
+++ b/packages/model-design/src/components/model-clipboard-paste-view/model-clipboard-paste-view.tsx
@@ -0,0 +1,398 @@
+/* eslint-disable no-await-in-loop */
+import { IModal } from '@ibiz-template/runtime';
+import { PropType, computed, defineComponent, ref } from 'vue';
+import { useNamespace } from '@ibiz-template/vue3-util';
+import draggable from 'vuedraggable';
+import { ClipboardData } from '../../model';
+import './model-clipboard-paste-view.scss';
+
+export default defineComponent({
+ name: 'IBizModelClipboardPasteView',
+ components: {
+ draggable,
+ },
+ props: {
+ context: { type: Object as PropType, default: () => ({}) },
+ params: { type: Object as PropType, default: () => ({}) },
+ modal: { type: Object as PropType },
+ },
+ setup(props) {
+ const ns = useNamespace('model-clipboard-paste-view');
+ // 模型粘贴板控制器
+ const modelClipboardController = ibiz.modelClipboard;
+ // 模型导入视图控制器
+ const c = ibiz.modelClipboardPasteView;
+
+ // 当前激活分页
+ const activeName = ref<'ModeTree' | 'JSON'>('ModeTree');
+
+ // 重置模型
+ const initModel = (val: string) => {
+ c.state.modelStr = val;
+ c.state.isModelChange = false;
+ };
+
+ // 清除当前已计算模型
+ const clearModel = async () => {
+ if (c.state.isModelChange) {
+ const result = await ibiz.confirm.warning({
+ title: '确认清除?',
+ desc: '模型数据已变更,将同已拖入模型一同清空,确认清除吗?',
+ });
+ if (result) {
+ c.clearAllData();
+ }
+ } else {
+ c.clearAllData();
+ }
+ };
+
+ // 关闭当前视图
+ const closeView = async () => {
+ if (c.state.isModelChange) {
+ const result = await ibiz.confirm.warning({
+ title: '确认关闭',
+ desc: '模型数据已变更,确认关闭吗?',
+ });
+ if (result) {
+ props.modal?.dismiss();
+ c.clearAllData();
+ }
+ } else {
+ props.modal?.dismiss();
+ }
+ };
+
+ // 格式化数据
+ const formatData = () => {
+ try {
+ c.state.modelStr = JSON.stringify(
+ JSON.parse(c.state.modelStr),
+ null,
+ 2,
+ );
+ } catch (error) {
+ ibiz.message.error('格式有误无法格式化,请检查!', 2.5);
+ }
+ };
+
+ // 模型编辑变更
+ const modelChange = (val: string) => {
+ if (!Object.is(c.state.modelStr, val)) {
+ c.state.modelStr = val;
+ c.state.isModelChange = true;
+ }
+ };
+
+ // 计算模型文本内容
+ const calcModeStr = () => {
+ ibiz.message.warning('编辑框内,模型内容已重新计算!');
+ c.state.models = [];
+ c.state.items.forEach(item => {
+ c.state.models.push(...item.models);
+ });
+ try {
+ initModel(JSON.stringify(c.state.models, null, 2));
+ } catch (error) {
+ ibiz.log.error(error);
+ }
+ };
+
+ // 删除拖拽项
+ const deleteDropItem = (i: number) => {
+ c.state.items.splice(i, 1);
+ calcModeStr();
+ };
+
+ // 拖入模型变更
+ const dropModelChange = async (e: IData) => {
+ if (c.state.isModelChange) {
+ const result = await ibiz.confirm.warning({
+ title: '确认操作?',
+ desc: '检测到输入框内容已手动修改,该操作后输入框内容将重新计算,确认操作吗?',
+ });
+ if (result) {
+ calcModeStr();
+ } else if (e && e.added && e.added.newIndex != null) {
+ c.state.items.splice(e.added.newIndex, 1);
+ }
+ } else {
+ calcModeStr();
+ }
+ };
+
+ // 素材项
+ const materialItem = computed(() => {
+ return modelClipboardController.state.items.filter(item => {
+ if (
+ item.type !== 'advanced' ||
+ !Object.is(c.state.params.codeName, item.codeName) ||
+ c.state.items.findIndex(self => Object.is(self.uuid, item.uuid)) !==
+ -1
+ ) {
+ return false;
+ }
+ return item;
+ });
+ });
+
+ // 保存模型
+ const saveModel = async () => {
+ try {
+ const models = JSON.parse(c.state.modelStr);
+ if (Array.isArray(models)) {
+ c.state.models = models;
+ } else {
+ ibiz.message.error('模型数据格式异常,请检查!');
+ return;
+ }
+ } catch (error) {
+ ibiz.message.error('模型数据格式异常,请检查!');
+ return;
+ }
+ c.state.isLoading = true;
+ c.state.importItems = [];
+ let isError: boolean = false;
+ const entity = await ibiz.hub.getAppDataEntity(
+ c.state.params.codeName,
+ props.context.srfappid,
+ );
+ const app = ibiz.hub.getApp(props.context.srfappid);
+ const service = await app.deService.getService(props.context, entity.id!);
+ for (let i = 0; i < c.state.models.length; i++) {
+ const item = c.state.models[i];
+ const params: IParams = {
+ ...item,
+ srfmodelv2scope: props.context.srfmodelv2scope,
+ };
+ try {
+ const res = await service.exec(
+ 'PasteModel',
+ props.context,
+ params,
+ props.params,
+ );
+ if (res.ok && res.data) {
+ c.state.isModelChange = false;
+ c.state.importItems.push(item);
+ } else {
+ ibiz.message.error(res.statusText);
+ isError = true;
+ break;
+ }
+ } catch (err) {
+ const error = err as IData;
+ ibiz.message.error(
+ error?.message ||
+ error?.data?.message ||
+ error?.statusText ||
+ ibiz.i18n.t('core.error.networkAbnormality'),
+ );
+ isError = true;
+ break;
+ }
+ }
+ if (!isError) {
+ const result = await ibiz.confirm.warning({
+ title: '关闭导入界面?',
+ desc: '已导入完毕,确认关闭导入界面!',
+ });
+ if (result) {
+ props.modal?.dismiss();
+ }
+ }
+ setTimeout(() => {
+ c.state.isLoading = false;
+ }, 300);
+ };
+
+ return {
+ c,
+ ns,
+ activeName,
+ materialItem,
+ modelClipboardController,
+ closeView,
+ clearModel,
+ formatData,
+ modelChange,
+ deleteDropItem,
+ dropModelChange,
+ saveModel,
+ };
+ },
+ render() {
+ const { isLoading, items, importItems, models, modelStr } = this.c.state;
+ return (
+
+ {{
+ header: () => {
+ return (
+
+ );
+ },
+ default: () => {
+ return (
+
+
+
+
this.dropModelChange(evt)}
+ >
+ {{
+ item: ({
+ element,
+ index,
+ }: {
+ element: ClipboardData;
+ index: number;
+ }) => {
+ const item = element;
+
+ return (
+
+
+
this.deleteDropItem(index)}
+ >
+
+
+
+
+ {item.title}
+
+
+ {item.createdDate}
+
+
+ );
+ },
+ }}
+
+
+ 请从右侧素材区拖入
+
+
+
+
+
+
+
+
+
+ this.modelChange(val)
+ }
+ >
+
+
+
+ this.clearModel()}
+ >
+ 清空
+
+ this.formatData()}
+ >
+ 格式化
+
+ this.saveModel()}
+ >
+ 导入
+
+
+
+
+
+
模型素材
+
+ {{
+ item: ({ element }: { element: ClipboardData }) => {
+ const item = element;
+
+ return (
+
+
+ {item.title}
+
+
+ {item.createdDate}
+
+
+ );
+ },
+ }}
+
+
+ 暂无数据
+
+
+
+ );
+ },
+ }}
+
+ );
+ },
+});
diff --git a/packages/model-design/src/components/model-clipboard/model-clipboard.scss b/packages/model-design/src/components/model-clipboard/model-clipboard.scss
index cdf8266e70b0744eb91ea1015ff14887c19f6399..1d96d0e11ec35acc4f0e39f2eb9c6a2fe711a740 100644
--- a/packages/model-design/src/components/model-clipboard/model-clipboard.scss
+++ b/packages/model-design/src/components/model-clipboard/model-clipboard.scss
@@ -37,12 +37,4 @@
.el-timeline {
padding: 0;
}
-}
-
-@include b(model-clipboard-drawer) {
- .el-drawer__header {
- .el-drawer__close-btn {
- display: none;
- }
- }
}
\ No newline at end of file
diff --git a/packages/model-design/src/components/model-clipboard/model-clipboard.tsx b/packages/model-design/src/components/model-clipboard/model-clipboard.tsx
index fb5fb41876e8b5498fecb58ec58361085c84dadb..45515a0699ee1261c93a7b1f3a192fa3fe4dd513 100644
--- a/packages/model-design/src/components/model-clipboard/model-clipboard.tsx
+++ b/packages/model-design/src/components/model-clipboard/model-clipboard.tsx
@@ -9,6 +9,10 @@ export default defineComponent({
context: { type: Object as PropType, default: () => ({}) },
params: { type: Object as PropType, default: () => ({}) },
modal: { type: Object as PropType },
+ type: {
+ type: String as PropType<'default' | 'advanced'>,
+ default: 'default',
+ },
},
setup(props) {
const ns = useNamespace('model-clipboard');
@@ -23,7 +27,7 @@ export default defineComponent({
desc: '确认删除当前粘贴板的数据?',
});
if (result) {
- controller.clearAll();
+ controller.clearAll(props.type);
}
}
};
@@ -43,7 +47,9 @@ export default defineComponent({
return (