houyaf hace 3 años
padre
commit
3639a12951

+ 14 - 0
src/api/model/modelObjectApi.ts

@@ -40,6 +40,20 @@ export function getObjectById(modelId: number, objectId: number) {
 }
 
 /**
+ * 根据Id获取Object
+ * @param modelId
+ * @param bizId
+ * @param objectId
+ * @returns
+ */
+export function selectForBizObjectMapping(modelId: number, bizId: number, objectId: number) {
+  return apiRequest({
+    url: `/model/object/select/${modelId}/${bizId}/${objectId}`,
+    method: 'GET',
+  })
+}
+
+/**
  * 添加Object
  * @param data
  * @returns

+ 9 - 9
src/views/biz/biz/components/Biz.vue

@@ -100,15 +100,15 @@ defineExpose({
           </el-form-item>
         </el-form>
       </div>
-
-      <template #footer>
-        <el-button size="large" @click="onCancel">
-          取消
-        </el-button>
-        <el-button type="primary" size="large" @click="onSubmit">
-          保存
-        </el-button>
-      </template>
     </el-scrollbar>
+
+    <template #footer>
+      <el-button size="large" @click="onCancel">
+        取消
+      </el-button>
+      <el-button type="primary" size="large" @click="onSubmit">
+        保存
+      </el-button>
+    </template>
   </el-drawer>
 </template>

+ 287 - 0
src/views/biz/mapping/components/ModelObjectSelector.vue

@@ -0,0 +1,287 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup name="bizObjectMapping">
+import { selectForBizObjectMapping } from '@/api/model/modelObjectApi'
+import { getModelByList } from '@/api/model/modelApi'
+import { createObjectMapping } from '@/api/biz/bizObjectMappingApi'
+
+const emit = defineEmits(['success'])
+
+interface TreeNode {
+  label: string
+  isLeaf: boolean
+  modelId: number
+  children?: TreeNode[]
+}
+
+interface Object {
+  modelId: number
+  objectId: number
+  objectTitle: string
+  objectCode: string
+  comment: string
+}
+
+const state = reactive({
+  title: '',
+  loading: false,
+  treeData: [] as TreeNode[],
+  objectList: [] as Object[],
+  dialogState: 1,
+  search: {
+    modelId: 0,
+    bizId: 0,
+    objectId: 0,
+    keywords: '',
+  },
+  formData: {
+    bizId: 0,
+    objectId: 0,
+    mappingModelId: 0,
+    mappingObjectId: 0,
+  },
+  dialogVisible: false,
+})
+
+const leftTreeRef = ref()
+const modelRef = ref()
+const getObjectData = async () => {
+  const { modelId, bizId, objectId } = state.search
+  state.loading = true
+  const { data } = await selectForBizObjectMapping(modelId, bizId, objectId)
+  state.loading = false
+  state.objectList = data
+}
+
+const getModelData = async () => {
+  const { data } = await getModelByList('')
+  const children: TreeNode[] = []
+  data.forEach((item: any) => {
+    return children.push({
+      label: item.modelTitle,
+      modelId: item.modelId,
+      isLeaf: true,
+    })
+  })
+  state.treeData = [
+    {
+      label: '数据模型库',
+      isLeaf: false,
+      modelId: -1,
+      children,
+    },
+  ]
+
+  if (data && data.length > 0) {
+    state.search.modelId = data[0].modelId
+    nextTick(() => {
+      leftTreeRef.value.setCurrentKey(data[0].modelId)
+    })
+    await getObjectData()
+  }
+}
+
+onMounted(() => {
+  getModelData()
+})
+
+// 模型选择
+const onTreeNodeClick = (node: TreeNode) => {
+  if (node.isLeaf) {
+    state.search.modelId = node.modelId
+    getObjectData()
+  }
+}
+
+function onCancel() {
+  state.dialogVisible = false
+}
+
+const onModelObjectMapping = async (row: any) => {
+  state.formData.mappingModelId = row.modelId
+  state.formData.mappingObjectId = row.objectId
+  await createObjectMapping(state.formData)
+  state.dialogVisible = false
+  emit('success')
+}
+
+defineExpose({
+  showModel(bizId: number, objectId: number) {
+    state.title = '新增业务对象映射'
+    state.formData.bizId = bizId
+    state.formData.objectId = objectId
+    state.search.bizId = bizId
+    state.search.objectId = objectId
+    state.dialogVisible = true
+  },
+})
+</script>
+
+<template>
+  <el-drawer v-model="state.dialogVisible" :title="state.title" size="80%">
+    <div class="absolute-container">
+      <tool-header title="数据模型" />
+
+      <div class="page-main">
+        <LayoutContainer left-side-width="250px" hide-left-side-toggle>
+          <template #leftSide>
+            <el-scrollbar class="tree">
+              <ElTree ref="leftTreeRef" :data="state.treeData" default-expand-all node-key="modelId" @node-click="onTreeNodeClick">
+                <template #default="{ node, data }">
+                  <div class="custom-tree-node">
+                    <div class="label" :title="node.label">
+                      <el-icon v-if="data.isLeaf" size="16px" style="margin-right: 5px;">
+                        <svg-icon name="bx:bxs-component" />
+                      </el-icon>
+                      <div class="text">
+                        {{ data.label }}
+                      </div>
+                    </div>
+                  </div>
+                </template>
+              </ElTree>
+            </el-scrollbar>
+          </template>
+
+          <div class="container">
+            <tool-bar>
+              <template #right>
+                <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
+                <el-button type="primary" @click="getObjectData">
+                  <template #icon>
+                    <el-icon>
+                      <svg-icon name="i-ep:search" />
+                    </el-icon>
+                  </template>
+                </el-button>
+              </template>
+            </tool-bar>
+
+            <el-table ref="modelObjectTableRef" v-loading="state.loading" class="list-table" :data="state.objectList" size="small" border stripe highlight-current-row height="100%">
+              <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+
+              <el-table-column prop="objectTitle" label="名称" header-align="center" align="center" width="200">
+                <template #default="scope">
+                  <el-icon>
+                    <svg-icon name="uim:box" />
+                  </el-icon>
+                  <span>{{ scope.row.objectTitle }}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column prop="objectCode" label="代码" header-align="center" align="center" width="150">
+                <template #default="scope">
+                  <span>{{ scope.row.objectCode }}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column prop="objectType" label="类型" header-align="center" align="center" width="150">
+                <template #default="scope">
+                  <span v-if="scope.row.objectType === 1">实体对象</span>
+                  <span v-else>视图对象</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column prop="comment" label="说明" header-align="center" align="left">
+                <template #default="scope">
+                  <span>{{ scope.row.comment }}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="操作" header-align="center" align="center" width="220">
+                <template #default="scope">
+                  <el-button type="primary" size="small" plain @click="onModelObjectMapping(scope.row)">
+                    选择
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </layoutcontainer>
+      </div>
+    </div>
+  </el-drawer>
+</template>
+
+<style lang="scss" scoped>
+.container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.absolute-container {
+  :deep(.left-side) {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+
+    .btns {
+      display: inline-flex;
+      width: 100%;
+      margin-bottom: var(--container-padding);
+
+      .add {
+        width: 100%;
+      }
+    }
+
+    .tree {
+      flex: 1;
+      overflow-y: auto;
+
+      .el-tree {
+        .el-tree-node__content {
+          height: 40px;
+        }
+
+        .is-current > .el-tree-node__content {
+          background-color: var(--el-color-primary-light-9);
+        }
+
+        .custom-tree-node {
+          flex: 1;
+          position: relative;
+          width: 0;
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+
+          .label {
+            display: inline-flex;
+            align-items: center;
+            width: calc(100% - 10px);
+            color: var(--el-text-color-primary);
+
+            .text {
+              @include text-overflow;
+            }
+          }
+
+          &:hover {
+            .actions {
+              display: block;
+            }
+          }
+
+          .actions {
+            display: none;
+            position: absolute;
+            right: 10px;
+            top: 50%;
+            transform: translateY(-50%);
+
+            .el-button {
+              padding: 5px 8px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 0 - 49
src/views/biz/mapping/components/ObjectMapping.vue

@@ -1,49 +0,0 @@
-<route lang="yaml">
-meta:
-  enabled: false
-</route>
-
-<script lang="ts" setup name="bizObjectMapping">
-import { getObjectMappingByList } from '@/api/biz/bizObjectMappingApi'
-
-const emit = defineEmits(['success'])
-
-// 数据
-const state = reactive({
-  title: '',
-  dialogVisible: false,
-  loading: false,
-  search: {
-    keywords: '',
-  },
-  formData: {
-    bizId: 0,
-    objectId: 0,
-    objectType: 1,
-    objectCode: '',
-    objectTitle: '',
-    comment: '',
-  },
-  actionType: 1,
-})
-
-onMounted(() => {})
-
-const getData = async () => {
-  const { bizId, objectId } = state.formData
-  state.loading = true
-  const { data } = await getObjectById(bizId, objectId)
-  state.loading = false
-  state.formData = data
-}
-
-defineExpose({
-  showModel(bizId: number) {
-    resetFormData()
-    state.title = '新增业务对象'
-    state.actionType = 1
-    state.formData.bizId = bizId
-    state.dialogVisible = true
-  },
-})
-</script>

+ 10 - 8
src/views/biz/mapping/index.vue

@@ -5,9 +5,10 @@ meta:
 
 <script lang="ts" setup name="BizObjectMappingList">
 import { ElMessage } from 'element-plus'
+import ModelObjectSelector from '@/views/biz/mapping/components/ModelObjectSelector.vue'
 import {
   deleteObjectMappingById,
-  getObjectAttrListById,
+  getObjectAttrListById, getObjectMappingByList,
 } from '@/api/biz/bizObjectMappingApi'
 const props = withDefaults(defineProps<{
   bizId: number
@@ -24,8 +25,6 @@ const state = reactive({
   loading: false,
   search: {
     keywords: '',
-  },
-  conditions: {
     bizId: props.bizId,
     objectId: props.objectId,
   },
@@ -36,23 +35,26 @@ const state = reactive({
 // 查询数据
 const getData = async () => {
   state.loading = true
-  const { bizId, objectId } = state.conditions
+  const { bizId, objectId } = state.search
   const { data } = await getObjectAttrListById(bizId, objectId)
   state.loading = false
   state.dataList = data
 }
 
 const objectMappingTableRef = ref()
+const modelObjectSelector = ref()
 
 function onObjectMappingAdd() {
-  state.actionType = 2
+  const { bizId, objectId } = state.search
+  modelObjectSelector.value.showModel(bizId, objectId)
 }
 
 async function onObjectMappingDelete(row: any) {
-  const { bizId, objectId } = state.conditions
+  const { bizId, objectId } = state.search
   const mappingId = row.mappingId
   await deleteObjectMappingById(bizId, objectId, mappingId)
   ElMessage.success('删除成功')
+  getData()
 }
 
 onMounted(() => {
@@ -106,8 +108,7 @@ onMounted(() => {
 
         <el-table-column label="映射代码" header-align="center" align="center">
           <template #default="scope">
-            <el-input v-if="scope.row.isEdit" v-model="scope.row.mappingCode" size="small" />
-            <span v-else>{{ scope.row.mappingCode }}</span>
+            <span>{{ scope.row.mappingObjectCode }}</span>
           </template>
         </el-table-column>
 
@@ -124,6 +125,7 @@ onMounted(() => {
         </el-table-column>
       </el-table>
     </div>
+    <ModelObjectSelector ref="modelObjectSelector" @success="getData" />
   </div>
 </template>
 

+ 11 - 11
src/views/model/model/components/Model.vue

@@ -97,17 +97,17 @@ defineExpose({
           <el-input v-model="state.formData.modelDesc" type="textarea" rows="10" placeholder="请输入标题" />
         </el-form-item>
       </el-form>
-
-      <template #footer>
-        <div style="flex: auto">
-          <el-button size="large" @click="onCancel">
-            取消
-          </el-button>
-          <el-button type="primary" size="large" @click="onSubmit">
-            保存
-          </el-button>
-        </div>
-      </template>
     </el-scrollbar>
+
+    <template #footer>
+      <div style="flex: auto">
+        <el-button size="large" @click="onCancel">
+          取消
+        </el-button>
+        <el-button type="primary" size="large" @click="onSubmit">
+          保存
+        </el-button>
+      </div>
+    </template>
   </el-drawer>
 </template>

+ 3 - 2
src/views/model/model/index.vue

@@ -38,7 +38,7 @@ const state = reactive({
   curModelId: 0,
   objectList: [] as Object[],
   dialogState: 1,
-  conditions: {
+  search: {
     keywords: '',
   },
 })
@@ -205,6 +205,7 @@ const onObjectDelete = (row: any) => {
         </el-button>
       </template>
     </tool-header>
+
     <div class="page-main">
       <LayoutContainer left-side-width="250px" hide-left-side-toggle>
         <template #leftSide>
@@ -248,7 +249,7 @@ const onObjectDelete = (row: any) => {
         <div class="container">
           <tool-bar>
             <template #right>
-              <el-input v-model="state.conditions.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
+              <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
               <el-button type="primary" @click="onSearch">
                 <template #icon>
                   <el-icon>