c046732c by lihua

数据申请前端页面开发

1 parent bc5cc150
......@@ -676,7 +676,7 @@ const panelChange = (scope, row) => {
</div>
</template>
<template v-else-if="item.type === 'label'">
<div :class="[item.col, { is_block: item.block }]">
<div :class="[item.col, { is_block: item.block }]" @click.stop="item.click?.()">
<span>{{ item.default }}</span>
</div>
</template>
......@@ -1484,7 +1484,7 @@ const panelChange = (scope, row) => {
v-model="formInline[item.field]" type="daterange" range-separator="至" start-placeholder="开始日期" :format="item.format ?? null"
:value-format="item.valueFormat ?? null"
end-placeholder="结束日期" :unlink-panels="item.unlink ?? false" :shortcuts="item.shortcuts ?? []"
:default-value="item.defaultDate" :disabled="item.disabled ?? false" />
:default-value="item.defaultDate" :disabled="item.disabled ?? false" :disabled-date="item.disabledDate" />
<el-date-picker :class="[item.col, { is_block: item.block }]" v-else-if="item.type == 'date-year'"
v-model="formInline[item.field]" type="year" format="YYYY" value-format="YYYY"
:placeholder="item.placeholder" :unlink-panels="item.unlink ?? false" :shortcuts="item.shortcuts ?? []"
......
......@@ -355,7 +355,7 @@ const routes: RouteRecordRaw[] = [
},
]
},
{
{
path: '/data-product/product-catalog',
component: Layout,
meta: {
......@@ -387,6 +387,51 @@ const routes: RouteRecordRaw[] = [
}
},
]
},
{
path: '/data-product/data-application',
component: Layout,
meta: {
title: '数据申请',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'productApplicationManage',
component: () => import('@/views/data_asset/productApplicationManage.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'application-edit',
name: 'productApplicationEdit',
component: () => import('@/views/data_asset/productApplicationEdit.vue'),
meta: {
title: '数据申请-',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
}
},
{
path: 'application-detail',
name: 'productApplicationDetail',
component: () => import('@/views/data_asset/productApplicationDetail.vue'),
meta: {
title: '数据申请-',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
}
},
]
}
]
export default routes
......
const useDataProductApplicationStore = defineStore(
// 资产目录guid
'productApplication',
() => {
const isRefresh = ref<boolean>(false);
function setIsRefresh(v: boolean) {
isRefresh.value = v;
}
return {
isRefresh,
setIsRefresh,
};
}
);
export default useDataProductApplicationStore;
<template>
<div class="container_wrap full" v-loading="fullscreenLoading">
<div class="content_main">
<ContentWrap id="id-baseInfo" title="数据申请信息" description="" :isExpand="baseInfoExpand" :expand-swicth="true"
class="mb16" @expand="(v) => baseInfoExpand = v">
<div class="list_panel">
<div class="list_item">
<span class="item_label">产品名称:</span>
<span class="item_value link" @click="viewProductDetail">
<ellipsis-tooltip :content="detailInfo.damName || '--'" class-name="w100f mr8-i"
:refName="'tooltipOver' + 'damName'"></ellipsis-tooltip>
</span>
</div>
<div class="list_item">
<span class="item_label">产品编号:</span>
<span class="item_value">{{ detailInfo.productCode || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">资产类型:</span>
<span class="item_value">{{ detailInfo.damTypeName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">预计使用期限:</span>
<span class="item_value">{{ detailInfo.damTypeName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">数据范围:</span>
<span class="item_value">{{ detailInfo.damTypeName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">产品发布机构:</span>
<span class="item_value">{{ detailInfo.productPublisherName || '--' }}</span>
</div>
<div class="list_item is_block">
<span class="item_label">数据粒度说明:</span>
<span class="item_value">{{ detailInfo.description || '--' }}</span>
</div>
<div class="list_item is_block">
<span class="item_label">使用场景描述:</span>
<span class="item_value">{{ detailInfo.description || '--' }}</span>
</div>
</div>
</ContentWrap>
<ContentWrap id="id-approveInfo" title="流程审批" expandSwicth style="margin-top: 15px" :isExpand="expandApprove"
@expand="(v) => expandApprove = v">
<ApprovalProcess ref="approvalProcessRef" v-if="deploymentId" :deploymentId="deploymentId"
:processInstanceId="processInstanceId">
</ApprovalProcess>
</ContentWrap>
</div>
<div class="tool_btns">
<div class="btns">
<el-button v-for="btn in toolBtns" :type="btn.type" :plain="btn.plain" @click="btnClick(btn)">{{ btn.label
}}</el-button>
</div>
</div>
</div>
</template>
<script lang="ts" setup name="productApplicationEdit">
import useUserStore from "@/store/modules/user";
const { proxy } = getCurrentInstance() as any;
const userStore = useUserStore();
const route = useRoute();
const router = useRouter();
const fullPath = route.fullPath;
const fullscreenLoading = ref(false);
const baseInfoExpand = ref(true);
const expandApprove = ref(true);
const deploymentId = ref('');
const processInstanceId = ref('');
const detailInfo: any = ref({});
const viewProductDetail = () => {
// TODO
}
const toolBtns: any = computed(() => {
let btnsArr: any = [{
label: "关闭", value: "cancel", plain: true
}];
// TODO,资产运营平台TODO
return btnsArr;
});
const btnClick = (btn: any) => {
switch (btn.value) {
case 'cancel':
cancel();
break;
default:
break;
}
}
const cancel = () => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: 'productApplicationManage'
});
}
onBeforeMount(() => {
})
</script>
<style lang="scss" scoped>
.content_main {
height: calc(100% - 44px);
padding: 16px;
overflow: hidden auto;
position: sticky;
}
.list_panel {
display: flex;
flex-wrap: wrap;
display: flex;
align-items: center;
.list_item {
width: 33.33%;
line-height: 32px;
font-size: 14px;
color: var(--el-text-color-regular);
display: flex;
justify-content: space-between;
min-width: 120px;
.item_label {
text-align: left;
}
.item_value {
color: var(--el-color-regular);
padding: 0 4px;
flex: 1;
text-align: justify;
min-width: 0;
&.link {
color: var(--el-color-primary);
cursor: pointer;
}
}
&.is_block {
width: 100%;
.item_value {
white-space: pre-wrap;
}
}
}
}
.tool_btns {
display: flex;
justify-content: center;
align-items: center;
height: 44px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
}
</style>
\ No newline at end of file
<template>
<div class="container_wrap full" v-loading="fullscreenLoading">
<div class="content_main">
<ContentWrap id="id-baseInfo" title="数据申请信息" description="" :isExpand="baseInfoExpand" :expand-swicth="true"
class="mb16" @expand="(v) => baseInfoExpand = v">
<Form ref="baseInfoFormRef" :itemList="baseInfoFormItems" formId="base-info-form" :rules="baseInfoFormRules"
col="col3" />
</ContentWrap>
<ContentWrap id="id-approveInfo" title="流程审批" expandSwicth style="margin-top: 15px" :isExpand="expandApprove"
@expand="(v) => expandApprove = v">
<ApprovalProcess ref="approvalProcessRef" v-if="deploymentId" :deploymentId="deploymentId"
:processInstanceId="processInstanceId">
</ApprovalProcess>
</ContentWrap>
</div>
<div class="bottom_tool_wrap">
<el-button @click="cancel">取消</el-button>
<el-button @click="save" v-preReClick>保存</el-button>
<el-button type="primary" @click="submit" v-preReClick>提交审批</el-button>
</div>
</div>
</template>
<script lang="ts" setup name="productApplicationEdit">
import { getCamundaDeploymentId } from "@/api/modules/workFlowService";
import {
getRegisterCatalogDetail
} from "@/api/modules/dataAsset";
import useUserStore from "@/store/modules/user";
import useDataProductApplicationStore from "@/store/modules/productApplication";
import { useValidator } from '@/hooks/useValidator';
const { required } = useValidator();
const { proxy } = getCurrentInstance() as any;
const userStore = useUserStore();
const productApplicationStore = useDataProductApplicationStore();
const route = useRoute();
const router = useRouter();
const userData = JSON.parse(localStorage.userData);
const fullPath = route.fullPath;
const fullscreenLoading = ref(false);
const baseInfoExpand = ref(true);
const expandApprove = ref(true);
const deploymentId = ref('');
const processInstanceId = ref('');
const baseInfoFormRef = ref();
const baseInfoFormItems = ref([{
label: '产品名称',
type: 'label',
field: 'damName',
col: 'link',
default: '-',
click: () => {
//TODO
debugger
router.push({
name: 'productDetail',
query: {
id: route.query.id,
type: 'view'
}
})
}
},
{
label: '产品编码',
type: 'input',
placeholder: '请输入',
field: 'productCode',
default: '-',
disabled: true
},
{
label: '产品类型',
type: 'input',
placeholder: '请输入',
field: 'damTypeName',
default: '-',
disabled: true
},
{
label: "预计使用期限",
type: "date-picker",
field: "useDateRange",
default: null,
placeholder: "开始时间~结束时间",
clearable: true,
disabledDate: (date) => {
const today = new Date();
// 将 today 设置为 00:00:00,只比较日期部分(本地时间)
const todayStart = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate()
);
// 将 date 也转换为本地日期的开始时间(避免 UTC 问题)
const dateStart = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate()
);
// 禁用 dateStart < todayStart 的日期(即今天之前)
return dateStart.getTime() < todayStart.getTime();
},
required: true,
},
{
label: "数据范围",
type: "date-picker",
field: "useDataDateRange",
default: null,
placeholder: "开始时间~结束时间",
clearable: true,
required: true,
},
{
label: '产品发布机构',
type: 'input',
placeholder: '请输入',
field: 'productPublisherName',
default: '',
disabled: true
},
{
label: '数据粒度说明',
type: 'textarea',
placeholder: '请输入需要的需求字段',
field: 'dataDescription',
default: '',
block: true,
maxlength: 500,
clearable: true,
required: true,
},
{
label: '使用场景描述',
type: 'textarea',
placeholder: '请输入使用该数据产品的场景描述信息',
field: 'useDescription',
default: '',
block: true,
maxlength: 500,
clearable: true,
required: true,
},
])
const baseInfoFormRules = ref({
useDateRange: [{
type: 'array', required: true, message: '请选择预计使用期限', trigger: 'change',
}],
useDataDateRange: [{
type: 'array', required: true, message: '请选择数据范围', trigger: 'change',
}],
dataDescription: [required('请输入数据粒度说明')],
useDescription: [required('请输入使用场景描述')]
})
const cancel = () => {
proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: 'productApplicationManage'
});
}, () => {
proxy.$ElMessage.info("已取消");
});
}
const save = () => {
// 保存不检验。
}
const submit = () => {
baseInfoFormRef.value?.ruleFormRef?.validate().then((valid, errorItem) => {
if (valid) {
let formInline = baseInfoFormRef.value.formInline;
// fullscreenLoading.value = true;
// listingSavePortal(params).then((res: any) => {
// fullscreenLoading.value = false;
// if (res?.code == proxy.$passCode) {
// proxy.$ElMessage.success('提交审批成功');
// userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
// productApplicationStore.setIsRefresh(true);
// router.push({
// name: "productApplicationManage",
// });
// } else {
// res?.msg && proxy.$ElMessage.error(res.msg);
// }
// }).catch((res) => {
// fullscreenLoading.value = false;
// });
} else {
var obj = Object.keys(errorItem);
baseInfoFormRef.value.ruleFormRef.scrollToField(obj[0]);
}
})
}
onActivated(() => {
let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath == fullPath);
let detailType = route.query.type;
let name = route.query.name;
if (tab) {
switch (detailType) {
case 'edit':
tab.meta.title = `编辑-${name}`;
break;
case 'redit':
tab.meta.title = `编辑-${name}`;
break;
default:
tab.meta.title = '新增数据申请';
}
document.title = tab.meta.title;
};
})
onBeforeMount(() => {
// getCamundaDeploymentId('10016', userData.tenantGuid, userData.staffGuid).then((res: any) => {
// if (res.code == proxy.$passCode) {
// deploymentId.value = res.data;
// } else {
// proxy.$ElMessage.error(res.msg);
// }
// })
fullscreenLoading.value = true;
getRegisterCatalogDetail(route.query.guid).then((res: any) => {
fullscreenLoading.value = false;
if (res?.code == proxy.$passCode) {
let detail = res.data || {};
baseInfoFormItems.value[0].default = <string>route.query.damName;
baseInfoFormItems.value[1].default = detail.productCode;
baseInfoFormItems.value[2].default = detail.damTypeName;
} else {
res?.msg && proxy.$ElMessage.error(res.msg);
}
})
})
</script>
<style lang="scss" scoped>
.content_main {
height: calc(100% - 40px);
padding: 16px;
overflow: hidden auto;
position: sticky;
}
.bottom_tool_wrap {
height: 40px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
display: flex;
justify-content: center;
align-items: center;
}
:deep(.el-form) {
.link {
color: var(--el-color-primary);
cursor: pointer;
line-height: 32px;
}
}
</style>
\ No newline at end of file
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'data-application-search'" @search="toSearch" />
</div>
<div class="table_panel_wrap" :style="{ height: 'calc(100% - 48px)' }">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
</div>
</template>
<script lang="ts" setup name="productApplicationManage">
import { commonPageConfig } from "@/components/PageNav";
import TableTools from "@/components/Tools/table_tools.vue";
import useUserStore from "@/store/modules/user";
import { TableColumnWidth } from "@/utils/enum";
import { getDamTypesList } from "@/api/modules/dataAsset";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const userStore = useUserStore();
const userData = JSON.parse(userStore.userData);
const damTypes: any = ref([]);
const searchItemList: any = ref([
{
type: "input",
label: "",
field: "damName",
default: "",
placeholder: "产品名称",
clearable: true
},
{
type: "select",
label: "",
field: "damType",
default: "",
props: {
value: 'value',
label: 'label'
},
placeholder: "产品类型",
options: damTypes.value,
clearable: true,
},
{
type: 'select',
label: '',
field: 'approveState',
default: '',
placeholder: '审批状态',
options: [
{ label: '草稿中', value: 'N' },
{ label: '审批中', value: 'A' },
{ label: '已通过', value: 'Y' },
{ label: '已驳回', value: 'R' },
{ label: '已撤销', value: 'C' },
],
clearable: true
},
]);
const page = ref({
...commonPageConfig,
damName: '',
damType: null,
approveState: null,
});
const tableInfo = ref({
id: "mapping-table",
fields: [
{ label: "序号", type: "index", width: 56, align: "center", fixed: "left" },
{ label: "数据产品编号", field: "productCode", width: 265 },
{ label: "数据产品名称", field: "damName", width: 180 },
{
label: "产品类型", field: "damTypeName", width: 100
},
{
label: "审批状态", field: "approveState", type: "tag", width: TableColumnWidth.STATE, align: 'center'
},
{ label: "申请方", field: "tenantName", width: 240 },
{ label: "数据提供方", field: "dataProviderName", width: 240 },
{ label: "提交时间", field: "submitTime", width: 170 },
],
loading: false,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 170,
btns: (scope) => {
const { row } = scope;
const bizApproveState = row.approveState;
let flowState;
if (bizApproveState == 'N') {
flowState = 1;
}
const currentStaffGuid = userData.userGuid
const staffGuid = row.createUserId || '';
let isShowCancel = false;
let list: any = [];
if (bizApproveState == 'N') {
flowState = 1;
}
if ((bizApproveState == 'D' || bizApproveState == 'C' || bizApproveState == 'R' || bizApproveState == 'E' || bizApproveState == 'R') && staffGuid == currentStaffGuid) {
flowState = 3;
}
if (bizApproveState == 'A' && staffGuid == currentStaffGuid) {
isShowCancel = true;
}
if (flowState === 1) {
list = [{ label: "编辑", value: "edit", click: btnHandlers.edit }, { label: "删除", value: "del", click: btnHandlers.del }]
}
if (flowState === 3) {
list.push({ label: "删除", value: "del", click: btnHandlers.del })
}
if (flowState === 3) { //重新提交过的不能再重新提交 && bizApproveState != 'D'
list.push({ label: "重新提交", value: "redit", click: btnHandlers.redit }) //已驳回
}
if (flowState !== 1) {
list.push({ label: "详情", value: "detail", click: btnHandlers.detail })
}
return list
},
}
});
const btnHandlers = {
edit: (scope) => {
router.push({
// name: "data-product-edit",
// query: {
// id: scope.row.id,
// },
});
},
redit: (scope) => {
},
detail: (scope) => {
router.push({
// name: "data-product-detail",
// query: {
// id: scope.row.id,
// },
})
},
del: (scope) => {
proxy.$openMessageBox('数据申请删除后不可恢复,确定继续删除吗?', () => {
// delCertificate([row.guid]).then((res: any) => {
// if (res?.code == proxy.$passCode) {
// proxy.$ElMessage.success('删除资产登记证件成功');
// page.value.curr = 1;
// getTableData();
// } else {
// proxy.$ElMessage.error(res.msg);
// }
// })
}, () => {
proxy.$ElMessage.info("已取消删除");
});
},
}
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map(item => item.default = "");
page.value.damName = '';
page.value.approveState = null;
page.value.damType = null;
} else {
page.value.damName = val.damName;
page.value.approveState = val.approveState;
page.value.damType = val.damType;
}
page.value.curr = 1;
tableInfo.value.page.curr = 1;
getTableData();
};
const getTableData = () => {
// tableInfo.value.loading = true;
// getListingList({
// pageIndex: page.value.curr,
// pageSize: page.value.limit,
// damName: page.value.damName,
// damType: page.value.damType,
// approveState: page.value.approveState
// }).then((res: any) => {
// tableInfo.value.loading = false;
// tableInfo.value.data = res.data.records || [];
// tableInfo.value.page.curr = res.data.pageIndex;
// tableInfo.value.page.limit = res.data.pageSize;
// tableInfo.value.page.rows = res.data.totalRows;
// }).catch((res) => {
// tableInfo.value.loading = false;
// });
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.limit = page.value.limit;
tableInfo.value.page.curr = page.value.curr;
getTableData();
};
onBeforeMount(() => {
getDamTypesList({
dictType: "资产类型",
}).then((res: any) => {
if (res.code == proxy.$passCode) {
damTypes.value = res.data || [];
searchItemList.value[1].options = damTypes.value;
} else {
proxy.$ElMessage.error(res.msg);
}
})
})
</script>
<style lang="scss" scoped>
.container_wrap {
width: 100%;
height: 100%;
overflow-y: auto;
.table_tool_wrap {
width: 100%;
padding: 0 8px;
.tools_btns {
padding: 0px 0 8px;
}
}
.table_panel_wrap {
width: 100%;
padding: 0px 8px 0;
}
}
</style>
\ No newline at end of file
<template>
<div class="container_wrap full flex">
<!-- 侧边栏容器,放置产品分类树 -->
<div class="aside_wrap">
<div class="aside_title">产品分类</div>
<Tree ref="treeRef" :treeInfo="treeInfo" @nodeCheck="handleTreeNodeChange" />
</div>
<!-- 主内容区域,包含搜索框和表格 -->
<div class="main_wrap">
<div class="header-bg">
<el-input v-model.trim="page.searchKey" size="large" placeholder="请输入关键字搜索" :prefix-icon="Search"
......@@ -26,7 +28,12 @@ import { USERROLE } from '@/utils/enum';
const router = useRouter();
const route = useRoute();
const { proxy } = getCurrentInstance() as any;
const dataSourceList = ref([{ //如果是授权数据则不能选择其余的
/**
* 数据源选项列表
* 包含四种不同类型的数据来源
*/
const dataSourceList = ref([{
value: 1,
label: '授权数据',
}, {
......@@ -42,164 +49,248 @@ const dataSourceList = ref([{ //如果是授权数据则不能选择其余的
label: '其他来源',
}]);
/** 是否是数据使用方 */
/**
* 判断当前用户角色是否为数据使用方
* 如果是使用方,则显示特定的操作按钮
*/
const isDataUse = computed(() => {
return localStorage.getItem('userRole') == USERROLE.USE;
})
const treeRef = ref();
const treeRef = ref(); // Tree组件引用,用于访问树组件实例
/**
* 树形控件配置信息
* 包含树的基本配置、数据结构定义等
*/
const treeInfo = ref({
id: "data-product-tree",
filter: true,
queryValue: "",
queryPlaceholder: "请输入关键字搜索",
showCheckbox: true,
checkStrictly: false,
id: "data-product-tree", // 树的唯一标识
filter: true, // 是否启用过滤功能
queryValue: "", // 过滤输入框的值
queryPlaceholder: "请输入关键字搜索", // 过滤输入框提示文字
showCheckbox: true, // 显示复选框
checkStrictly: false, // 不严格遵循父子节点不互相关联
props: {
label: "label",
value: "value",
children: 'childDictList'
label: "label", // 节点标签字段
value: "value", // 节点值字段
children: 'childDictList' // 子节点数据字段
},
nodeKey: 'value',
expandOnNodeClick: false,
data: <any>[],
loading: false
nodeKey: 'value', // 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
expandOnNodeClick: false, // 点击节点时不展开或收缩节点
data: <any>[], // 树形数据
loading: false // 加载状态
});
//记录每次点击的节点。
/**
* 处理树节点选择变化事件
* 处理半选和全选节点的逻辑
* @param checkedObj - 选中的对象信息
* @param id - 节点ID
* @param nodeObj - 节点对象
*/
const handleTreeNodeChange = (checkedObj, id, nodeObj) => {
debugger
let treeRefs = treeRef.value.treeRef;
let checkedKeys = checkedObj.checkedObj || [];//全勾选的所有节点。
let halfCheckedKeys = checkedObj.halfCheckedKeys || [];//半勾选的节点。
//思路,一个个的分类判断是否在半勾选,如果是,就将其勾选的子节点获取出来。
/** 先damType */
let checkedKeys = checkedObj.checkedObj || []; // 全勾选的所有节点
let halfCheckedKeys = checkedObj.halfCheckedKeys || []; // 半勾选的节点
// 思路:一个个的分类判断是否在半勾选,如果是,就将其勾选的子节点获取出来
/** 产品类型 */
if (halfCheckedKeys.includes('damType')) {
// 获取出来勾选的子节点。
treeRefs.getNode("damType").childNodes?.filter(c=> c.checked == true);
} //如果是全选,则不需要处理传参。
// 获取勾选的子节点
treeRefs.getNode("damType").childNodes?.filter(c => c.checked == true);
}
// 如果是全选,则不需要处理传参
/** 数据来源 */
if (halfCheckedKeys.includes('dataSources')) {
}
/** 行业分类 */
/** 机构分类 */
/** 复杂的领域及应用场景。 */
/** 领域及应用场景 */
if (halfCheckedKeys.includes('domain')) {
//计算领域下勾选的子节点。同时判断医疗健康和工业制造。
// 计算领域下勾选的子节点,同时判断医疗健康和工业制造
}
}
/**
* 页面配置信息
* 包含分页、搜索等公共配置
*/
const page = ref({
...commonPageConfig,
searchKey: '',
...commonPageConfig, // 继承通用页面配置
searchKey: '', // 搜索关键词
});
const oldKeyWord = ref(""); //记录上次输入的关键字,若是输入值未变化,则失去焦点时不用触发搜索。
const isEnter = ref(false);
const oldKeyWord = ref(""); // 记录上次输入的关键字,避免重复搜索
const isEnter = ref(false); // 标识是否通过回车键触发搜索
/** 触发搜索查询 */
/**
* 触发搜索查询
* @param clear - 是否清空页码,默认为true
* @param isBlur - 是否是失焦触发,默认为false
*/
const toSearch = (clear: boolean = true, isBlur: boolean = false) => {
if (clear) {
page.value.curr = 1
page.value.curr = 1 // 重置为第一页
}
// 如果是失焦且不是回车触发,且关键词没有变化,则不执行搜索
if (isBlur && !isEnter.value && oldKeyWord.value === page.value.searchKey) {
return;
}
isEnter.value = false;
oldKeyWord.value = page.value.searchKey;
isEnter.value = false; // 重置回车状态
oldKeyWord.value = page.value.searchKey; // 更新关键词记录
getSearchData(clear);
}
/**
* 回车搜索事件处理
* 在输入框按下回车键时触发
* @param event - 键盘事件对象
*/
const searchEnterFun = (event) => {
isEnter.value = true;
event.target?.blur();
isEnter.value = true; // 标记为回车触发
event.target?.blur(); // 输入框失去焦点
}
/** 查询表格数据 */
/**
* 查询表格数据
* 根据筛选条件获取表格数据
* @param clear - 是否清除现有数据
*/
const getSearchData = (clear = false) => {
// TODO: 实现具体的数据获取逻辑
}
/**
* 表格配置信息
* 定义表格列、数据、分页、操作按钮等
*/
const tableInfo = ref({
id: 'contract-table',
rowKey: 'guid',
loading: false,
fields: [{ label: "序号", type: "index", width: 56, align: "center" },
{
label: "数据产品名称", field: "dataProductName", width: 160, type: "text_btn", columClass: 'text_btn', value: "detail", disabled: (scope) => {
return scope.row.contractStatus == '06';
}, click: (scope) => {
if (scope.row.contractStatus == '06') {
return;
}
router.push({
name: 'productSortCatalogDetail',
query: {
guid: scope.row.dataProductGuid,
type: 'detail',
foundMode: 'use',
name: scope.row.dataProductName,
id: 'contract-table', // 表格唯一标识
rowKey: 'guid', // 行数据的唯一标识
loading: false, // 加载状态
// 表格列定义
fields: [
{
label: "序号",
type: "index",
width: 56,
align: "center"
},
{
label: "数据产品名称",
field: "dataProductName",
width: 160,
type: "text_btn",
columClass: 'text_btn',
value: "detail",
// 合同状态为06时禁用点击
disabled: (scope) => {
return scope.row.contractStatus == '06';
},
// 点击查看详细信息
click: (scope) => {
if (scope.row.contractStatus == '06') {
return;
}
});
}
},
{ label: "产品类型", field: "damTypeName", width: 100 },
{ label: "应用场景", field: "scenarioName", width: 120 },
{ label: "行业分类", field: "industryName", width: 140 },
{ label: "机构分类", field: "institutionTypeName", width: 120 },
{
label: "数据来源", field: "dataSources", width: 100, getName: (scope) => {
return scope.row.dataSources && dataSourceList.value.find(i => i.value == scope.row.dataSources)?.label || '--'
}
},
{ label: "上架时间", field: "listingTime", width: 170 },
router.push({
name: 'productSortCatalogDetail',
query: {
guid: scope.row.dataProductGuid, // 产品GUID
type: 'detail', // 查看类型
foundMode: 'use', // 发现模式
name: scope.row.dataProductName, // 产品名称
}
});
}
},
{ label: "产品类型", field: "damTypeName", width: 100 },
{ label: "应用场景", field: "scenarioName", width: 120 },
{ label: "行业分类", field: "industryName", width: 140 },
{ label: "机构分类", field: "institutionTypeName", width: 120 },
{
label: "数据来源",
field: "dataSources",
width: 100,
// 获取数据源名称
getName: (scope) => {
return scope.row.dataSources && dataSourceList.value.find(i => i.value == scope.row.dataSources)?.label || '--'
}
},
{ label: "上架时间", field: "listingTime", width: 170 },
],
data: [{}],
data: [{}], // 表格数据
// 分页配置
page: {
type: "normal",
rows: 0,
...page.value,
type: "normal", // 分页类型
rows: 0, // 总行数
...page.value, // 继承页面配置
},
// 操作按钮配置
actionInfo: {
label: "操作",
type: "btn",
show: isDataUse.value,
show: isDataUse.value, // 仅对数据使用方显示
width: 120,
// 操作按钮定义
btns: (scope) => {
return [{
value: 'approve', label: "数据申请", click: (scope) => { //TODO,是否申请过的不能再申请?
value: 'approve',
label: "数据申请",
// 点击申请数据
click: (scope) => {
// TODO,是否申请过的不能再申请?
router.push({
name: 'productApplicationEdit',
query: {
damGuid: scope.row.guid, // 数据资产GUID
damName: scope.row.dataProductName // 数据产品名称
}
});
}
}]
}
}
});
/**
* 表格分页变化事件处理
* 当分页信息改变时更新页面配置并重新加载数据
* @param info - 分页信息对象
*/
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.curr = page.value.curr;
page.value.curr = Number(info.curr); // 更新当前页
page.value.limit = Number(info.limit); // 更新每页条数
tableInfo.value.page.curr = page.value.curr; // 同步到表格分页
tableInfo.value.page.limit = page.value.limit;
getSearchData();
getSearchData(); // 重新获取数据
};
const damTypes: any = ref([]);
/** 所属主题多级列表 */
const subjectDomainListData: any = ref([]);
/** 行业分类类型列表 */
const industryDictList: any = ref([]);
/** 领域字典列表 */
const domainDictList: any = ref([]);
/** 机构类型字典列表 */
const institutionTypeDictList: any = ref([]);
/** 所属科室下拉列表 */
const medDepartmentCodeList: any = ref([]);
// 数据字典变量定义
const damTypes: any = ref([]); // 产品类型字典列表
const subjectDomainListData: any = ref([]); // 主题域列表
const industryDictList: any = ref([]); // 行业分类字典列表
const domainDictList: any = ref([]); // 领域字典列表
const institutionTypeDictList: any = ref([]); // 机构类型字典列表
const medDepartmentCodeList: any = ref([]); // 科室代码列表
/**
* 组件挂载前生命周期钩子
* 初始化树形控件所需的各种字典数据
*/
onBeforeMount(() => {
treeInfo.value.loading = true;
treeInfo.value.loading = true; // 开启加载状态
// 并发请求所有字典数据
let psAll: any[] = [];
// 获取产品类型字典
psAll.push(getDamTypesList({
dictType: "资产类型",
}).then((res: any) => {
......@@ -209,6 +300,8 @@ onBeforeMount(() => {
proxy.$ElMessage.error(res.msg);
}
}))
// 获取行业分类字典(一级)
psAll.push(getDamTypesList({
dictType: "行业分类",
level: 1
......@@ -219,6 +312,8 @@ onBeforeMount(() => {
proxy.$ElMessage.error(res.msg);
}
}))
// 获取领域字典
psAll.push(getDamTypesList({ dictType: '领域' }).then((res: any) => {
if (res.code == proxy.$passCode) {
domainDictList.value = res.data || [];
......@@ -226,6 +321,8 @@ onBeforeMount(() => {
proxy.$ElMessage.error(res.msg);
}
}));
// 获取机构类型字典
psAll.push(getDamTypesList({
dictType: "组织机构性质",
}).then((res: any) => {
......@@ -235,6 +332,8 @@ onBeforeMount(() => {
proxy.$ElMessage.error(res.msg);
}
}))
// 获取主题域字典
psAll.push(getDamTypesList({
dictType: "数据资产目录主题名称",
}).then((res: any) => {
......@@ -245,6 +344,7 @@ onBeforeMount(() => {
}
}))
// 获取科室字典
psAll.push(getDamTypesList({
dictType: "科室",
}).then((res: any) => {
......@@ -255,63 +355,79 @@ onBeforeMount(() => {
}
}));
// 等待所有请求完成,然后构建树形数据
Promise.all(psAll).then(() => {
treeInfo.value.loading = false;
treeInfo.value.data = [];
treeInfo.value.loading = false; // 关闭加载状态
treeInfo.value.data = []; // 清空原有数据
// 构建树形结构数据
treeInfo.value.data.push({
value: 'damType',
label: '产品类型',
childDictList: damTypes.value
});
let item = domainDictList.value.find(i => i.value == '003');//医疗健康,下级应用场景和所属科室
// 特殊处理医疗健康领域(003)
let item = domainDictList.value.find(i => i.value == '003'); // 医疗健康,下级应用场景和所属科室
let childDictList = item.childDictList || [];
item.childDictList = [{
value: 'scenario',
label: '应用场景',
childDictList: childDictList
}];
// 添加所属科室节点
item.childDictList.push({
value: 'medDepartmentCode',
label: '所属科室',
childDictList: medDepartmentCodeList.value
});
let item4 = domainDictList.value.find(i => i.value == '004'); //工业制造
// 特殊处理工业制造领域(004)
let item4 = domainDictList.value.find(i => i.value == '004'); // 工业制造
let childDictList4 = item4.childDictList || [];
item4.childDictList = [{
value: 'scenario',
label: '应用场景',
childDictList: childDictList4
}];
// 添加所属主题节点
item4.childDictList.push({
value: 'subjectDomain',
label: '所属主题',
childDictList: subjectDomainListData.value
});
// 添加领域及应用场景节点
treeInfo.value.data.push({
value: 'domain',
label: '领域及应用场景',
childDictList: domainDictList.value //TODO,需要带上主题和科室。
childDictList: domainDictList.value // TODO,需要带上主题和科室
});
// 添加数据来源节点
treeInfo.value.data.push({
value: 'dataSource',
label: '数据来源',
childDictList: dataSourceList.value
});
// 添加行业分类节点
treeInfo.value.data.push({
value: 'industry',
label: '行业分类',
childDictList: industryDictList.value
});
// 添加机构分类节点
treeInfo.value.data.push({
value: 'institutionType',
label: '机构分类',
childDictList: institutionTypeDictList.value
});
}).catch(() => {
treeInfo.value.loading = false;
treeInfo.value.loading = false; // 出错时关闭加载状态
})
})
</script>
<style lang="scss" scoped>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!