houyaf преди 3 години
родител
ревизия
ffb1fbf066

+ 7 - 7
src/api/api/apiApi.ts

@@ -7,7 +7,7 @@ import apiRequest from '@/network/http/apiRequest'
  */
 export function getApiByPage(data: any) {
   return apiRequest({
-    url: '/paas/api/page',
+    url: '/api/page',
     method: 'GET',
     params: data,
   })
@@ -20,7 +20,7 @@ export function getApiByPage(data: any) {
  */
 export function getApiByList(data: any) {
   return apiRequest({
-    url: '/paas/api',
+    url: '/api',
     method: 'GET',
     params: data,
   })
@@ -33,7 +33,7 @@ export function getApiByList(data: any) {
  */
 export function getApiById(moduleId: number, apiId: number) {
   return apiRequest({
-    url: `/paas/api/${moduleId}/${apiId}`,
+    url: `/api/${moduleId}/${apiId}`,
     method: 'GET',
   })
 }
@@ -45,7 +45,7 @@ export function getApiById(moduleId: number, apiId: number) {
  */
 export function createApi(data: any) {
   return apiRequest({
-    url: '/paas/api/add',
+    url: '/api/add',
     method: 'POST',
     data,
   })
@@ -58,7 +58,7 @@ export function createApi(data: any) {
  */
 export function updateApi(data: any) {
   return apiRequest({
-    url: '/paas/api/update',
+    url: '/api/update',
     method: 'PUT',
     data,
   })
@@ -72,7 +72,7 @@ export function updateApi(data: any) {
  */
 export function updateApiStatus(moduleId: number, apiId: number, status: number) {
   return apiRequest({
-    url: `/paas/api/updateStatus/${moduleId}/${apiId}/${status}`,
+    url: `/api/updateStatus/${moduleId}/${apiId}/${status}`,
     method: 'PUT',
   })
 }
@@ -84,7 +84,7 @@ export function updateApiStatus(moduleId: number, apiId: number, status: number)
  */
 export function deleteApiById(moduleId: number, apiId: number) {
   return apiRequest({
-    url: `/paas/api/${moduleId}/${apiId}`,
+    url: `/api/${moduleId}/${apiId}`,
     method: 'DELETE',
   })
 }

+ 3 - 3
src/api/api/apiLogApi.ts

@@ -7,7 +7,7 @@ import apiRequest from '@/network/http/apiRequest'
  */
 export function getApiReqByPage(data: any) {
   return apiRequest({
-    url: '/paas/api/request/page',
+    url: '/api/log/page',
     method: 'GET',
     params: data,
   })
@@ -20,7 +20,7 @@ export function getApiReqByPage(data: any) {
  */
 export function getApiReqByList(data: any) {
   return apiRequest({
-    url: '/paas/api/request',
+    url: '/api/log',
     method: 'GET',
     params: data,
   })
@@ -33,7 +33,7 @@ export function getApiReqByList(data: any) {
  */
 export function getApiReqById(reqId: number) {
   return apiRequest({
-    url: `/paas/api/request/${reqId}`,
+    url: `/api/log/${reqId}`,
     method: 'GET',
   })
 }

+ 5 - 5
src/api/api/apiModuleApi.ts

@@ -7,7 +7,7 @@ import apiRequest from '@/network/http/apiRequest'
  */
 export function getModuleByList(data: any) {
   return apiRequest({
-    url: '/paas/module',
+    url: '/api/module',
     method: 'GET',
     params: data,
   })
@@ -20,7 +20,7 @@ export function getModuleByList(data: any) {
  */
 export function getModuleById(moduleId: number) {
   return apiRequest({
-    url: `/paas/module/${moduleId}`,
+    url: `/api/module/${moduleId}`,
     method: 'GET',
   })
 }
@@ -32,7 +32,7 @@ export function getModuleById(moduleId: number) {
  */
 export function createModule(data: any) {
   return apiRequest({
-    url: '/paas/module/add',
+    url: '/api/module/add',
     method: 'POST',
     data,
   })
@@ -45,7 +45,7 @@ export function createModule(data: any) {
  */
 export function updateModule(data: any) {
   return apiRequest({
-    url: '/paas/module/update',
+    url: '/api/module/update',
     method: 'PUT',
     data,
   })
@@ -58,7 +58,7 @@ export function updateModule(data: any) {
  */
 export function deleteModuleById(moduleId: number) {
   return apiRequest({
-    url: `/paas/module/${moduleId}`,
+    url: `/api/module/${moduleId}`,
     method: 'DELETE',
   })
 }

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

@@ -0,0 +1,396 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup name="bizObjectEdit">
+import Sortable from 'sortablejs'
+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()
+
+interface ObjectAttr {
+  attrId: number
+  attrTitle: string
+  attrCode: string
+  attrType: number
+  attrLength: number
+  attrDecimals: number
+  isNotNull: number
+  comment: string
+  sortNo: number
+}
+
+const dataType = [
+  { dataType: 1, dataName: '整数' },
+  { dataType: 2, dataName: '字符串' },
+  { dataType: 3, dataName: '小数' }]
+
+// 数据
+const state = reactive({
+  title: '',
+  dialogVisible: false,
+  loading: false,
+  search: {
+    keywords: '',
+  },
+  formData: {
+    bizId,
+    objectId,
+    objectType: 1,
+    objectCode: '',
+    objectTitle: '',
+    comment: '',
+    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 { 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, // 是否为空
+    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(() => {
+  if (objectId <= 0) {
+    state.title = '新增对象'
+    state.actionType = 1
+  }
+  else {
+    state.title = '编辑对象'
+    state.actionType = 2
+    getData()
+  }
+
+  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('新增成功')
+      }
+      else {
+        await updateObject(state.formData)
+        state.dialogVisible = false
+        ElMessage.success('修改成功')
+      }
+      goBack()
+    }
+  })
+}
+
+function onCancel() {
+  goBack()
+}
+
+// 返回列表页
+function goBack() {
+  if (settingsStore.settings.tabbar.enable && settingsStore.settings.tabbar.mergeTabsBy !== 'activeMenu') {
+    tabbar.close({ name: 'model' })
+  }
+  else {
+    router.push({ name: 'model' })
+  }
+}
+</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>
+        </template>
+
+        <div class="container">
+          <tool-bar>
+            <template #left>
+              <h2>属性</h2>
+            </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="primary" @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.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-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="注释">
+              <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>
+    </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%;
+
+    .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;
+      }
+    }
+  }
+  h2{
+    padding: 0;
+    margin: 0;
+  }
+}
+</style>

+ 2 - 2
src/views/biz/object/components/Biz.vue

@@ -71,13 +71,13 @@ function resetFormData() {
 defineExpose({
   showAddModel() {
     resetFormData()
-    state.title = '新增模型'
+    state.title = '新增业务'
     state.actionType = 1
     state.dialogVisible = true
   },
   showEditModel(bizId: any) {
     resetFormData()
-    state.title = '编辑模型'
+    state.title = '编辑业务'
     state.actionType = 2
     state.dialogVisible = true
     getData(bizId)

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

@@ -88,13 +88,13 @@ onMounted(() => {
 
 // 对象新增
 const onBizAdd = () => {
-  bizRef.value.showAddBiz()
+  bizRef.value.showAddModel()
 }
 
 // 对象编辑
 const onBizEdit = (data: { bizId: number }) => {
   const bizId = data.bizId
-  bizRef.value.showEditBiz(bizId)
+  bizRef.value.showEditModel(bizId)
 }
 
 // 模型删除
@@ -118,7 +118,7 @@ const onTreeNodeClick = (node: TreeNode) => {
 }
 
 const objectTableRef = ref()
-const objectRef = ref()
+const bizObjectRef = ref()
 
 // 检索对象
 const onSearch = () => {
@@ -309,8 +309,8 @@ const onObjectDelete = (row: any) => {
         </div>
       </LayoutContainer>
     </div>
-    <Biz ref="modelRef" @success="getBizData" />
-    <BizObject ref="objectRef" @success="getObjectData" />
+    <Biz ref="bizRef" @success="getBizData" />
+    <BizObject ref="bizObjectRef" @success="getObjectData" />
   </div>
 </template>
 

+ 76 - 0
src/views/biz/rule/index.vue

@@ -0,0 +1,76 @@
+<script lang="ts" setup name="DbTypeIndex">
+import { getBizRuleByList } from '@/api/biz/bizRuleApi'
+
+const state = reactive({
+  loading: false,
+  // 表格是否自适应高度
+  tableAutoHeight: false,
+  // 搜索
+  search: {
+    keywords: '',
+  },
+  // 列表数据
+  dataList: [],
+})
+
+const bizRuleRef = ref()
+
+const getDataList = async () => {
+  state.loading = true
+  const { data } = await getBizRuleByList({})
+  state.dataList = data
+  state.loading = false
+}
+
+onMounted(() => {
+  getDataList()
+})
+</script>
+
+<template>
+  <div :class="{ 'absolute-container': state.tableAutoHeight }">
+    <page-header title="业务规则">
+      <template #content>
+        <div>
+          系统支持多种业务规则
+        </div>
+      </template>
+    </page-header>
+
+    <page-main>
+      <el-table v-loading="state.loading" class="list-table" :data="state.dataList" border stripe highlight-current-row height="100%">
+        <el-table-column type="index" label="序号" width="60" header-align="center" align="center" />
+
+        <el-table-column prop="ruleTitle" label="名称" header-align="center" align="center" width="200" />
+
+        <el-table-column prop="ruleDesc" label="说明" />
+      </el-table>
+    </page-main>
+  </div>
+</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;
+
+    .search-container {
+      margin-bottom: 0;
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/model/attr/index.vue

@@ -3,7 +3,7 @@ meta:
   enabled: false
 </route>
 
-<script lang="ts" setup name="daasObjectEdit">
+<script lang="ts" setup name="modelObjectEdit">
 import Sortable from 'sortablejs'
 import type { FormInstance, FormRules } from 'element-plus'
 import { ElMessage } from 'element-plus'