|
|
@@ -3,21 +3,27 @@ meta:
|
|
|
enabled: false
|
|
|
</route>
|
|
|
|
|
|
-<script lang="ts" setup name="bizObjectEdit">
|
|
|
-import Sortable from 'sortablejs'
|
|
|
+<script lang="ts" setup name="BizObjectAttrList">
|
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
-import { createObject, getObjectById, updateObject } from '@/api/biz/bizObjectApi'
|
|
|
-import useSettingsStore from '@/store/modules/settings'
|
|
|
-
|
|
|
-const settingsStore = useSettingsStore()
|
|
|
-const route = useRoute()
|
|
|
-const bizId = parseInt(route.params.bizId.toString())
|
|
|
-const objectId = parseInt(route.params.objectId.toString())
|
|
|
-const router = useRouter()
|
|
|
-const tabbar = useTabbar()
|
|
|
+import { dataType } from '@/utils/tool'
|
|
|
+import {
|
|
|
+ createObjectAttr,
|
|
|
+ deleteObjectAttrById,
|
|
|
+ getObjectAttrListById,
|
|
|
+ updateObjectAttr,
|
|
|
+} from '@/api/biz/bizObjectAttrApi'
|
|
|
+const props = withDefaults(defineProps<{
|
|
|
+ bizId: number
|
|
|
+ objectId: number
|
|
|
+}>(), {
|
|
|
+ bizId: 0,
|
|
|
+ objectId: 0,
|
|
|
+})
|
|
|
|
|
|
interface ObjectAttr {
|
|
|
+ bizId: number
|
|
|
+ objectId: number
|
|
|
attrId: number
|
|
|
attrTitle: string
|
|
|
attrCode: string
|
|
|
@@ -28,16 +34,9 @@ interface ObjectAttr {
|
|
|
isNotNull: number
|
|
|
comment: string
|
|
|
sortNo: number
|
|
|
+ isEdit: boolean
|
|
|
}
|
|
|
|
|
|
-const dataType = [
|
|
|
- { dataType: 1, dataName: '整数' },
|
|
|
- { dataType: 2, dataName: '字符串' },
|
|
|
- { dataType: 3, dataName: '浮点小数' },
|
|
|
- { dataType: 4, dataName: '日期' },
|
|
|
- { dataType: 5, dataName: '日期时间' },
|
|
|
-]
|
|
|
-
|
|
|
// 数据
|
|
|
const state = reactive({
|
|
|
title: '',
|
|
|
@@ -46,15 +45,11 @@ const state = reactive({
|
|
|
search: {
|
|
|
keywords: '',
|
|
|
},
|
|
|
- formData: {
|
|
|
- bizId,
|
|
|
- objectId,
|
|
|
- objectType: 1,
|
|
|
- objectCode: '',
|
|
|
- objectTitle: '',
|
|
|
- comment: '',
|
|
|
- attrs: [] as ObjectAttr[],
|
|
|
+ conditions: {
|
|
|
+ bizId: props.bizId,
|
|
|
+ objectId: props.objectId,
|
|
|
},
|
|
|
+ attrs: [] as ObjectAttr[],
|
|
|
actionType: 1,
|
|
|
})
|
|
|
|
|
|
@@ -77,15 +72,22 @@ const formRules = reactive<FormRules>({
|
|
|
// 查询数据
|
|
|
const getData = async () => {
|
|
|
state.loading = true
|
|
|
- const { data } = await getObjectById(bizId, objectId)
|
|
|
+ const { bizId, objectId } = state.conditions
|
|
|
+ const { data } = await getObjectAttrListById(bizId, objectId)
|
|
|
state.loading = false
|
|
|
- state.formData = data
|
|
|
+ state.attrs = data
|
|
|
+ data.forEach((attr: ObjectAttr) => {
|
|
|
+ attr.isEdit = false
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
const attrsTableRef = ref()
|
|
|
const attrsTableKey = ref(0)
|
|
|
+
|
|
|
function onAttrAdd() {
|
|
|
- state.formData.attrs.push({
|
|
|
+ state.attrs.push({
|
|
|
+ bizId: props.bizId,
|
|
|
+ objectId: props.objectId,
|
|
|
attrId: 0,
|
|
|
attrTitle: '', // 名称
|
|
|
attrCode: '', // 代码
|
|
|
@@ -96,48 +98,48 @@ function onAttrAdd() {
|
|
|
isNotNull: 0, // 是否为空
|
|
|
comment: '', // 注释
|
|
|
sortNo: 0,
|
|
|
+ isEdit: true,
|
|
|
})
|
|
|
- nextTick(() => {
|
|
|
- attrsTableRef.value.setScrollTop(state.formData.attrs.length * 50)
|
|
|
- })
|
|
|
+ state.actionType = 1
|
|
|
}
|
|
|
|
|
|
-// 删除属性
|
|
|
-function onAttrDelete(index: number) {
|
|
|
- state.formData.attrs.splice(index, 1)
|
|
|
+function onAttrEdit(row: any) {
|
|
|
+ row.isEdit = true
|
|
|
+ state.actionType = 2
|
|
|
}
|
|
|
|
|
|
-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())
|
|
|
- },
|
|
|
- })
|
|
|
+async function onAttrDelete(row: any) {
|
|
|
+ const { bizId, objectId } = state.conditions
|
|
|
+ const attrId = row.attrId
|
|
|
+ await deleteObjectAttrById(bizId, objectId, attrId)
|
|
|
+ ElMessage.success('删除成功')
|
|
|
}
|
|
|
|
|
|
-onMounted(() => {
|
|
|
- if (objectId <= 0) {
|
|
|
- state.title = '新增对象'
|
|
|
- state.actionType = 1
|
|
|
+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 {
|
|
|
- state.title = '编辑对象'
|
|
|
- state.actionType = 2
|
|
|
- getData()
|
|
|
+ await updateObjectAttr(row)
|
|
|
+ state.dialogVisible = false
|
|
|
+ ElMessage.success('修改成功')
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+onMounted(() => {
|
|
|
+ getData()
|
|
|
nextTick(() => {
|
|
|
- onAttrDrag()
|
|
|
})
|
|
|
})
|
|
|
|
|
|
@@ -145,240 +147,170 @@ onMounted(() => {
|
|
|
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)
|
|
|
+ await createObjectAttr(state.attrs)
|
|
|
state.dialogVisible = false
|
|
|
ElMessage.success('新增成功')
|
|
|
}
|
|
|
else {
|
|
|
- await updateObject(state.formData)
|
|
|
+ await updateObjectAttr(state.attrs)
|
|
|
state.dialogVisible = false
|
|
|
ElMessage.success('修改成功')
|
|
|
}
|
|
|
- goBack()
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
-function onCancel() {
|
|
|
- goBack()
|
|
|
-}
|
|
|
-
|
|
|
-// 返回列表页
|
|
|
-function goBack() {
|
|
|
- if (settingsStore.settings.tabbar.enable && settingsStore.settings.tabbar.mergeTabsBy !== 'activeMenu') {
|
|
|
- tabbar.close({ name: 'biz_object_index' })
|
|
|
- }
|
|
|
- else {
|
|
|
- router.push({ name: 'biz_object_index' })
|
|
|
- }
|
|
|
-}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div class="absolute-container">
|
|
|
- <page-header title="对象" content="创建元数据对象。">
|
|
|
- <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 hide-left-side-toggle>
|
|
|
- <template #leftSide>
|
|
|
- <h2>基本信息</h2>
|
|
|
- <el-scrollbar class="form-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="objectType">
|
|
|
- <el-radio-group v-model="state.formData.objectType">
|
|
|
- <el-radio :label="1">
|
|
|
- 实体对象
|
|
|
- </el-radio>
|
|
|
- <el-radio :label="2">
|
|
|
- 视图对象
|
|
|
- </el-radio>
|
|
|
- </el-radio-group>
|
|
|
- </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>
|
|
|
+ <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>
|
|
|
|
|
|
- <div class="container">
|
|
|
- <tool-bar>
|
|
|
- <template #left>
|
|
|
- <h2>属性</h2>
|
|
|
+ <el-button type="default" @click="onAttrAdd">
|
|
|
+ <template #icon>
|
|
|
+ <el-icon>
|
|
|
+ <svg-icon name="i-ep:plus" />
|
|
|
+ </el-icon>
|
|
|
</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>
|
|
|
+ </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" @click="onAttrAdd">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:plus" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
+ <el-button type="primary" plain size="small" @click="onAttrCancel(scope.row, scope.$index)">
|
|
|
+ 取消
|
|
|
</el-button>
|
|
|
</template>
|
|
|
- </tool-bar>
|
|
|
-
|
|
|
- <el-table ref="attrsTableRef" :key="attrsTableKey" :data="state.formData.attrs" class="list-table" 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-input v-model="scope.row.mappingCode" />
|
|
|
- </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="130">
|
|
|
- <template #default="scope">
|
|
|
- <el-input-number
|
|
|
- v-model="scope.row.attrLength" style="width:100px"
|
|
|
- :min="0"
|
|
|
- controls-position="right"
|
|
|
- size="large"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="长度" width="130">
|
|
|
- <template #default="scope">
|
|
|
- <el-input-number
|
|
|
- v-model="scope.row.attrDecimals" style="width:100px"
|
|
|
- :min="0"
|
|
|
- controls-position="right"
|
|
|
- size="large"
|
|
|
- />
|
|
|
- </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="注释">
|
|
|
- <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>
|
|
|
- </div>
|
|
|
- </LayoutContainer>
|
|
|
+ <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>
|
|
|
-
|
|
|
- <fixed-action-bar>
|
|
|
- <el-button type="primary" size="large" @click="onSubmit">
|
|
|
- 保存
|
|
|
- </el-button>
|
|
|
- <el-button size="large" @click="onCancel">
|
|
|
- 取消
|
|
|
- </el-button>
|
|
|
- </fixed-action-bar>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.page-header {
|
|
|
- margin-bottom: 0;
|
|
|
-}
|
|
|
-
|
|
|
.page-main {
|
|
|
- :deep(.left-side) {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- height: 100%;
|
|
|
- .form-el-scrollbar{
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
- }
|
|
|
:deep(.el-table) {
|
|
|
height: 100%;
|
|
|
|
|
|
@@ -407,7 +339,7 @@ function goBack() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- h2{
|
|
|
+ h4{
|
|
|
padding: 0;
|
|
|
margin: 0;
|
|
|
}
|