9eadeb70 by lihua

数据服务前端代码

1 parent 24ba6db6
# 页面标题
VITE_APP_TITLE = 数据资产管理系统
VITE_APP_TITLE = 可信数据空间
# 接口域名
# VITE_API_BASEURL = https://www.zgsjzc.com/api
# VITE_API_BASEURL = https://swzl-test.csbr.cn/api
VITE_API_BASEURL = http://192.168.6.20:28052/
# VITE_API_BASEURL = http://localhost:9000
VITE_API_BASEURL = http://192.168.9.1:58052/
# VITE_API_BASEURL = http://192.168.6.20:8052/
VITE_IDASS_BASEURL = https://daop-test.zgsjzc.com/portalLogin
......@@ -97,6 +98,9 @@ VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/
#数据加工交付
VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/
#数据服务接口地址
VITE_APP_SERVICE_BASEURL = ms-daop-jgjf-data-open-service
# 本地访问地址
# VITE_API_CIRCULATION_URL = http://localhost:9000/circulation
......
# 页面标题
VITE_APP_TITLE = 数据资产管理系统
VITE_APP_TITLE = 可信数据空间
# 接口域名
VITE_API_BASEURL = https://daop-zcgl-test.zgsjzc.com/
# VITE_API_BASEURL = http://49.4.26.201:31709/
......@@ -122,6 +122,9 @@ VITE_API_MESSAGE = ms-daop-message-service
#企业信息接口
VITE_APP_PERSONAL_URL = ms-daop-personel-service
#数据服务接口地址
VITE_APP_SERVICE_BASEURL = ms-daop-jgjf-data-open-service
#流通平台接口地址
VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/
#数据加工交付
......
......@@ -32,10 +32,10 @@ export const getSystemMenu = (params, isAdmin = false) => {
isAdmin
? `${
import.meta.env.VITE_APP_AUTH_URL
}/product-menu-permission/tenant/get-product-menu?tenantGuid=${params.tenantGuid}&platformSystemGuid=32774fcfdf5e43e8b866660374d8bced`
}/product-menu-permission/tenant/get-product-menu?tenantGuid=${params.tenantGuid}&platformSystemGuid=4149c763d70948b195eb3d4b997c1722`
: `${
import.meta.env.VITE_APP_AUTH_URL
}/product-menu-permission/staff/get-product-menu-template?platformSystemGuid=32774fcfdf5e43e8b866660374d8bced`,
}/product-menu-permission/staff/get-product-menu-template?platformSystemGuid=4149c763d70948b195eb3d4b997c1722`,
method: "get",
});
};
......@@ -247,6 +247,21 @@ export const getDataSource = (params) => request({
method: "post",
data: params,
});
/** 获取数据源列表 */
export const getSchemaTableList = (params) => request({
url:`${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/schema-table-page-list`,
method: 'post',
data: params
})
// 获取表结构
export const tableColumnList = (params)=> request({
url:`${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/table-column-list`,
method: 'post',
data: params
})
// 新增
export const addDataSource = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/save`,
......@@ -289,6 +304,12 @@ export const getAllFlowData = (params) => request({
method: 'get',
params
})
export const getParamsDictList = (dictType) => request({
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${dictType}`,
method: 'get',
})
// 获取资产/价值评估机构数据
export const getSingleList = (params) => request({
url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/singlePage`,
......@@ -317,3 +338,10 @@ export const getParamsList = (params) => request({
method: 'get',
params
})
// sql验证
export const checkSql = (params) => request({
url:`${import.meta.env.VITE_APP_DATA_SOURCE_URL }/sql-operate/check-sql`,
method: 'post',
data:params
})
......
......@@ -3,25 +3,6 @@ function Layout() {
return import('@/layouts/index.vue')
}
const routes: RouteRecordRaw[] = [
// {
// path: '/data-asset/register-guide',
// component: Layout,
// meta: {
// title: '登记服务指南',
// icon: 'sidebar-videos',
// },
// children: [{
// path: '',
// name: 'registerGuide',
// component: () => import('@/views/data_asset/registerGuide.vue'),
// meta: {
// title: '登记服务指南',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// }]
// },
{
path: '/data-asset/register-catalog',
component: Layout,
......
......@@ -253,47 +253,5 @@ const routes: RouteRecordRaw[] = [
},
],
},
{
path: '/data-asset-register/register-progress',
component: Layout,
meta: {
title: '登记进度一览',
icon: 'ep:grid',
},
children: [
{
path: '',
name: 'registerProgress',
component: () => import('@/views/data_asset/registerProgress.vue'),
meta: {
title: '登记进度一览',
sidebar: false,
cache: true,
breadcrumb: false,
},
},
]
},
{
path: '/data-asset-register/contract-progress',
component: Layout,
meta: {
title: '合同进度一览',
icon: 'ep:grid',
},
children: [
{
path: '',
name: 'contractProgress',
component: () => import('@/views/data_asset/contractProgress.vue'),
meta: {
title: '合同进度一览',
sidebar: false,
cache: true,
breadcrumb: false,
},
},
]
}
]
export default routes
......
import type { RouteRecordRaw } from 'vue-router'
function Layout() {
return import('@/layouts/index.vue')
}
const routes: RouteRecordRaw[] = [
{
path: '/data-service/api-management',
component: Layout,
meta: {
title: '管理API',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'apiManagement',
component: () => import('@/views/data_service/apiManagement.vue'),
meta: {
title: '管理API',
sidebar: false,
breadcrumb: false,
cache: true
}
},
{
path: 'api-create',
name: 'apiCreate',
component: () => import('@/views/data_service/apiCreate.vue'),
meta: {
title: '新建API',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
editPage: true
},
beforeEnter: (to, from) => {
if (to.query.type) {
to.meta.title = `新建(${to.query.type == '1' ? '单表API' : (to.query.type == '2' ? '自定义sql' : '注册API')})`;
to.meta.editPage = true;
} else if (to.query.detail) {
to.meta.title = `详情-${to.query.apiName}`;
to.meta.editPage = false;
} else if (to.query.guid) {
to.meta.title = `编辑-${to.query.apiName}`;
to.meta.editPage = true;
}
}
},
{
// path: 'processDetail',
// name: 'APIProcessDetail',
path: 'api-detail',
name: 'apiDetail',
component: () => import('@/views/data_service/detail_serviceApi.vue'),
meta: {
title: '流程详情',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
}
},
{
path: 'processDetail',
name: 'APIProcessDetail',
component: () => import('@/views/detail.vue'),
meta: {
title: '流程详情',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
}
},
],
},
{
path: '/data-service/api-test',
component: Layout,
meta: {
title: '测试API',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'apiTest',
component: () => import('@/views/data_service/apiTest.vue'),
meta: {
title: '测试API',
sidebar: false,
breadcrumb: false,
cache: true
},
},
],
},
]
export default routes
......@@ -3,6 +3,7 @@ import generatedRoutes from 'virtual:generated-pages'
import type { RouteRecordRaw } from 'vue-router'
import DataAssess from './modules/dataAsset';
import DataAssetRegistry from './modules/dataAssetRegistry';
import DataService from './modules/dataService';
import useSettingsStore from '@/store/modules/settings'
......@@ -90,7 +91,8 @@ const systemRoutes: RouteRecordRaw[] = [
// 动态路由(异步路由、导航栏路由)
const asyncRoutes: RouteRecordRaw[] = [
...DataAssess,
...DataAssetRegistry,
...DataService,
// ...DataAssetRegistry,
]
const constantRoutesByFilesystem = generatedRoutes.filter((item) => {
......
......@@ -40,7 +40,7 @@ const globalSettings: Settings.all = {
},
"home": {
"enable": false,
"title": "数据资产管理系统"
"title": "可信数据空间"
},
"breadcrumb": {
"enable": true
......
const useDataAnonymizationStore = defineStore(
// 资产目录guid
'isRefresh',
() => {
const isRefresh = ref<boolean>(false);
function setIsRefresh(v: boolean) {
isRefresh.value = v;
}
const isAnonPageRefresh = ref<boolean>(false);
function setIsAnonPageRefresh(v: boolean) {
isAnonPageRefresh.value = v;
}
return {
isRefresh,
isAnonPageRefresh,
setIsRefresh,
setIsAnonPageRefresh,
};
}
);
export default useDataAnonymizationStore;
const useDataCatalogStore = defineStore(
// 主题域guid
'domainGuid',
() => {
const domainGuid = ref<string>("")
function set(guid: any) {
domainGuid.value = guid;
}
return {
domainGuid,
set
}
},
)
export default useDataCatalogStore
\ No newline at end of file
const useEntryStore = defineStore(
// api标签分类guid
'isRefresh',
() => {
const isRefresh = ref(false);
function setIsRefresh(update: boolean) {
isRefresh.value = update;
}
return {
isRefresh,
setIsRefresh,
}
},
)
export default useEntryStore
\ No newline at end of file
const useDataMetaStore = defineStore("dataMeta", () => {
const guid: Ref<string> = ref("")
const databaseName = ref("")
const tableName = ref("")
const databaseChName = ref("");
const databaseGuid = ref('');
const fieldGuid = ref("");
const fieldEnName = ref('');
const isFieldLineage = ref(false);
const set = (prop?: {
tableGuid: string;
table: string;
databas: string;
databaseCh: string;
dsGuid: string;
fGuid?: string;
fEnName?: string;
isFieldLine?: boolean;
}) => {
guid.value = prop?.tableGuid || "";
databaseName.value = prop?.databas || "";
tableName.value = prop?.table || "";
databaseChName.value = prop?.databaseCh || "";
databaseGuid.value = prop?.dsGuid || "";
fieldGuid.value = prop?.fGuid || "";
fieldEnName.value = prop?.fEnName || "";
isFieldLineage.value = prop?.isFieldLine ?? false;
}
return {
guid,
databaseName,
tableName,
databaseChName,
databaseGuid,
fieldGuid,
fieldEnName,
isFieldLineage,
set
}
})
export default useDataMetaStore
\ No newline at end of file
const useDataQualityStore = defineStore(
// 质检表分组guid
'modelGroupGuid',
() => {
const modelGroupGuid = ref<string>("")
function set(guid: any) {
modelGroupGuid.value = guid;
}
const modelGuid = ref<string>("")
function setModelGuid(guid: any) {
modelGuid.value = guid;
}
const planType = ref<number>(0);
function setPlanType(type: any) {
planType.value = type;
}
const defaultPlanType = ref<number>(1);
function setDefaultPlanType(type: any) {
defaultPlanType.value = type;
}
const isUpdate = ref(false);
function setIsUpdate(update: boolean) {
isUpdate.value = update;
}
return {
modelGroupGuid,
set,
setModelGuid,
modelGuid,
planType,
isUpdate,
setIsUpdate,
setPlanType,
setDefaultPlanType,
defaultPlanType
}
},
)
export default useDataQualityStore
\ No newline at end of file
const useDataAsyncStore = defineStore("asyncGuid",()=>{
const taskGuid = ref("")
const set = (guid:string)=>{
taskGuid.value = guid
}
return {
taskGuid,
set
}
})
export default useDataAsyncStore
\ No newline at end of file
const useDataStandardsStore = defineStore(
// 主题域guid
'domainGuid',
() => {
const isAdd = ref(false)
const standardSetGuid = ref("")
const guid = ref("")
function set(guid: any) {
isAdd.value = guid;
}
function setGuid(sGuid,stanGuid){
guid.value = sGuid
standardSetGuid.value = stanGuid
}
return {
isAdd,
set,
guid,
setGuid,
standardSetGuid,
}
},
)
export default useDataStandardsStore
\ No newline at end of file
......@@ -46,4 +46,4 @@ export const commonPageConfig = {
}
/** 通用的系统guid */
export const SystemGuid = '32774fcfdf5e43e8b866660374d8bced';
\ No newline at end of file
export const SystemGuid = '4149c763d70948b195eb3d4b997c1722';
\ No newline at end of file
......
<route lang="yaml">
name: notFound
meta:
title: 数据资产管理
title: 可信数据空间
constant: true
layout: false
</route>
......
<route lang="yaml">
name: apiCalls
</route>
<script lang="ts" setup name="apiCalls">
import { ref } from 'vue';
import { TableColumnWidth } from '@/utils/enum';
import { commonPageConfig } from '@/components/PageNav/index';
import TableTools from '@/components/Tools/table_tools.vue';
import { useRouter, useRoute } from "vue-router";
import {
getAppProductData,
deleteAppProduct
} from "@/api/modules/dataService";
import useDataServiceStore from "@/store/modules/dataService";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const dataServiceStore = useDataServiceStore();
/** 分页及搜索传参信息配置。 */
const page = ref({
...commonPageConfig,
productName: ''
});
const searchItemList = ref([
{
type: "input",
label: "",
field: "productName",
default: "",
placeholder: "应用名称",
clearable: true,
}
]);
const tableInfo = ref({
id: 'data-app-table',
fields: [
{ label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
{ label: "应用名称", field: "productName", width: 140 },
{ label: "appKey", field: "appKey", width: 140 },
{ label: "appSecret", field: "appSecret", width: 120 },
{
label: "绑定API数", field: "apiBingingNum", width: 100, align: 'right', type: 'chnum'
},
{
label: "调用次数", field: "invokeNum", width: 100, align: 'right', type: 'chnum'
},
{
label: "调用异常数", field: "invokeErrorNum", width: 105, align: 'right', type: 'chnum'
},
{ label: "应用负责人", field: "directorName", width: TableColumnWidth.USERNAME },
{ label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 120,
fixed: 'right',
btns: (scope) => {
const row = scope.row
let btnsArr: any = [];
btnsArr.push({
label: "编辑", value: "edit", click: (scope) => {
router.push({
name: 'apiBind',
query: {
guid: scope.row.guid,
productName: scope.row.productName
}
});
}
});
btnsArr.push({
label: "删除", value: "delete", click: (scope) => {
if (scope.row.apiBingingNum > 0) {
proxy.$ElMessage.warning('该应用有绑定的API,无法删除');
return;
}
proxy.$openMessageBox('确定要删除该应用吗?', () => {
deleteAppProduct([scope.row.guid]).then((res: any) => {
if (res.code == proxy.$passCode) {
page.value.curr = 1;
getTableData();
proxy.$ElMessage.success("删除成功");
} else {
proxy.$ElMessage.error(res.msg);
}
});
}, () => {
proxy.$ElMessage.info("已取消");
})
}
});
return btnsArr
},
},
loading: false
})
const toSearch = (val: any, clear: boolean = false) => {
page.value.curr = 1;
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.productName = '';
} else {
page.value.productName = val.productName;
}
getTableData();
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData();
};
const getTableDataPromise: any = ref(null);
const getTableData = () => {
tableInfo.value.loading = true
getTableDataPromise.value = getAppProductData({
pageIndex: page.value.curr,
pageSize: page.value.limit,
productName: page.value.productName
}).then((res: any) => {
getTableDataPromise.value = null;
if (res.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
proxy.$ElMessage({
type: 'error',
message: res.msg,
})
}
tableInfo.value.loading = false
})
};
const addAppProduct = () => {
router.push({
name: 'apiBind',
});
}
onBeforeMount(() => {
toSearch({})
})
onActivated(() => {
if (dataServiceStore.isUpdate) {
if (getTableDataPromise.value) {
getTableDataPromise.value.then(() => {
getTableData();
dataServiceStore.setIsUpdate(false);
});
} else {
getTableData();
dataServiceStore.setIsUpdate(false);
}
}
});
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" :init="false" />
<div class="tools_btns">
<el-button type="primary" @click="addAppProduct" v-preReClick>添加</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
.tools_btns {
padding: 0px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 0px 8px 0;
}
</style>
\ No newline at end of file
<route lang="yaml">
name: ipWhitelist
</route>
<script lang="ts" setup name="ipWhitelist">
import { ref } from 'vue';
import { TableColumnWidth } from '@/utils/enum';
import TableTools from '@/components/Tools/table_tools.vue';
import { commonPageConfig } from '@/components/PageNav/index';
import { useRouter, useRoute } from "vue-router";
import {
getIPList,
deleteIP,
saveIP,
updateIP
} from "@/api/modules/dataService";
import { useValidator } from '@/hooks/useValidator';
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const { required, regexpValidate } = useValidator();
/** 分页及搜索传参信息配置。 */
const page = ref({
...commonPageConfig,
ip: ''
});
const searchItemList = ref([{
type: "input",
label: "",
field: "ip",
default: "",
placeholder: "IP",
clearable: true,
}]);
const currTableData: any = ref({});
const tableInfo = ref({
id: 'data-app-table',
fields: [
{ label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
{ label: "IP", field: "ip", width: 140 },
{ label: "描述", field: "description", width: TableColumnWidth.DESCRIPTION },
{ label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 120,
fixed: 'right',
btns: (scope) => {
let btnsArr: any = [];
btnsArr.push({
label: "编辑", value: "edit", click: (scope) => {
currTableData.value = scope.row;
IPDialogInfo.value.header.title = '编辑IP';
IPDialogInfo.value.type = 'edit';
IPFormItems.value[0].default = scope.row.ip;
IPFormItems.value[1].default = scope.row.description;
IPDialogInfo.value.visible = true;
}
});
btnsArr.push({
label: "删除", value: "delete", click: (scope) => {
proxy.$openMessageBox('确定要删除该IP吗?', () => {
deleteIP([scope.row.guid]).then((res: any) => {
if (res.code == proxy.$passCode) {
page.value.curr = 1;
getTableData();
proxy.$ElMessage.success("删除成功");
} else {
proxy.$ElMessage.error(res.msg);
}
});
}, () => {
proxy.$ElMessage.info("已取消");
})
}
});
return btnsArr
},
},
loading: false
})
const IPFormItems = ref([{
type: 'input',
label: 'IP',
field: 'ip',
default: '',
block: true,
placeholder: '请输入',
maxlength: 50,
clearable: true,
required: true
}, {
label: '描述',
type: 'textarea',
placeholder: '请输入',
field: 'description',
default: '',
maxlength: 200,
block: true,
clearable: true,
required: false
}]);
const IPFormRules = ref({
ip: [required("请填写IP"), regexpValidate(/^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/, '请输入合法的IP地址')],
});
const IPDialogInfo = ref({
visible: false,
size: 480,
direction: "column",
header: {
title: "添加IP",
},
type: 'add',
contents: [
{
type: 'form',
title: '',
formInfo: {
id: 'add-authorize-form',
items: IPFormItems.value,
rules: IPFormRules.value
}
}
],
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", value: "submit", loading: false },
],
},
});
const IPDialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
IPDialogInfo.value.footer.btns[1].loading = true;
if (IPDialogInfo.value.type == 'add') {
saveIP(info).then((res: any) => {
IPDialogInfo.value.footer.btns[1].loading = false;
if (res.code == proxy.$passCode) {
page.value.curr = 1;
getTableData();
proxy.$ElMessage({
type: 'success',
message: `添加IP成功`
})
IPDialogInfo.value.visible = false;
} else {
proxy.$ElMessage.error(res.msg);
}
})
} else {
info.guid = currTableData.value.guid;
updateIP(info).then((res: any) => {
IPDialogInfo.value.footer.btns[1].loading = false;
if (res.code == proxy.$passCode) {
page.value.curr = 1;
getTableData();
proxy.$ElMessage({
type: 'success',
message: `编辑IP成功`
})
IPDialogInfo.value.visible = false;
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
} else if (btn.value == 'cancel') {
IPDialogInfo.value.visible = false;
}
};
const toSearch = (val: any, clear: boolean = false) => {
page.value.curr = 1;
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.ip = '';
} else {
page.value.ip = val.ip;
}
getTableData();
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true
getIPList({
pageIndex: page.value.curr,
pageSize: page.value.limit,
ip: page.value.ip
}).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
proxy.$ElMessage({
type: 'error',
message: res.msg,
})
}
tableInfo.value.loading = false
})
};
const addIPWhite = () => {
IPDialogInfo.value.visible = true;
IPDialogInfo.value.header.title = '添加IP';
IPDialogInfo.value.type = 'add';
IPFormItems.value[0].default = '';
IPFormItems.value[1].default = ''
}
onBeforeMount(() => {
toSearch({})
})
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" :init="false" />
<div class="tools_btns">
<el-button type="primary" @click="addIPWhite" v-preReClick>添加</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
<!-- 添加编辑IP对话框 -->
<Dialog :dialogInfo="IPDialogInfo" @btnClick="IPDialogBtnClick" />
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
.tools_btns {
padding: 0px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 0px 8px 0;
}
</style>
\ No newline at end of file
......@@ -154,7 +154,7 @@ function testAccount(logonUser: string) {
<div>
<img :src="banner" class="banner">
<div class="banner_desc">
<h4>数据资产管理系统</h4>
<h4>可信数据空间</h4>
<span>激活数据流通体系,释放数据要素新质生产力</span>
</div>
</div>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!