From 4e81ae830621569f71e7b7d27180d15ed2894ded Mon Sep 17 00:00:00 2001 From: "si@aidatagov.com" Date: Sun, 27 Jul 2025 03:58:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/datastd_controller.py | 21 ++ .../module_admin/dao/datastd_dao.py | 42 ++++ .../module_admin/service/datastd_service.py | 49 ++++ vue-fastapi-frontend/src/api/datastd/std.js | 14 +- .../src/views/datastd/main/index.vue | 27 ++ .../src/views/datastd/main/stdMap.vue | 236 ++++++++++++++++++ .../src/views/datastd/stdcode/treeNodeg6.vue | 130 +++------- 7 files changed, 428 insertions(+), 91 deletions(-) create mode 100644 vue-fastapi-frontend/src/views/datastd/main/stdMap.vue diff --git a/vue-fastapi-backend/module_admin/controller/datastd_controller.py b/vue-fastapi-backend/module_admin/controller/datastd_controller.py index d690b50..7e833f9 100644 --- a/vue-fastapi-backend/module_admin/controller/datastd_controller.py +++ b/vue-fastapi-backend/module_admin/controller/datastd_controller.py @@ -50,6 +50,16 @@ async def get_std_code_map_list( ): code_page_query_result = await DataStdService.get_std_code_map_list_services(query_db, code_page_query, is_page=True) return ResponseUtil.success(model_content=code_page_query_result) +@datastdController.get( + '/stdcode/code/maplist2', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:list'))] +) +async def get_std_code_map_list2( + request: Request, + code_page_query: DataStdCodePageQueryModel = Depends(DataStdCodePageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), +): + code_page_query_result = await DataStdService.get_std_main_map_list_services(query_db, code_page_query, is_page=True) + return ResponseUtil.success(model_content=code_page_query_result) @datastdController.get('/stdcode/code/listappr', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stddict:dict:list'))] ) async def get_std_code_appr_list( @@ -679,4 +689,15 @@ async def get_code_map_list( ): code_page_query_result = await DataStdService.get_code_map_list(query_db, id) logger.info('获取列配置列表成功') + return ResponseUtil.success(data=code_page_query_result) +@datastdController.get( + '/stdcode/code/mapstdlist2/{id}', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:list'))] +) +async def get_code_map_list2( + request: Request, + id: str, + query_db: AsyncSession = Depends(get_db), +): + code_page_query_result = await DataStdService.get_code_map_list2(query_db, id) + logger.info('获取列配置列表成功') return ResponseUtil.success(data=code_page_query_result) \ No newline at end of file diff --git a/vue-fastapi-backend/module_admin/dao/datastd_dao.py b/vue-fastapi-backend/module_admin/dao/datastd_dao.py index 8bc2f2d..bcd5c70 100644 --- a/vue-fastapi-backend/module_admin/dao/datastd_dao.py +++ b/vue-fastapi-backend/module_admin/dao/datastd_dao.py @@ -187,6 +187,37 @@ class DataStdDao: ) return col_list @classmethod + async def get_std_main_map_list(cls, db: AsyncSession, query_object: DataStdDictModel, is_page: bool = False): + # 构建查询条件 + filters = [] + # 系统级代码 + c1 = aliased(DataStdMain) # + c2 = aliased(DataStdDict) # + + filters.append(c1.onum == query_object.onum) + + # 3. 构建基础查询,使用连接和别名 + query = ( + select( + c1.data_std_no.label("data_std_no"), # 标准编号 + c1.data_std_eng_name.label("data_std_eng_name"), # 标准英文名称 + c1.data_std_cn_name.label("data_std_cn_name"), # 标准中文名 + c2.data_dict_no.label("data_dict_no"), # 字典编号 + c2.data_dict_eng_name.label("data_dict_eng_name"), # 字典英文名称 + c2.data_dict_cn_name.label("data_dict_cn_name"), # 字典中文名 + ) + .select_from(c1) # 从 c1 开始查询 + .join(c2, c1.data_std_no == c2.data_std_no, isouter=True) # 连接 c2 + + .where(*filters) # 使用所有过滤条件 + .order_by(desc(c1.create_time)) # 按照创建时间降序排列 + ) + # 4. 分页逻辑 + col_list = await PageUtil.paginate( + db, query, query_object.page_num, query_object.page_size, is_page + ) + return col_list + @classmethod async def get_data_code_list_by_info(cls, db: AsyncSession, query_object: DataStdCodeModel): List = ( await db.execute( @@ -376,6 +407,17 @@ class DataStdDao: query = select(DataStdDict).where(*filters).order_by(desc(DataStdDict.create_time)) return await PageUtil.paginate(db, query, 0, 0, False) @classmethod + async def get_data_dict_list_by_info(cls, db: AsyncSession, query_object: DataStdDictModel): + List = ( + await db.execute( + select(DataStdDict) + .where( + DataStdDict.data_std_no == query_object.data_std_no if query_object.data_std_no else True + ) + ) + ).scalars().all() + return List + @classmethod async def update_std_dict(cls, db: AsyncSession, update_data: DataStdDictModel): await db.execute(update(DataStdDict), [update_data]) diff --git a/vue-fastapi-backend/module_admin/service/datastd_service.py b/vue-fastapi-backend/module_admin/service/datastd_service.py index 9064355..f205eba 100644 --- a/vue-fastapi-backend/module_admin/service/datastd_service.py +++ b/vue-fastapi-backend/module_admin/service/datastd_service.py @@ -98,6 +98,20 @@ class DataStdService: col_list_result = await DataStdDao.get_std_code_map_list(query_db, query_object, is_page) return col_list_result @classmethod + async def get_std_main_map_list_services( + cls, query_db: AsyncSession, query_object: DataStdMainModel, is_page: bool = False + ): + """ + 获取列配置列表信息service + + :param query_db: orm对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 列配置列表信息对象 + """ + col_list_result = await DataStdDao.get_std_main_map_list(query_db, query_object, is_page) + return col_list_result + @classmethod async def get_std_code_by_id_services(cls, query_db: AsyncSession, id: str): """ 获取列配置详细信息service @@ -1509,6 +1523,41 @@ class DataStdService: } + children.append(node) + + return { + "tableData": table_data, + "children": children + } + @classmethod + async def get_code_map_list2(cls, query_db: AsyncSession, id: str): + check_model = DataStdDictModel() + dataStdNo=await DataStdDao.get_std_main_by_id(query_db, id) + cd_type=dataStdNo.src_sys + check_model.data_std_no=dataStdNo.onum + main_list = await DataStdDao.get_data_dict_list_by_info(query_db, check_model) + + if not main_list: + return { "children": []} # 如果 A 表没有数据,返回空结构 + + table_data = [] # 存储表格数据 + children = [] # 存储图谱数据 + + for main in main_list: + # 组织图谱数据(A 表作为父节点) + node = { + "id": f"node_{main.onum}", # 使用 get() 方法访问字段 + "name": main.data_dict_cn_name, # 使用 get() 方法访问字段 + "label": main.data_dict_eng_name, # 使用 get() 方法访问字段 + "rate": 1.0, + "status": "B", + # "currency": main.get('dataStdNo'), # 使用 get() 方法访问字段 + "variableValue": "数据字典", + "variableUp": True, + "children": [], + } + + children.append(node) return { diff --git a/vue-fastapi-frontend/src/api/datastd/std.js b/vue-fastapi-frontend/src/api/datastd/std.js index 8e41dfd..4d97df4 100644 --- a/vue-fastapi-frontend/src/api/datastd/std.js +++ b/vue-fastapi-frontend/src/api/datastd/std.js @@ -30,6 +30,13 @@ export function listStdCodemap(query) { params: query }) } +export function listStdCodemap2(query) { + return request({ + url: '/default-api/datastd/stdcode/code/maplist2', + method: 'get', + params: query + }) +} // 查询标准代码项列表 export function listStdCodeItem(query) { return request({ @@ -66,7 +73,12 @@ export function getStdCodeMap(rowId) { method: 'get' }) } - +export function getStdMap(rowId) { + return request({ + url: '/default-api/datastd/stdcode/code/mapstdlist2/' + parseStrEmpty(rowId), + method: 'get' + }) +} // 新增标准代码 export function addStdCode(data) { return request({ diff --git a/vue-fastapi-frontend/src/views/datastd/main/index.vue b/vue-fastapi-frontend/src/views/datastd/main/index.vue index d6b160f..0091604 100644 --- a/vue-fastapi-frontend/src/views/datastd/main/index.vue +++ b/vue-fastapi-frontend/src/views/datastd/main/index.vue @@ -287,6 +287,19 @@ + + + + + + + + @@ -402,6 +420,8 @@ import MoveDialog from './components/MoveDialog.vue' import MergerDialog from './components/MergerDialog.vue' import AssetMoveDialog from './components/AssetMoveDialog.vue' import AddEditForm from "./components/AddEditForm.vue"; +import stdMap from './stdMap'; // 引入第二个页面组件 + import { listStdMain, getStdMain, @@ -427,6 +447,8 @@ const currentNode = ref({}) const handleTargetCatalogNodeClick = (data) => { chooseOnumNum.value=data.contentOnum } +const codeMapId = ref(null); +const mapVisible = ref(false); const directoryTableData = ref([]) const queryParams = ref({ @@ -463,6 +485,11 @@ const handleCodeClick = (row) => { codeId.value=row.cdId codeVisible.value = true; +}; +const handleMapCodeClick = (row) => { + codeMapId.value=row.onum + mapVisible.value = true; + }; const resetQuery = () => { queryParams.value = { dataStdNo: '', dataStdBusiDefn: '' , pageNum: 1, diff --git a/vue-fastapi-frontend/src/views/datastd/main/stdMap.vue b/vue-fastapi-frontend/src/views/datastd/main/stdMap.vue new file mode 100644 index 0000000..ebba4b8 --- /dev/null +++ b/vue-fastapi-frontend/src/views/datastd/main/stdMap.vue @@ -0,0 +1,236 @@ + + + + + + + diff --git a/vue-fastapi-frontend/src/views/datastd/stdcode/treeNodeg6.vue b/vue-fastapi-frontend/src/views/datastd/stdcode/treeNodeg6.vue index 0600756..435c75c 100644 --- a/vue-fastapi-frontend/src/views/datastd/stdcode/treeNodeg6.vue +++ b/vue-fastapi-frontend/src/views/datastd/stdcode/treeNodeg6.vue @@ -19,64 +19,6 @@ insertCss(` border-radius = 4px; } `); - -// mocked data -// const mockData = { -// id: 'g1', -// name: '发型机构类型代码', -// count: 123456, -// label: 'SYS049', -// // currency: '代码', -// rate: 1.0, -// status: 'G', -// // variableName: 'V1', -// variableValue:'代码', -// variableUp: true, -// children: [ -// { -// id: 'g12', -// name: '发行机构类型', -// count: 123456, -// label: 'iss_ins_type', -// rate: 1.0, -// status: 'R', -// currency: 'xx001', -// // variableName: 'V2', -// variableValue:'标准', -// variableUp: true, -// children: [ -// { -// id: 'g121', -// name: '发行机构类型', -// collapsed: true, -// count: 123456, -// label: 'iss_ins_type', -// rate: 1.0, -// status: 'B', -// currency: 'xx002', -// variableValue:'词典', -// variableUp: true, - -// }, - -// ], -// }, -// { -// id: 'g13', -// name: '发行人编号', -// label: 'issr_no', -// rate: 1, -// status: 'R', -// currency: 'xx002', -// // variableName: '标准', -// variableValue:'标准', -// variableUp: true, - -// } - -// ], -// }; - const colors = { B: '#5B8FF9', R: '#F46649', @@ -109,7 +51,6 @@ const propsConfig = { modes: { default: ['zoom-canvas', 'drag-canvas'] }, }, }; -console.log(props.mockData,"mockDatamockDatamockData") // 自定义节点和边的注册函数 const registerFn = () => { /** 自定义节点 **/ @@ -178,17 +119,22 @@ console.log(props.mockData,"mockDatamockDatamockData") }); // price - const price = group.addShape('text', { - attrs: { - ...textConfig, - x: 12 + nodeOrigin.x, - y: rectBBox.maxY - 12, - text: label, - fontSize: 16, - fill: '#000', - opacity: 0.85, - }, - }); +// 节点中的 label 显示在这里 +const price = group.addShape('text', { + attrs: { + ...textConfig, + x: 12 + nodeOrigin.x, + y: rectBBox.maxY - 12, + text: label && label.length > 10 ? label.slice(0, 10) + '...' : label, + fontSize: 16, + fill: '#000', + opacity: 0.85, + cursor: 'pointer', // 可选:增强可悬浮感知 + }, + name: 'label-shape', // ✅ 加上这一行! +}); + + // label currency group.addShape('text', { @@ -439,26 +385,30 @@ console.log(props.mockData,"mockDatamockDatamockData") offsetX: 20, offsetY: 30, itemTypes: ['node'], - getContent: (e) => { - const outDiv = document.createElement('div'); - const nodeName = e.item.getModel().name; - let formatedNodeName = ''; - for (let i = 0; i < nodeName.length; i++) { - formatedNodeName = `${formatedNodeName}${nodeName[i]}`; - if (i !== 0 && i % 20 === 0) - formatedNodeName = `${formatedNodeName}
`; - } - outDiv.innerHTML = `${formatedNodeName}`; - return outDiv; - }, - shouldBegin: (e) => { - if ( - e.target.get('name') === 'name-shape' || - e.target.get('name') === 'mask-label-shape' - ) - return true; - return false; - }, +getContent: (e) => { + const model = e.item.getModel(); + const shapeName = e.target.get('name'); + + let tooltipText = ''; + + if (shapeName === 'name-shape') { + tooltipText = `${model.name || ''}`; + } else if (shapeName === 'label-shape') { + tooltipText = `${model.label || ''}`; + } else { + tooltipText = `${model.name || ''}`; + } + + const outDiv = document.createElement('div'); + outDiv.style.width = 'auto'; + outDiv.innerHTML = tooltipText; + return outDiv; +}, + shouldBegin: (e) => { + // 仅在悬浮在 name 或 label 字段时触发 tooltip + const name = e.target.get('name'); + return name === 'name-shape' || name === 'mask-label-shape' || name === 'label-shape'; + }, }); graph = new G6.TreeGraph({ container: container.value,