houyaf 3 年 前
コミット
a296e7c941

+ 1 - 1
src/api/biz/bizObjectOAMApi.ts

@@ -20,7 +20,7 @@ export function getObjectOAMByList(data: any) {
  * @param oamId
  * @returns
  */
-export function getObjectOAMByObjectId(bizId: number, objectId: number) {
+export function getObjectOAMListByObjectId(bizId: number, objectId: number) {
   return apiRequest({
     url: `/biz/object/oam/${bizId}/${objectId}`,
     method: 'GET',

+ 71 - 0
src/api/biz/bizObjectOAMParamsApi.ts

@@ -0,0 +1,71 @@
+import apiRequest from '@/network/http/apiRequest'
+
+/**
+ * 根据Id获取ObjectParams
+ * @param bizId
+ * @param objectId
+ * @param oamId
+ * @returns
+ */
+export function getObjectOAMParamsListByOamId(bizId: number, objectId: number, oamId: number) {
+  return apiRequest({
+    url: `/biz/object/oam/params/${bizId}/${objectId}/${oamId}`,
+    method: 'GET',
+  })
+}
+
+/**
+ * 根据Id获取ObjectParams
+ * @param bizId
+ * @param objectId
+ * @param oamId
+ * @param paramsId
+ * @returns
+ */
+export function getObjectOAMParamsById(bizId: number, objectId: number, oamId: number, paramsId: number) {
+  return apiRequest({
+    url: `/biz/object/oam/params/${bizId}/${objectId}/${oamId}/${paramsId}`,
+    method: 'GET',
+  })
+}
+
+/**
+ * 添加ObjectParams
+ * @param data
+ * @returns
+ */
+export function createObjectOAMParams(data: any) {
+  return apiRequest({
+    url: '/biz/object/oam/params/add',
+    method: 'POST',
+    data,
+  })
+}
+
+/**
+ * 更新ObjectParams
+ * @param data
+ * @returns
+ */
+export function updateObjectOAMParams(data: any) {
+  return apiRequest({
+    url: '/biz/object/oam/params/update',
+    method: 'PUT',
+    data,
+  })
+}
+
+/**
+ * 删除ObjectParams
+ * @param bizId
+ * @param objectId
+ * @param oamId
+ * @param paramsId
+ * @returns
+ */
+export function deleteObjectOAMParamsById(bizId: number, objectId: number, oamId: number, paramsId: number) {
+  return apiRequest({
+    url: `/biz/object/oam/params/${bizId}/${objectId}/${oamId}/${paramsId}`,
+    method: 'DELETE',
+  })
+}

+ 0 - 5
src/views/biz/attr/index.vue

@@ -332,11 +332,6 @@ function onSubmit() {
           display: inline-block;
         }
       }
-
-      .el-tag.sortable,
-      .el-tag.sortable .el-icon {
-        cursor: s-resize;
-      }
     }
   }
   h4{

+ 0 - 344
src/views/biz/biz/components/BizObject.vue

@@ -1,344 +0,0 @@
-<route lang="yaml">
-meta:
-  enabled: false
-</route>
-
-<script lang="ts" setup>
-import Sortable from 'sortablejs'
-import type { FormInstance, FormRules } from 'element-plus'
-import { ElMessage } from 'element-plus'
-import { createObject, getObjectById, updateObject } from '@/api/biz/bizObjectApi'
-const emit = defineEmits(['success'])
-
-interface ObjectAttr {
-  attrId: number
-  attrTitle: string
-  attrCode: string
-  attrType: number
-  attrLength: number
-  attrDecimals: number
-  isNotNull: number
-  isFixed: number
-  comment: string
-  isPKey: number
-  sortNo: number
-}
-
-const dataType = [
-  { dataType: 1, dataName: '整数' },
-  { dataType: 2, dataName: '字符串' },
-  { dataType: 3, dataName: '小数' }]
-
-const state = reactive({
-  title: '',
-  dialogVisible: false,
-  loading: false,
-  formData: {
-    bizId: 0,
-    objectId: 0,
-    objectCode: '',
-    objectTitle: '',
-    comment: '',
-    attrs: [] as ObjectAttr[],
-  },
-  actionType: 1,
-})
-
-const formRef = ref<FormInstance>()
-const formRules = ref<FormRules>({
-  objectTitle: [
-    { required: true, message: '请输入标题', trigger: 'blur' },
-  ],
-  objectCode: [
-    { required: true, message: '请输入标题', trigger: 'blur' },
-  ],
-  comment: [
-    { required: false, message: '请输入描述', trigger: 'blur' },
-  ],
-})
-
-// 查询数据
-const getData = async (bizId: number, objectId: number) => {
-  state.loading = true
-  const { data } = await getObjectById(bizId, objectId)
-  state.loading = false
-  state.formData = data
-}
-
-const attrsTableRef = ref()
-const attrsTableKey = ref(0)
-function onAttrAdd() {
-  state.formData.attrs.push({
-    attrId: 0,
-    attrTitle: '', // 名称
-    attrCode: '', // 代码
-    attrType: 0, // 类型
-    attrLength: 0, // 长度
-    attrDecimals: 0, // 小数位数
-    isNotNull: 0, // 是否为空
-    isFixed: 0, // 是否锁定
-    isPKey: 0, // 主键
-    comment: '', // 注释
-    sortNo: 0,
-  })
-  nextTick(() => {
-    attrsTableRef.value.setScrollTop(state.formData.attrs.length * 50)
-  })
-}
-
-// 删除属性
-function onAttrDelete(index: number) {
-  state.formData.attrs.splice(index, 1)
-}
-
-function onAttrDrag() {
-  const tbody = attrsTableRef.value.$el.querySelector('.el-table__body-wrapper tbody')
-  Sortable.create(tbody, {
-    handle: '.sortable',
-    animation: 300,
-    ghostClass: 'ghost',
-    onEnd: ({ newIndex, oldIndex }) => {
-      if (newIndex === undefined || oldIndex === undefined) {
-        return
-      }
-      const currRow = state.formData.attrs.splice(oldIndex, 1)[0]
-      state.formData.attrs.splice(newIndex, 0, currRow)
-      attrsTableKey.value += 1
-      nextTick(() => onAttrDrag())
-    },
-  })
-}
-
-onMounted(() => {
-  nextTick(() => {
-    onAttrDrag()
-  })
-})
-
-// 保存
-function onSubmit() {
-  formRef.value && formRef.value.validate(async (valid) => {
-    if (valid) {
-      state.formData.attrs.forEach((item, index) => item.sortNo = index)
-      if (state.actionType === 1) {
-        await createObject(state.formData)
-        state.dialogVisible = false
-        ElMessage.success('新增成功')
-        emit('success')
-      }
-      else {
-        await updateObject(state.formData)
-        state.dialogVisible = false
-        ElMessage.success('修改成功')
-        emit('success')
-      }
-    }
-  })
-}
-
-function onCancel() {
-  state.dialogVisible = false
-}
-
-function resetFormData() {
-  state.formData = {
-    bizId: 0,
-    objectId: 0,
-    objectCode: '',
-    objectTitle: '',
-    comment: '',
-    attrs: [],
-  }
-}
-
-defineExpose({
-  showAddModel(bizId: number) {
-    resetFormData()
-    state.title = '新增对象'
-    state.actionType = 1
-    state.dialogVisible = true
-    state.formData.bizId = bizId
-  },
-  showEditModel(bizId: number, objectId: number) {
-    resetFormData()
-    state.title = '编辑对象'
-    state.actionType = 2
-    state.dialogVisible = true
-    getData(bizId, objectId)
-  },
-
-})
-</script>
-
-<template>
-  <div v-show="state.dialogVisible">
-    <el-drawer :model-value="true" :title="state.title" size="80%" direction="ltr">
-      <template #default>
-        <el-row :gutter="20" class="container">
-          <el-col :span="7" :xs="24" class="form-left-side">
-            <h2>基本信息</h2>
-            <el-scrollbar>
-              <div class="form-content">
-                <el-form ref="formRef" :model="state.formData" :rules="formRules" label-position="top">
-                  <el-form-item label="对象名称" prop="objectTitle">
-                    <el-input v-model="state.formData.objectTitle" placeholder="请输入标题" />
-                  </el-form-item>
-                  <el-form-item label="对象代码" prop="objectCode">
-                    <el-input v-model="state.formData.objectCode" placeholder="请输入代码" />
-                  </el-form-item>
-                  <el-form-item label="简要说明" prop="comment">
-                    <el-input v-model="state.formData.comment" type="textarea" rows="10" placeholder="请输入标题" />
-                  </el-form-item>
-                </el-form>
-              </div>
-            </el-scrollbar>
-          </el-col>
-          <el-col :span="17" :xs="24" class="form-right-side">
-            <h2>属性</h2>
-            <el-table ref="attrsTableRef" :key="attrsTableKey" :data="state.formData.attrs" border stripe highlight-current-row>
-              <el-table-column width="60" align="center" fixed>
-                <template #header>
-                  <el-button type="primary" size="small" plain circle @click="onAttrAdd">
-                    <template #icon>
-                      <el-icon>
-                        <svg-icon name="i-ep:plus" />
-                      </el-icon>
-                    </template>
-                  </el-button>
-                </template>
-
-                <template #default="scope">
-                  <span class="index">{{ scope.$index + 1 }}</span>
-                  <el-button type="danger" size="small" plain circle class="delete" @click="onAttrDelete(scope.$index)">
-                    <template #icon>
-                      <el-icon>
-                        <svg-icon name="i-ep:delete" />
-                      </el-icon>
-                    </template>
-                  </el-button>
-                </template>
-              </el-table-column>
-
-              <el-table-column label="名称" width="150">
-                <template #default="scope">
-                  <el-input v-model="scope.row.attrTitle" />
-                </template>
-              </el-table-column>
-
-              <el-table-column label="代码" width="120">
-                <template #default="scope">
-                  <el-input v-model="scope.row.attrCode" />
-                </template>
-              </el-table-column>
-
-              <el-table-column label="类型" width="120">
-                <template #default="scope">
-                  <el-select v-model="scope.row.attrType">
-                    <el-option
-                      v-for="item in dataType"
-                      :key="item.dataType"
-                      :value="item.dataType"
-                      :label="item.dataName"
-                    />
-                  </el-select>
-                </template>
-              </el-table-column>
-
-              <el-table-column label="长度" width="90">
-                <template #default="scope">
-                  <el-input v-model="scope.row.attrLength" />
-                </template>
-              </el-table-column>
-
-              <el-table-column label="小数位数" width="90">
-                <template #default="scope">
-                  <el-input v-model="scope.row.attrDecimals" />
-                </template>
-              </el-table-column>
-
-              <el-table-column label="是否为空" width="90">
-                <template #default="scope">
-                  <el-checkbox v-model="scope.row.isNotNull" :true-label="1" :false-label="0">
-                    {{ scope.row.isNotNull === 1 ? '是' : '否' }}
-                  </el-checkbox>
-                </template>
-              </el-table-column>
-
-              <el-table-column label="注释" width="120">
-                <template #default="scope">
-                  <el-input v-model="scope.row.comment" />
-                </template>
-              </el-table-column>
-
-              <el-table-column width="80" align="center">
-                <template #header>
-                  排序
-                </template>
-                <template #default>
-                  <el-tag type="info" class="sortable">
-                    <el-icon>
-                      <svg-icon name="i-ep:d-caret" />
-                    </el-icon>
-                  </el-tag>
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-col>
-        </el-row>
-      </template>
-
-      <template #footer>
-        <div style="flex: auto">
-          <el-button type="primary" size="large" @click="onSubmit">
-            提交
-          </el-button>
-          <el-button size="large" @click="onCancel">
-            取消
-          </el-button>
-        </div>
-      </template>
-    </el-drawer>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-    .form-right-side {
-      // display: flex;
-      // flex-direction: column;
-      // width: 500px;
-      padding: var(--container-padding);
-      border-left: 1px dashed var(--el-disabled-border-color);
-      background-color: var(--g-app-bg);
-      transition: background-color 0.3s;
-
-      :deep(.el-table) {
-        height: 100%;
-        margin-top: 15px;
-
-        .el-table__row {
-          .index {
-            display: inline-block;
-          }
-
-          .delete {
-            display: none;
-          }
-
-          &:hover {
-            .index {
-              display: none;
-            }
-
-            .delete {
-              display: inline-block;
-            }
-          }
-
-          .el-tag.sortable,
-          .el-tag.sortable .el-icon {
-            cursor: s-resize;
-          }
-        }
-      }
-    }
-</style>

+ 4 - 3
src/views/biz/biz/index.vue

@@ -5,7 +5,7 @@ meta:
 
 <script lang="ts" setup>
 import { ElMessage, ElMessageBox } from 'element-plus'
-import BizObjectComponent from '../object/compnents/Object.vue'
+import BizObjectComponent from '../object/components/Object.vue'
 import BizComponent from './components/Biz.vue'
 import { deleteBizById, getBizByList } from '@/api/biz/bizApi'
 import { deleteObjectById, getObjectByList } from '@/api/biz/bizObjectApi'
@@ -269,7 +269,7 @@ const onObjectDelete = (row: any) => {
           <el-table ref="objectTableRef" v-loading="state.loading" class="list-table" :data="state.objectList" border stripe highlight-current-row height="100%">
             <el-table-column type="index" label="序号" header-align="center" align="center" width="70" />
 
-            <el-table-column prop="objectTitle" label="名称" header-align="center" align="center" width="200">
+            <el-table-column prop="objectTitle" label="对象名称" header-align="center" align="center" width="200">
               <template #default="scope">
                 <el-icon>
                   <svg-icon name="uim:box" />
@@ -278,7 +278,7 @@ const onObjectDelete = (row: any) => {
               </template>
             </el-table-column>
 
-            <el-table-column prop="objectCode" label="代码" header-align="center" align="center" width="150">
+            <el-table-column prop="objectCode" label="对象代码" header-align="center" align="center" width="150">
               <template #default="scope">
                 <span>{{ scope.row.objectCode }}</span>
               </template>
@@ -292,6 +292,7 @@ const onObjectDelete = (row: any) => {
 
             <el-table-column label="操作" header-align="center" align="center" width="230">
               <template #default="scope">
+                <el-button type="primary" size="small" plain @click="onObjectOAM(scope.row)">行为</el-button>
                 <el-button type="warning" size="small" plain @click="onObjectDetails(scope.row)">详情</el-button>
                 <el-button type="danger" size="small" plain @click="onObjectDelete(scope.row)">删除</el-button>
               </template>

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


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

@@ -0,0 +1,49 @@
+<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>

+ 1 - 1
src/views/biz/oam/components/RuleSelector.vue

@@ -1,4 +1,4 @@
-<script lang="ts" setup name="AppCatSelector">
+<script lang="ts" setup name="BizRuleSelector">
 import { getBizRuleByList } from '@/api/biz/bizRuleApi'
 const props = withDefaults(defineProps<{
   modelValue: number

+ 266 - 189
src/views/biz/oam/index.vue

@@ -3,25 +3,30 @@ meta:
   enabled: false
 </route>
 
-<script lang="ts" setup name="BizObjectOAMListComponent">
+<script lang="ts" setup name="BizObjectOAM">
+import type { TabsPaneContext } from 'element-plus'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import ObjectOAMComponent from './components/ObjectOAM.vue'
-import ObjectOAMRuleComponent from './components/ObjectOAMRule.vue'
-import { deleteObjectOAMById, getObjectOAMById, getObjectOAMByList } from '@/api/biz/bizObjectOAMApi'
-import { deleteObjectOAMRuleById, getObjectOAMRuleListByOamId } from '@/api/biz/bizObjectOAMRuleApi'
+import ObjectOAMComponent from './components/objectOAM.vue'
+import ObjectOAMRuleComponent from './components/objectOAMRule.vue'
+import useSettingsStore from '@/store/modules/settings'
+import { getObjectById } from '@/api/biz/bizObjectApi'
+import { deleteObjectOAMById, getObjectOAMById, getObjectOAMListByObjectId } from '@/api/biz/bizObjectOAMApi'
+import { getObjectOAMRuleListByOamId } from '@/api/biz/bizObjectOAMRuleApi'
 import { oamType, sqlType } from '@/utils/tool'
-const props = withDefaults(defineProps<{
-  bizId: number
-  objectId: number
-}>(), {
-  bizId: 0,
-  objectId: 0,
-})
+
+const settingsStore = useSettingsStore()
+const route = useRoute()
+const router = useRouter()
+const tabbar = useTabbar()
+
+const bizId = parseInt(route.params.bizId.toString())
+const objectId = parseInt(route.params.objectId.toString())
 
 interface TreeNode {
   label: string
   isLeaf: boolean
   oamId: number
+  oamCode: string
   children?: TreeNode[]
 }
 
@@ -48,15 +53,16 @@ const state = reactive({
   objectTitle: '',
   objectCode: '',
   objectType: 0,
+  keywords: '',
   curOamId: 0,
   oamList: [],
   objectOamRuleList: [],
   treeData: [] as TreeNode[],
   oam: {} as ObjectOAM,
   dialogState: 1,
-  conditions: {
-    bizId: props.bizId,
-    objectId: props.objectId,
+  search: {
+    bizId,
+    objectId,
     keywords: '',
   },
   params: '',
@@ -65,11 +71,19 @@ const state = reactive({
 
 const leftTreeRef = ref()
 
+const getObjectData = async () => {
+  state.loading = true
+  const { data } = await getObjectById(bizId, objectId)
+  state.objectTitle = data.objectTitle
+  state.objectCode = data.objectCode
+  state.objectType = data.objectType
+  state.loading = false
+}
+
 const getObjectOAMData = async () => {
   const curOamId = state.curOamId
   if (curOamId > 0) {
     state.loading = true
-    const { bizId, objectId } = state.conditions
     const { data } = await getObjectOAMById(bizId, objectId, curOamId)
     state.oam = data
     state.loading = false
@@ -80,7 +94,6 @@ const getObjectOAMRuleList = async () => {
   const curOamId = state.curOamId
   if (curOamId > 0) {
     state.loading = true
-    const { bizId, objectId } = state.conditions
     const { data } = await getObjectOAMRuleListByOamId(bizId, objectId, curOamId)
     state.objectOamRuleList = data
     state.loading = false
@@ -88,13 +101,14 @@ const getObjectOAMRuleList = async () => {
 }
 
 const getOAMTree = async () => {
-  const { data } = await getObjectOAMByList(state.conditions)
+  const { data } = await getObjectOAMListByObjectId(bizId, objectId)
   state.treeData = []
-  if (data && data.length > 0){
+  if (data && data.length > 0) {
     data.forEach((item: any) => {
       state.treeData.push({
         label: item.oamTitle,
         oamId: item.oamId,
+        oamCode: item.oamCode,
         isLeaf: true,
       })
     })
@@ -109,6 +123,7 @@ const getOAMTree = async () => {
 }
 
 onMounted(() => {
+  getObjectData()
   getOAMTree()
 })
 
@@ -117,18 +132,15 @@ const onTreeNodeClick = (node: TreeNode) => {
   if (node.isLeaf) {
     state.curOamId = node.oamId
     getObjectOAMData()
-    getObjectOAMRuleList()
   }
 }
 
 const objectOAMRef = ref()
 const onAddOAM = () => {
-  const { bizId, objectId } = state.conditions
   objectOAMRef.value.showAddModel(bizId, objectId)
 }
 
 const onEditOAM = () => {
-  const { bizId, objectId } = state.conditions
   objectOAMRef.value.showEditModel(bizId, objectId, state.curOamId)
 }
 
@@ -146,10 +158,14 @@ const onDeleteOAM = (data: { bizId: number; objectId: number; oamId: number; oam
 
 // 选择对象模型回调
 const onSuccess = () => {
-  // getOAMTree()
+  getOAMTree()
 }
 
-const tabIndex = ref(1)
+const activeName = ref('first')
+
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event)
+}
 
 const objectOAMRuleRef = ref()
 const onObjectOAMRuleSearch = () => {
@@ -157,178 +173,249 @@ const onObjectOAMRuleSearch = () => {
 }
 
 const onObjectOAMRuleAdd = () => {
-  const { bizId, objectId } = state.conditions
   objectOAMRuleRef.value.showAddModel(bizId, objectId, state.curOamId)
 }
 
 const onObjectOAMRuleEdit = (row: { orId: number }) => {
-  const { bizId, objectId } = state.conditions
   objectOAMRuleRef.value.showEditModel(bizId, objectId, state.curOamId, row.orId)
 }
 
-const onObjectOAMRuleDelete = (row: { bizId: number; objectId: number; oamId: number; orId: number; ruleTitle: string }) => {
-  const { bizId, objectId, oamId, orId, ruleTitle } = row
-  ElMessageBox.confirm(`确认删除「${ruleTitle}」吗?`, '确认信息').then(async () => {
-    await deleteObjectOAMRuleById(bizId, objectId, oamId, orId)
-    await getObjectOAMRuleList()
-    ElMessage.success({
-      message: '删除成功',
-      center: true,
-    })
-  })
+const onObjectOAMRuleDelete = (row: { }) => {
+
+}
+// 返回列表页
+function goBack() {
+  if (settingsStore.settings.tabbar.enable && settingsStore.settings.tabbar.mergeTabsBy !== 'activeMenu') {
+    tabbar.close({ name: 'biz_object_list' })
+  }
+  else {
+    router.push({ name: 'biz_object_list' })
+  }
 }
 </script>
 
 <template>
-  <div class="page-main">
-    <LayoutContainer left-side-width="250px" hide-left-side-toggle>
-      <template #leftSide>
-        <el-button-group class="btns">
-          <el-button type="primary" class="add" @click="onAddOAM()">
-            新增对象行为
-          </el-button>
-          <el-button @click="getObjectOAMData">
-            <template #icon>
-              <el-icon>
-                <svg-icon name="i-ep:refresh" />
-              </el-icon>
-            </template>
-          </el-button>
-        </el-button-group>
-
-        <el-scrollbar class="tree">
-          <ElTree ref="leftTreeRef" :data="state.treeData" default-expand-all node-key="oamId" @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="ep:key" />
-                  </el-icon>
-                  <div class="text">
-                    {{ data.label }}
-                  </div>
-                  <div class="code">
-                    {{ oamType(data.oamType) }}
+  <div class="absolute-container">
+    <page-header :title="state.objectTitle" :content="state.objectCode ">
+      <el-button size="default" round @click="goBack">
+        <template #icon>
+          <el-icon>
+            <svg-icon name="i-ep:arrow-left" />
+          </el-icon>
+        </template>
+        返回
+      </el-button>
+    </page-header>
+
+    <div class="page-main">
+      <LayoutContainer left-side-width="250px" hide-left-side-toggle>
+        <template #leftSide>
+          <el-button-group class="btns">
+            <el-button type="primary" class="add" @click="onAddOAM()">
+              <template #icon>
+                <el-icon>
+                  <svg-icon name="i-ep:plus" />
+                </el-icon>
+              </template>
+              对象行为
+            </el-button>
+            <el-button @click="getObjectOAMData">
+              <template #icon>
+                <el-icon>
+                  <svg-icon name="i-ep:refresh" />
+                </el-icon>
+              </template>
+            </el-button>
+          </el-button-group>
+          <el-input placeholder="请输入关键词筛选" clearable class="search" />
+
+          <el-scrollbar class="tree">
+            <ElTree ref="leftTreeRef" :data="state.treeData" default-expand-all node-key="oamId" @node-click="onTreeNodeClick">
+              <template #default="{ node, data }">
+                <div class="custom-tree-node">
+                  <div class="label" :title="node.label">
+                    <div class="text">
+                      <el-icon v-if="data.isLeaf" size="16px" style="margin:0 5px 5px 0;">
+                        <svg-icon name="ant-design:api-outlined" />
+                      </el-icon>
+                      <span>{{ data.label }}</span>
+                    </div>
+                    <div class="code">
+                      {{ data.oamCode }}
+                    </div>
                   </div>
                 </div>
-              </div>
-            </template>
-          </ElTree>
-        </el-scrollbar>
-      </template>
-
-      <div class="container">
-        <page-main title="基础用法" class="demo">
-          <el-radio v-model="tabIndex" label="1">
-            行为定义
-          </el-radio>
-          <el-radio v-model="tabIndex" label="2">
-            业务规则
-          </el-radio>
-        </page-main>
-
-        <page-main v-show="tabIndex === 1">
-          <div class="form">
-            <tool-header>
-              <template #right>
-                <el-button type="primary" @click="onEditOAM">
-                  编辑
-                </el-button>
               </template>
-            </tool-header>
-            <page-main v-if="state.oam" :title="state.oam.oamTitle">
-              <div class="question">
-                <ol class="answer">
-                  <li><span>编码:</span><br>{{ state.oam.oamCode }}</li>
-                  <li><span>行为类型:</span><br>{{ oamType(state.oam.oamType) }}</li>
-                  <li><span>操作类型:</span><br>{{ sqlType(state.oam.sqlType) }}</li>
-                  <li v-if="state.oam.sqlType === 1">
-                    <span>Sql:</span><br>{{ state.oam.sqlStatement }}
-                  </li>
-                  <li v-if="state.oam.oamType === 3">
-                    <span>Count</span><br>{{ state.oam.sqlCount }}
-                  </li>
-                  <li><span>说明</span><br>{{ state.oam.oamDesc }}</li>
-                </ol>
-              </div>
-            </page-main>
-          </div>
-        </page-main>
-
-        <page-main v-show="tabIndex === 2">
-          <tool-bar>
-            <template #right>
-              <el-input v-model="state.conditions.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
-              <el-button type="primary" @click="onObjectOAMRuleSearch">
-                <template #icon>
-                  <el-icon>
-                    <svg-icon name="i-ep:search" />
-                  </el-icon>
+            </ElTree>
+          </el-scrollbar>
+        </template>
+
+        <div class="container">
+          <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+            <el-tab-pane label="行为定义" name="first">
+              <el-descriptions
+                :title="state.oam.oamTitle"
+                :column="1"
+                border
+              >
+                <template #extra>
+                  <el-button type="primary" @click="onEditOAM">
+                    编辑
+                  </el-button>
                 </template>
-              </el-button>
 
-              <el-button type="primary" size="default" @click.stop="onObjectOAMRuleAdd">
-                <template #icon>
-                  <el-icon>
-                    <svg-icon name="i-ep:plus" />
-                  </el-icon>
+                <el-descriptions-item
+                  label-align="right"
+                  label="编码"
+                  width="150px"
+                >
+                  {{ state.oam.oamCode }}
+                </el-descriptions-item>
+
+                <el-descriptions-item
+                  label="行为类型"
+                  width="150px"
+                  label-align="right"
+                >
+                  {{ oamType(state.oam.oamType) }}
+                </el-descriptions-item>
+
+                <el-descriptions-item
+                  label-align="right"
+                  width="150px"
+                  label="操作类型"
+                >
+                  {{ sqlType(state.oam.sqlType) }}
+                </el-descriptions-item>
+
+                <el-descriptions-item
+                  v-if="state.oam.sqlType === 1"
+                  label-align="right"
+                  width="150px"
+                  label="Sql"
+                >
+                  {{ state.oam.sqlStatement }}
+                </el-descriptions-item>
+
+                <el-descriptions-item
+                  v-if="state.oam.oamType === 3"
+                  label-align="right"
+                  width="150px"
+                  label="Count"
+                >
+                  {{ state.oam.sqlCount }}
+                </el-descriptions-item>
+
+                <el-descriptions-item
+                  label-align="right"
+                  width="150px"
+                  label="说明"
+                >
+                  {{ state.oam.oamDesc }}
+                </el-descriptions-item>
+              </el-descriptions>
+            </el-tab-pane>
+
+            <el-tab-pane label="查询参数" name="second">
+
+            </el-tab-pane>
+
+            <el-tab-pane label="业务规则" name="three">
+              <tool-bar>
+                <template #left>
+                  <h4>业务规则</h4>
                 </template>
-                业务规则
-              </el-button>
-            </template>
-          </tool-bar>
-
-          <el-table ref="objectRuleTableRef" v-loading="state.loading" class="list-table" :data="state.objectOamRuleList" border stripe highlight-current-row height="100%">
-            <el-table-column type="index" label="序号" header-align="center" align="center" width="70" />
 
-            <el-table-column prop="objectTitle" label="名称" header-align="center" align="center" width="200">
-              <template #default="scope">
-                <el-icon>
-                  <svg-icon name="lucide:clipboard-check" />
-                </el-icon>
-                <span> &nbsp;&nbsp;{{ scope.row.objectTitle }}</span>
-              </template>
-            </el-table-column>
-
-            <el-table-column prop="attrTitle" label="属性" header-align="center" align="center" width="250">
-              <template #default="scope">
-                <span> {{ scope.row.targetAttrTitle }}-{{ scope.row.targetAttrCode }}</span>
-              </template>
-            </el-table-column>
-
-            <el-table-column prop="ruleTitle" label="规则" header-align="center" align="center" width="150" />
-
-            <el-table-column label="操作" header-align="center" align="center" width="230">
-              <template #default="scope">
-                <el-button type="warning" size="small" plain @click="onObjectOAMRuleEdit(scope.row)">
-                  编辑
-                </el-button>
-                <el-button type="danger" size="small" plain @click="onObjectOAMRuleDelete(scope.row)">
-                  删除
-                </el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </page-main>
-      </div>
-    </LayoutContainer>
+                <template #right>
+                  <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
+                  <el-button type="primary" @click="onObjectOAMRuleSearch">
+                    <template #icon>
+                      <el-icon>
+                        <svg-icon name="i-ep:search" />
+                      </el-icon>
+                    </template>
+                  </el-button>
+
+                  <el-button type="primary" size="default" @click.stop="onObjectOAMRuleAdd">
+                    <template #icon>
+                      <el-icon>
+                        <svg-icon name="i-ep:plus" />
+                      </el-icon>
+                    </template>
+                    业务规则
+                  </el-button>
+                </template>
+              </tool-bar>
+
+              <el-table ref="objectRuleTableRef" v-loading="state.loading" class="list-table" :data="state.objectOamRuleList" border stripe highlight-current-row height="100%">
+                <el-table-column type="index" label="序号" header-align="center" align="center" width="70" />
+
+                <el-table-column prop="objectTitle" label="名称" header-align="center" align="center" width="200">
+                  <template #default="scope">
+                    <el-icon>
+                      <svg-icon name="lucide:clipboard-check" />
+                    </el-icon>
+                    <span> &nbsp;&nbsp;{{ scope.row.objectTitle }}</span>
+                  </template>
+                </el-table-column>
+
+                <el-table-column prop="ruleTitle" label="规则" header-align="center" align="center" width="150" />
+
+                <el-table-column label="操作" header-align="center" align="center" width="230">
+                  <template #default="scope">
+                    <el-button type="warning" size="small" plain @click="onObjectOAMRuleEdit(scope.row)">
+                      编辑
+                    </el-button>
+                    <el-button type="danger" size="small" plain @click="onObjectOAMRuleDelete(scope.row)">
+                      删除
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-tab-pane>
+          </el-tabs>
+        </div>
+      </LayoutContainer>
+    </div>
+    <ObjectOAMComponent ref="objectOAMRef" @success="getOAMTree" />
+    <ObjectOAMRuleComponent ref="objectOAMRuleRef" @success="getObjectOAMRuleList" />
   </div>
-  <ObjectOAMComponent ref="objectOAMRef" @success="getOAMTree" />
-  <ObjectOAMRuleComponent ref="objectOAMRuleRef" @success="getObjectOAMRuleList" />
 </template>
 
 <style lang="scss" scoped>
 .absolute-container {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
   .page-header {
     margin-bottom: 0;
   }
 
+  .page-main {
+    // 让 page-main 的高度自适应
+    flex: 1;
+    overflow: auto;
+    display: flex;
+    flex-direction: column;
+
+    .flex-container {
+      position: static;
+    }
+  }
+}
+
+.flex-container{
   :deep(.left-side) {
     display: flex;
     flex-direction: column;
     height: 100%;
-
-    .btns {
+      .search{
+        margin: 15px 0;
+      }
+      .btns {
       display: inline-flex;
       width: 100%;
 
@@ -343,7 +430,7 @@ const onObjectOAMRuleDelete = (row: { bizId: number; objectId: number; oamId: nu
 
       .el-tree {
         .el-tree-node__content {
-          height: 40px;
+          height: 60px;
         }
 
         .is-current > .el-tree-node__content {
@@ -360,33 +447,30 @@ const onObjectOAMRuleDelete = (row: { bizId: number; objectId: number; oamId: nu
           justify-content: center;
 
           .label {
-            display: inline-flex;
-            align-items: center;
             width: calc(100% - 10px);
             color: var(--el-text-color-primary);
+            padding: 10px;
+
+            @include text-overflow;
 
-            .text {
-              @include text-overflow;
+            .el-icon {
+              padding-top: 5px;
             }
           }
 
+          .code {
+            padding-left: 20px;
+            width: calc(100% - 10px);
+            color: var(--el-text-color-placeholder);
+
+            @include text-overflow;
+          }
+
           &:hover {
             .actions {
               display: block;
             }
           }
-
-          .actions {
-            display: none;
-            position: absolute;
-            right: 10px;
-            top: 50%;
-            transform: translateY(-50%);
-
-            .el-button {
-              padding: 5px 8px;
-            }
-          }
         }
       }
     }
@@ -414,11 +498,4 @@ const onObjectOAMRuleDelete = (row: { bizId: number; objectId: number; oamId: nu
     }
   }
 }
-
-.demo-tabs > .el-tabs__content {
-  padding: 22px;
-  color: #6b778c;
-  font-size: 32px;
-  font-weight: 600;
-}
 </style>

+ 0 - 0
src/views/biz/object/compnents/Object.vue → src/views/biz/object/components/Object.vue


+ 6 - 6
src/views/biz/object/index.vue

@@ -5,7 +5,7 @@ meta:
 
 <script lang="ts" setup name="bizObjectDetails">
 import type { TabsPaneContext } from 'element-plus'
-import BizObjectComponent from '../object/compnents/Object.vue'
+import BizObjectComponent from '@/views/biz/object/components/Object.vue'
 import BizObjectOAMListComponent from '../oam/index.vue'
 import BizObjectAttrListComponent from '../attr/index.vue'
 import BizObjectMappingListComponent from '../mapping/index.vue'
@@ -96,6 +96,7 @@ function goBack() {
         返回
       </el-button>
     </page-header>
+
     <page-main>
       <div class="container">
         <el-tabs v-model="activeTab" class="demo-tabs" @tab-click="handleClick">
@@ -137,10 +138,6 @@ function goBack() {
             <BizObjectAttrListComponent :bizId="bizId" :objectId="objectId" ref="bizObjectAttrList" />
           </el-tab-pane>
 
-          <el-tab-pane label="对象行为" name="three">
-            <BizObjectOAMListComponent :bizId="bizId" :objectId="objectId" ref="bizObjectOAMList" />
-          </el-tab-pane>
-
           <el-tab-pane label="模型映射" name="four">
             <BizObjectMappingListComponent :bizId="bizId" :objectId="objectId" ref="bizObjectMappingList" />
           </el-tab-pane>
@@ -154,10 +151,13 @@ function goBack() {
 
 <style scoped>
 .el-descriptions {
-  margin: 10px;
+  margin: 0 10px;
 }
 .cell-item {
   display: flex;
   align-items: center;
 }
+::v-deep .el-tabs__content{
+  min-height: 67vh;
+}
 </style>

+ 342 - 0
src/views/biz/params/index.vue

@@ -0,0 +1,342 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup name="BizObjectParamsList">
+import type { FormInstance, FormRules } from 'element-plus'
+import { ElMessage } from 'element-plus'
+import { dataType } from '@/utils/tool'
+import {
+  createObjectAttr,
+  deleteObjectAttrById,
+  getObjectAttrListById,
+  updateObjectAttr,
+} from '@/api/biz/bizObjectParamsApi'
+const props = withDefaults(defineProps<{
+  bizId: number
+  objectId: number
+}>(), {
+  bizId: 0,
+  objectId: 0,
+})
+
+interface ObjectAttr {
+  bizId: number
+  objectId: number
+  attrId: number
+  attrTitle: string
+  attrCode: string
+  mappingCode: string
+  attrType: number
+  attrLength: number
+  attrDecimals: number
+  isNotNull: number
+  comment: string
+  sortNo: number
+  isEdit: boolean
+}
+
+// 数据
+const state = reactive({
+  title: '',
+  dialogVisible: false,
+  loading: false,
+  search: {
+    keywords: '',
+  },
+  conditions: {
+    bizId: props.bizId,
+    objectId: props.objectId,
+  },
+  attrs: [] as ObjectAttr[],
+  actionType: 1,
+})
+
+const formRef = ref<FormInstance>()
+const formRules = reactive<FormRules>({
+  objectTitle: [
+    { required: true, message: '请输入对象标题', trigger: 'blur' },
+  ],
+  objectType: [
+    { required: true, message: '请输入对象类型', trigger: 'blur' },
+  ],
+  objectCode: [
+    { required: true, message: '请输入对像代码', trigger: 'blur' },
+  ],
+  comment: [
+    { required: false, message: '请输入简要描述', trigger: 'blur' },
+  ],
+})
+
+// 查询数据
+const getData = async () => {
+  state.loading = true
+  const { bizId, objectId } = state.conditions
+  const { data } = await getObjectAttrListById(bizId, objectId)
+  state.loading = false
+  state.attrs = data
+  data.forEach((attr: ObjectAttr) => {
+    attr.isEdit = false
+  })
+}
+
+const attrsTableRef = ref()
+const attrsTableKey = ref(0)
+
+function onAttrAdd() {
+  state.attrs.push({
+    bizId: props.bizId,
+    objectId: props.objectId,
+    attrId: 0,
+    attrTitle: '', // 名称
+    attrCode: '', // 代码
+    mappingCode: '',
+    attrType: 0, // 类型
+    attrLength: 0, // 长度
+    attrDecimals: 0, // 小数位数
+    isNotNull: 0, // 是否为空
+    comment: '', // 注释
+    sortNo: 0,
+    isEdit: true,
+  })
+  state.actionType = 1
+}
+
+function onAttrEdit(row: any) {
+  row.isEdit = true
+  state.actionType = 2
+}
+
+async function onAttrDelete(row: any) {
+  const { bizId, objectId } = state.conditions
+  const attrId = row.attrId
+  await deleteObjectAttrById(bizId, objectId, attrId)
+  ElMessage.success('删除成功')
+}
+
+function onAttrCancel(row: any, index: number) {
+  row.isEdit = false
+  if (state.actionType === 1) {
+    state.attrs.splice(index, 1)
+  }
+  state.actionType = 0
+}
+
+async function onAttrSave(row: any) {
+  row.isEdit = false
+  if (state.actionType === 1) {
+    await createObjectAttr(row)
+    state.dialogVisible = false
+    ElMessage.success('新增成功')
+  }
+  else {
+    await updateObjectAttr(row)
+    state.dialogVisible = false
+    ElMessage.success('修改成功')
+  }
+}
+
+onMounted(() => {
+  getData()
+  nextTick(() => {
+  })
+})
+
+// 保存
+function onSubmit() {
+  formRef.value && formRef.value.validate(async (valid) => {
+    if (valid) {
+      if (state.actionType === 1) {
+        await createObjectAttr(state.attrs)
+        state.dialogVisible = false
+        ElMessage.success('新增成功')
+      }
+      else {
+        await updateObjectAttr(state.attrs)
+        state.dialogVisible = false
+        ElMessage.success('修改成功')
+      }
+    }
+  })
+}
+</script>
+
+<template>
+  <div class="absolute-container">
+    <div class="container">
+      <tool-bar>
+        <template #left>
+          <h4>对象属性</h4>
+        </template>
+        <template #right>
+          <el-input v-model="state.search.keywords" placeholder="请输入关键词筛选" clearable style="width: 200px;" />
+          <el-button style="margin-left:10px" @click="getData">
+            <template #icon>
+              <el-icon>
+                <svg-icon name="i-ep:search" />
+              </el-icon>
+            </template>
+          </el-button>
+
+          <el-button type="default" @click="onAttrAdd">
+            <template #icon>
+              <el-icon>
+                <svg-icon name="i-ep:plus" />
+              </el-icon>
+            </template>
+          </el-button>
+        </template>
+      </tool-bar>
+
+      <el-table ref="attrsTableRef" :key="attrsTableKey" :data="state.attrs" class="list-table" size="small" border stripe highlight-current-row>
+        <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+
+        <el-table-column label="名称" header-align="center" align="center" width="150">
+          <template #default="scope">
+            <el-input v-if="scope.row.isEdit" v-model="scope.row.attrTitle" size="small" />
+            <span v-else>{{ scope.row.attrTitle }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="代码" header-align="center" align="center" width="120">
+          <template #default="scope">
+            <el-input v-if="scope.row.isEdit" v-model="scope.row.attrCode" size="small" />
+            <span v-else>{{ scope.row.attrCode }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="映射代码" header-align="center" align="center" width="120">
+          <template #default="scope">
+            <el-input v-if="scope.row.isEdit" v-model="scope.row.mappingCode" size="small" />
+            <span v-else>{{ scope.row.mappingCode }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="类型" header-align="center" align="center" width="120">
+          <template #default="scope">
+            <data-type-selector v-if="scope.row.isEdit" v-model="scope.row.attrType" />
+            <span v-else>{{ dataType(scope.row.attrType) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="长度" header-align="center" align="center" width="120">
+          <template #default="scope">
+            <el-input-number
+              v-if="scope.row.isEdit"
+              v-model="scope.row.attrLength" style="width:90px"
+              :min="0"
+              controls-position="right"
+              size="small"
+            />
+            <span v-else>{{ scope.row.attrLength }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="小数位数" header-align="center" align="center" width="120">
+          <template #default="scope">
+            <el-input-number
+              v-if="scope.row.isEdit"
+              v-model="scope.row.attrDecimals" style="width:90px"
+              :min="0"
+              controls-position="right"
+              size="small"
+            />
+            <span v-else>{{ scope.row.attrDecimals }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="是否为空" header-align="center" align="center" width="90">
+          <template #default="scope">
+            <el-checkbox
+              v-if="scope.row.isEdit"
+              v-model="scope.row.isNotNull"
+              :true-label="1"
+              :false-label="0"
+            >
+              {{ scope.row.isNotNull === 1 ? '是' : '否' }}
+            </el-checkbox>
+            <span v-else>{{ scope.row.isNotNull === 1 ? '是' : '否' }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="注释">
+          <template #default="scope">
+            <el-input v-if="scope.row.isEdit" v-model="scope.row.comment" size="small" />
+            <span v-else>{{ scope.row.comment }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column header-align="center" align="center" width="70">
+          <template #header>
+            排序
+          </template>
+          <template #default>
+            <el-tag type="info" class="sortable">
+              <el-icon>
+                <svg-icon name="i-ep:d-caret" />
+              </el-icon>
+            </el-tag>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="操作" width="140" align="center">
+          <template #default="scope">
+            <template v-if="scope.row.isEdit">
+              <el-button type="primary" plain size="small" @click="onAttrSave(scope.row)">
+                保存
+              </el-button>
+              <el-button type="primary" plain size="small" @click="onAttrCancel(scope.row, scope.$index)">
+                取消
+              </el-button>
+            </template>
+            <template v-else>
+              <el-button type="primary" plain size="small" @click="onAttrEdit(scope.row)">
+                编辑
+              </el-button>
+              <el-popconfirm title="是否要删除此行?" style="margin-left: 10px;" @confirm="onAttrDelete(scope.row)">
+                <template #reference>
+                  <el-button type="danger" plain size="small">
+                    删除
+                  </el-button>
+                </template>
+              </el-popconfirm>
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.page-main {
+  :deep(.el-table) {
+    height: 100%;
+
+    .el-table__row {
+      .index {
+        display: inline-block;
+      }
+
+      .delete {
+        display: none;
+      }
+
+      &:hover {
+        .index {
+          display: none;
+        }
+
+        .delete {
+          display: inline-block;
+        }
+      }
+    }
+  }
+  h4{
+    padding: 0;
+    margin: 0;
+  }
+}
+</style>