|
@@ -2,13 +2,13 @@
|
|
|
* @Author: code4eat awesomedema@gmail.com
|
|
* @Author: code4eat awesomedema@gmail.com
|
|
|
* @Date: 2022-07-12 11:14:21
|
|
* @Date: 2022-07-12 11:14:21
|
|
|
* @LastEditors: code4eat awesomedema@gmail.com
|
|
* @LastEditors: code4eat awesomedema@gmail.com
|
|
|
- * @LastEditTime: 2025-04-25 17:40:50
|
|
|
|
|
|
|
+ * @LastEditTime: 2025-08-26 09:38:13
|
|
|
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/indicatorMana/index.tsx
|
|
* @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/indicatorMana/index.tsx
|
|
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
import { ActionType, ProColumns } from '@ant-design/pro-table';
|
|
import { ActionType, ProColumns } from '@ant-design/pro-table';
|
|
|
-import React, { useEffect, useRef, useState } from 'react';
|
|
|
|
|
|
|
+import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
|
import { Dropdown, Empty, Input, Popconfirm, Tabs, Modal, Form, message } from 'antd';
|
|
import { Dropdown, Empty, Input, Popconfirm, Tabs, Modal, Form, message } from 'antd';
|
|
|
import { ModalForm, ProFormInstance, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
|
|
import { ModalForm, ProFormInstance, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
|
|
|
|
|
|
|
@@ -16,6 +16,7 @@ import DrawerForm from './DrawerForm/drawer';
|
|
|
import { createFromIconfontCN, DownOutlined } from '@ant-design/icons';
|
|
import { createFromIconfontCN, DownOutlined } from '@ant-design/icons';
|
|
|
import {
|
|
import {
|
|
|
addIndicatorManaList,
|
|
addIndicatorManaList,
|
|
|
|
|
+ applyStatisticalAnalysisMap,
|
|
|
applyOnlineReportMap,
|
|
applyOnlineReportMap,
|
|
|
delIndicatorManaList,
|
|
delIndicatorManaList,
|
|
|
editIndicatorManaList,
|
|
editIndicatorManaList,
|
|
@@ -28,13 +29,14 @@ import {
|
|
|
|
|
|
|
|
import './style.less';
|
|
import './style.less';
|
|
|
import { getIndicatorDictionary, IndicatorDictionaryDataType } from '@/service/dictionary';
|
|
import { getIndicatorDictionary, IndicatorDictionaryDataType } from '@/service/dictionary';
|
|
|
-import { useHistory, useLocation, useModel, useParams } from 'umi';
|
|
|
|
|
|
|
+import { useLocation, useModel } from 'umi';
|
|
|
import { KCIMLeftList } from '../../components/KCIMLeftList';
|
|
import { KCIMLeftList } from '../../components/KCIMLeftList';
|
|
|
import KCTable from '@/components/kcTable';
|
|
import KCTable from '@/components/kcTable';
|
|
|
import { KCInput } from '@/components/KCInput';
|
|
import { KCInput } from '@/components/KCInput';
|
|
|
import generateTableData from '../dataFilling/fillingMana/generateTableData';
|
|
import generateTableData from '../dataFilling/fillingMana/generateTableData';
|
|
|
import { DATAFILL_PERIODTYPE } from '../dataFilling/fillingMana';
|
|
import { DATAFILL_PERIODTYPE } from '../dataFilling/fillingMana';
|
|
|
import FrameComponent from './frameContainer';
|
|
import FrameComponent from './frameContainer';
|
|
|
|
|
+import { TableRequestParamsType } from '@/typings';
|
|
|
|
|
|
|
|
const defaultYear = new Date().getFullYear();
|
|
const defaultYear = new Date().getFullYear();
|
|
|
let table_columns: any[] = [];
|
|
let table_columns: any[] = [];
|
|
@@ -61,10 +63,8 @@ const IndicatorMana = () => {
|
|
|
});
|
|
});
|
|
|
const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
|
|
const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');
|
|
|
const [currentSelectedLeft, set_currentSelectedLeft] = useState<any>(undefined);
|
|
const [currentSelectedLeft, set_currentSelectedLeft] = useState<any>(undefined);
|
|
|
- const [actionType, set_actionType] = useState<'NORMAL' | 'DETAIL' | undefined>('NORMAL');
|
|
|
|
|
- const [drawerActype, set_drawerActype] = useState<'ADD' | 'EDIT' | 'DATAMANA' | undefined>(
|
|
|
|
|
- undefined
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ const [actionType, set_actionType] = useState<'NORMAL' | 'DETAIL' | 'ANALYZE' | undefined>('NORMAL');
|
|
|
|
|
+ const [drawerActype, set_drawerActype] = useState<'ADD' | 'EDIT' | 'DATAMANA' | undefined>(undefined);
|
|
|
const [tableDataSource, set_tableDataSource] = useState<any[]>([]);
|
|
const [tableDataSource, set_tableDataSource] = useState<any[]>([]);
|
|
|
const [currentYear, set_currentYear] = useState(defaultYear);
|
|
const [currentYear, set_currentYear] = useState(defaultYear);
|
|
|
const [currentEditRow, set_currentEditRow] = useState<any>(undefined);
|
|
const [currentEditRow, set_currentEditRow] = useState<any>(undefined);
|
|
@@ -72,14 +72,138 @@ const IndicatorMana = () => {
|
|
|
|
|
|
|
|
const [currentBigTab, set_currentBigTab] = useState('2');
|
|
const [currentBigTab, set_currentBigTab] = useState('2');
|
|
|
const indicatorTableRef = useRef<ActionType>();
|
|
const indicatorTableRef = useRef<ActionType>();
|
|
|
- const history: any = useHistory();
|
|
|
|
|
const [currentTab, set_currentTab] = useState('1');
|
|
const [currentTab, set_currentTab] = useState('1');
|
|
|
- const {
|
|
|
|
|
- indicatorType: indicatorUrlType,
|
|
|
|
|
- }: { id: string; indicatorType: string } = history.location.query;
|
|
|
|
|
|
|
|
|
|
const [reportModalVisible, setReportModalVisible] = useState(false);
|
|
const [reportModalVisible, setReportModalVisible] = useState(false);
|
|
|
const reportForm = useRef<ProFormInstance>();
|
|
const reportForm = useRef<ProFormInstance>();
|
|
|
|
|
+ // 报表刷新键,每次保存后自增以强制 iframe 重新加载
|
|
|
|
|
+ const [reportReloadKey, set_reportReloadKey] = useState(0);
|
|
|
|
|
+
|
|
|
|
|
+ // 根据当前路径在菜单树中查找对应菜单节点,解析功能码列表,用于按钮级权限控制
|
|
|
|
|
+ const location = useLocation();
|
|
|
|
|
+ const { initialState } = useModel('@@initialState');
|
|
|
|
|
+ const getMenuNodeByPath = (tree: any[] = [], targetPath: string): any | undefined => {
|
|
|
|
|
+ // 1) 标准化:去查询参数、去尾部斜杠
|
|
|
|
|
+ const normalize = (p?: string) => {
|
|
|
|
|
+ if (!p) return '';
|
|
|
|
|
+ const pure = p.split('?')[0];
|
|
|
|
|
+ return pure !== '/' ? pure.replace(/\/+$/, '') : pure;
|
|
|
|
|
+ };
|
|
|
|
|
+ const normalizedTargetPath = normalize(targetPath);
|
|
|
|
|
+
|
|
|
|
|
+ // 2) 解析当前页面查询参数
|
|
|
|
|
+ const parseQuery = (q?: string) => {
|
|
|
|
|
+ const out: Record<string, string> = {};
|
|
|
|
|
+ if (!q) return out;
|
|
|
|
|
+ const s = q.startsWith('?') ? q.substring(1) : q;
|
|
|
|
|
+ const usp = new URLSearchParams(s);
|
|
|
|
|
+ usp.forEach((v, k) => (out[k] = v));
|
|
|
|
|
+ return out;
|
|
|
|
|
+ };
|
|
|
|
|
+ const currentQuery = parseQuery((location as any).search || window.location.search);
|
|
|
|
|
+
|
|
|
|
|
+ // 3) 收集同路径候选节点
|
|
|
|
|
+ const candidates: any[] = [];
|
|
|
|
|
+ const dfs = (nodes: any[]) => {
|
|
|
|
|
+ for (const n of nodes) {
|
|
|
|
|
+ const nodePath = normalize(n.path);
|
|
|
|
|
+ if (nodePath === normalizedTargetPath) {
|
|
|
|
|
+ candidates.push(n);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (n.children && n.children.length > 0) dfs(n.children);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ dfs(tree);
|
|
|
|
|
+
|
|
|
|
|
+ if (candidates.length === 0) return undefined;
|
|
|
|
|
+ if (candidates.length === 1) return candidates[0];
|
|
|
|
|
+
|
|
|
|
|
+ // 4) 若有多个,用查询参数进行打分匹配(节点自身 path 上的 query 必须被当前页面包含且值相同)
|
|
|
|
|
+ const score = (n: any) => {
|
|
|
|
|
+ const parts = String(n.path || '').split('?');
|
|
|
|
|
+ if (parts.length < 2) return 0;
|
|
|
|
|
+ const nodeQuery = parseQuery(parts[1]);
|
|
|
|
|
+ let matched = 0;
|
|
|
|
|
+ Object.keys(nodeQuery).forEach((k) => {
|
|
|
|
|
+ if (currentQuery[k] !== undefined && currentQuery[k] === nodeQuery[k]) matched += 1;
|
|
|
|
|
+ });
|
|
|
|
|
+ return matched;
|
|
|
|
|
+ };
|
|
|
|
|
+ let best = candidates[0];
|
|
|
|
|
+ let bestScore = score(best);
|
|
|
|
|
+ for (let i = 1; i < candidates.length; i++) {
|
|
|
|
|
+ const s = score(candidates[i]);
|
|
|
|
|
+ if (s > bestScore) {
|
|
|
|
|
+ best = candidates[i];
|
|
|
|
|
+ bestScore = s;
|
|
|
|
|
+ } else if (s === bestScore) {
|
|
|
|
|
+ // 平分时,优先带有 function 的
|
|
|
|
|
+ const hasFuncBest = Array.isArray(best?.function) && best.function.length > 0;
|
|
|
|
|
+ const hasFuncCurr = Array.isArray(candidates[i]?.function) && candidates[i].function.length > 0;
|
|
|
|
|
+ if (!hasFuncBest && hasFuncCurr) best = candidates[i];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5) 若仍不唯一,尝试根据当前选中的菜单 key 精确命中
|
|
|
|
|
+ const selectedKeysStr = localStorage.getItem('selectedKeys');
|
|
|
|
|
+ if (selectedKeysStr) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const [selectedKey] = JSON.parse(selectedKeysStr) || [];
|
|
|
|
|
+ const byKey = candidates.find((n) => String(n.key) === String(selectedKey));
|
|
|
|
|
+ if (byKey) return byKey;
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return best;
|
|
|
|
|
+ };
|
|
|
|
|
+ const canManageReport = useMemo(() => {
|
|
|
|
|
+ const node = getMenuNodeByPath(initialState?.menuData || [], location.pathname);
|
|
|
|
|
+ const codes: string[] = Array.isArray((node as any)?.function)
|
|
|
|
|
+ ? ((node as any).function as any[]).map((i: any) => i?.code).filter(Boolean)
|
|
|
|
|
+ : [];
|
|
|
|
|
+ return codes.includes('report_manage');
|
|
|
|
|
+
|
|
|
|
|
+ }, [initialState?.menuData, location.pathname, (location as any).search]);
|
|
|
|
|
+
|
|
|
|
|
+ // 读取基础参数:userId、hospId(院区)
|
|
|
|
|
+ const getBaseParams = (): { userId?: string | number; hospId?: string | number } => {
|
|
|
|
|
+ const userId = (initialState as any)?.userData?.userId;
|
|
|
|
|
+ let hospId: any;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const subHop = localStorage.getItem('currentSelectedSubHop');
|
|
|
|
|
+ if (subHop) {
|
|
|
|
|
+ const parsed = JSON.parse(subHop);
|
|
|
|
|
+ hospId = parsed?.id;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ return { userId, hospId };
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const withBaseParams = (obj: any) => {
|
|
|
|
|
+ const base = getBaseParams();
|
|
|
|
|
+ // 强制覆盖为当前登录/选择的上下文
|
|
|
|
|
+ return { ...obj, ...base };
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 校验:只需是合法 JSON(userId、hospId 由前台自动拼接,不强制用户填写)
|
|
|
|
|
+ const validateParamJson = (_rule: any, value: any) => {
|
|
|
|
|
+ const text = (value ?? '').toString().trim();
|
|
|
|
|
+ if (text.length === 0) return Promise.resolve();
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSON.parse(text);
|
|
|
|
|
+ return Promise.resolve();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ return Promise.reject(new Error('请输入合法的 JSON'));
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 动态解析当前查询参数中的 indicatorType,支持 pathname/search 变化
|
|
|
|
|
+ const indicatorUrlType: string = React.useMemo(() => {
|
|
|
|
|
+ const search = (location as any)?.search || window.location.search || '';
|
|
|
|
|
+ const s = search.startsWith('?') ? search.substring(1) : search;
|
|
|
|
|
+ const usp = new URLSearchParams(s);
|
|
|
|
|
+ return usp.get('indicatorType') || '';
|
|
|
|
|
+ }, [location.search, location.pathname]);
|
|
|
|
|
|
|
|
const columns: ProColumns<any>[] = [
|
|
const columns: ProColumns<any>[] = [
|
|
|
{
|
|
{
|
|
@@ -202,7 +326,15 @@ const IndicatorMana = () => {
|
|
|
{
|
|
{
|
|
|
key: '2',
|
|
key: '2',
|
|
|
label: (
|
|
label: (
|
|
|
- <a href={record.indicatorPath} target="_blank">
|
|
|
|
|
|
|
+ <a
|
|
|
|
|
+ key="linka"
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ // 打开简化视图:只展示返回的header和“报告管理”按钮
|
|
|
|
|
+ set_currentEditRow(record);
|
|
|
|
|
+ set_actionType('ANALYZE');
|
|
|
|
|
+ set_currentBigTab('1');
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
统计分析
|
|
统计分析
|
|
|
</a>
|
|
</a>
|
|
|
),
|
|
),
|
|
@@ -479,6 +611,8 @@ const IndicatorMana = () => {
|
|
|
}, [currentTab, currentYear]);
|
|
}, [currentTab, currentYear]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
|
|
+ // 路由参数变动时重置页面到初始态
|
|
|
|
|
+ set_indicatorCateTreeData([]);
|
|
|
set_cateId(undefined);
|
|
set_cateId(undefined);
|
|
|
set_actionType(undefined);
|
|
set_actionType(undefined);
|
|
|
set_drawerActype(undefined);
|
|
set_drawerActype(undefined);
|
|
@@ -487,9 +621,16 @@ const IndicatorMana = () => {
|
|
|
set_tableColumns([]);
|
|
set_tableColumns([]);
|
|
|
set_tableDataSource([]);
|
|
set_tableDataSource([]);
|
|
|
set_currentEditRowData(undefined);
|
|
set_currentEditRowData(undefined);
|
|
|
|
|
+ set_defaultExpandedRowKeys([]);
|
|
|
|
|
+ set_tableDataSearchKeywords('');
|
|
|
|
|
+ set_currentSelectedLeft(undefined);
|
|
|
|
|
+ set_currentTab('1');
|
|
|
|
|
+ set_currentYear(defaultYear);
|
|
|
|
|
+ setReportModalVisible(false);
|
|
|
|
|
+ set_tableDataFilterParams({ current: 1, pageSize: 10, name: '' });
|
|
|
|
|
|
|
|
getIndicatorCateTree();
|
|
getIndicatorCateTree();
|
|
|
- }, [location.search]);
|
|
|
|
|
|
|
+ }, [location.search, location.pathname]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
if (!drawerVisible) {
|
|
if (!drawerVisible) {
|
|
@@ -511,26 +652,68 @@ const IndicatorMana = () => {
|
|
|
// 处理报告表单提交
|
|
// 处理报告表单提交
|
|
|
const handleReportSubmit = async (values: any) => {
|
|
const handleReportSubmit = async (values: any) => {
|
|
|
try {
|
|
try {
|
|
|
- const resp = await applyOnlineReportMap({
|
|
|
|
|
- code: currentEditRow.code,
|
|
|
|
|
- onlineReportCode: values.reportId,
|
|
|
|
|
- onlineRemark: values.remark,
|
|
|
|
|
- });
|
|
|
|
|
- if (resp) {
|
|
|
|
|
- message.success('提交成功');
|
|
|
|
|
- set_currentEditRow((prevRow: any) => ({
|
|
|
|
|
- ...prevRow,
|
|
|
|
|
- onlineRemark: values.remark,
|
|
|
|
|
|
|
+ const isAnalyze = actionType === 'ANALYZE';
|
|
|
|
|
+ const isDetailOnline = actionType === 'DETAIL' && currentBigTab === '1';
|
|
|
|
|
+
|
|
|
|
|
+ // 解析并校验 JSON 字符串;后端需要字符串,空则默认 '{}'
|
|
|
|
|
+ const rawParamStr = isAnalyze ? values?.analysisReportParam : values?.onlineReportParam;
|
|
|
|
|
+ const trimmed = (rawParamStr ?? '').toString().trim();
|
|
|
|
|
+ const textToSend = trimmed.length > 0 ? trimmed : '{}';
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSON.parse(textToSend);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ message.error('参数(JSON)格式不合法');
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 不在保存到后端时注入 userId/hospId,仅在 Superset 嵌入时动态拼接
|
|
|
|
|
+ const finalParamStr = textToSend;
|
|
|
|
|
+
|
|
|
|
|
+ if (isAnalyze) {
|
|
|
|
|
+ const resp = await applyStatisticalAnalysisMap({
|
|
|
|
|
+ code: currentEditRow.code,
|
|
|
|
|
+ analysisReportCode: values.reportId,
|
|
|
|
|
+ analysisRemark: values.remark,
|
|
|
|
|
+ analysisReportParam: finalParamStr,
|
|
|
|
|
+ });
|
|
|
|
|
+ if (resp) {
|
|
|
|
|
+ message.success('提交成功');
|
|
|
|
|
+ set_currentEditRow((prevRow: any) => ({
|
|
|
|
|
+ ...prevRow,
|
|
|
|
|
+ analysisRemark: values.remark,
|
|
|
|
|
+ analysisReportCode: values.reportId,
|
|
|
|
|
+ analysisReportParam: finalParamStr,
|
|
|
|
|
+ }));
|
|
|
|
|
+ set_reportReloadKey((k) => k + 1);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (isDetailOnline) {
|
|
|
|
|
+ const resp = await applyOnlineReportMap({
|
|
|
|
|
+ code: currentEditRow.code,
|
|
|
onlineReportCode: values.reportId,
|
|
onlineReportCode: values.reportId,
|
|
|
- }));
|
|
|
|
|
- return true; // 提交成功后关闭弹窗
|
|
|
|
|
|
|
+ onlineRemark: values.remark,
|
|
|
|
|
+ onlineReportParam: finalParamStr,
|
|
|
|
|
+ });
|
|
|
|
|
+ if (resp) {
|
|
|
|
|
+ message.success('提交成功');
|
|
|
|
|
+ set_currentEditRow((prevRow: any) => ({
|
|
|
|
|
+ ...prevRow,
|
|
|
|
|
+ onlineRemark: values.remark,
|
|
|
|
|
+ onlineReportCode: values.reportId,
|
|
|
|
|
+ onlineReportParam: finalParamStr,
|
|
|
|
|
+ }));
|
|
|
|
|
+ set_reportReloadKey((k) => k + 1);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ message.error('当前上下文不支持报告管理保存');
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('表单验证或提交失败:', error);
|
|
console.error('表单验证或提交失败:', error);
|
|
|
- message.error('提交失败'); // 添加错误提示
|
|
|
|
|
- return false; // 提交失败,保持弹窗打开
|
|
|
|
|
|
|
+ message.error('提交失败');
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
- // 如果 API 调用失败 (resp 为 false),显式返回 false
|
|
|
|
|
message.error('提交失败');
|
|
message.error('提交失败');
|
|
|
return false;
|
|
return false;
|
|
|
};
|
|
};
|
|
@@ -548,43 +731,88 @@ const IndicatorMana = () => {
|
|
|
)}
|
|
)}
|
|
|
|
|
|
|
|
{/* 报告管理弹窗 */}
|
|
{/* 报告管理弹窗 */}
|
|
|
- {reportModalVisible && (
|
|
|
|
|
- <ModalForm
|
|
|
|
|
- title="报告管理"
|
|
|
|
|
- open={reportModalVisible}
|
|
|
|
|
- onOpenChange={setReportModalVisible}
|
|
|
|
|
- onFinish={handleReportSubmit}
|
|
|
|
|
- width={500}
|
|
|
|
|
- initialValues={{
|
|
|
|
|
- reportId: currentEditRow?.onlineReportCode,
|
|
|
|
|
- remark: currentEditRow?.onlineRemark,
|
|
|
|
|
- }}
|
|
|
|
|
- formRef={reportForm}
|
|
|
|
|
- modalProps={{
|
|
|
|
|
- destroyOnClose: true,
|
|
|
|
|
- bodyStyle: {
|
|
|
|
|
- maxHeight: '72vh',
|
|
|
|
|
- overflowY: 'auto',
|
|
|
|
|
- overflowX: 'hidden',
|
|
|
|
|
- },
|
|
|
|
|
- }}
|
|
|
|
|
- >
|
|
|
|
|
- <ProFormText
|
|
|
|
|
- name="reportId"
|
|
|
|
|
- label="关联报告ID"
|
|
|
|
|
- placeholder="请输入"
|
|
|
|
|
- rules={[{ required: true, message: '请输入关联报告ID' }]}
|
|
|
|
|
|
|
+ <ModalForm
|
|
|
|
|
+ title="报告管理"
|
|
|
|
|
+ open={reportModalVisible}
|
|
|
|
|
+ onOpenChange={setReportModalVisible}
|
|
|
|
|
+ onFinish={handleReportSubmit}
|
|
|
|
|
+ width={500}
|
|
|
|
|
+ initialValues={
|
|
|
|
|
+ currentEditRow && (
|
|
|
|
|
+ actionType === 'ANALYZE'
|
|
|
|
|
+ ? {
|
|
|
|
|
+ reportId: currentEditRow.analysisReportCode,
|
|
|
|
|
+ remark: currentEditRow.analysisRemark,
|
|
|
|
|
+ analysisReportParam: (() => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const txt = currentEditRow.analysisReportParam;
|
|
|
|
|
+ if (!txt || String(txt).trim().length === 0) return '{}';
|
|
|
|
|
+ const obj = JSON.parse(String(txt));
|
|
|
|
|
+ return JSON.stringify(obj, null, 2);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ return String(currentEditRow.analysisReportParam || '{}');
|
|
|
|
|
+ }
|
|
|
|
|
+ })(),
|
|
|
|
|
+ }
|
|
|
|
|
+ : {
|
|
|
|
|
+ reportId: currentEditRow.onlineReportCode,
|
|
|
|
|
+ remark: currentEditRow.onlineRemark,
|
|
|
|
|
+ onlineReportParam: (() => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const txt = currentEditRow.onlineReportParam;
|
|
|
|
|
+ if (!txt || String(txt).trim().length === 0) return '{}';
|
|
|
|
|
+ const obj = JSON.parse(String(txt));
|
|
|
|
|
+ return JSON.stringify(obj, null, 2);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ return String(currentEditRow.onlineReportParam || '{}');
|
|
|
|
|
+ }
|
|
|
|
|
+ })(),
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ formRef={reportForm}
|
|
|
|
|
+ modalProps={{
|
|
|
|
|
+ destroyOnClose: true,
|
|
|
|
|
+ bodyStyle: {
|
|
|
|
|
+ maxHeight: '72vh',
|
|
|
|
|
+ overflowY: 'auto',
|
|
|
|
|
+ overflowX: 'hidden',
|
|
|
|
|
+ },
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <ProFormText
|
|
|
|
|
+ name="reportId"
|
|
|
|
|
+ label="关联报告ID"
|
|
|
|
|
+ placeholder="请输入"
|
|
|
|
|
+ rules={[{ required: true, message: '请输入关联报告ID' }]}
|
|
|
|
|
+ />
|
|
|
|
|
+ {actionType === 'ANALYZE' && (
|
|
|
|
|
+ <ProFormTextArea
|
|
|
|
|
+ name="analysisReportParam"
|
|
|
|
|
+ label="参数(JSON)"
|
|
|
|
|
+ placeholder='请输入合法 JSON,例如 {"a":1}'
|
|
|
|
|
+ rules={[{ validator: validateParamJson }]}
|
|
|
|
|
+ fieldProps={{ rows: 6 }}
|
|
|
/>
|
|
/>
|
|
|
|
|
+ )}
|
|
|
|
|
+ {actionType !== 'ANALYZE' && (
|
|
|
<ProFormTextArea
|
|
<ProFormTextArea
|
|
|
- name="remark"
|
|
|
|
|
- label="备注说明"
|
|
|
|
|
- placeholder="请输入"
|
|
|
|
|
- fieldProps={{
|
|
|
|
|
- rows: 4,
|
|
|
|
|
- }}
|
|
|
|
|
|
|
+ name="onlineReportParam"
|
|
|
|
|
+ label="参数(JSON)"
|
|
|
|
|
+ placeholder='请输入合法 JSON,例如 {"a":1}'
|
|
|
|
|
+ rules={[{ validator: validateParamJson }]}
|
|
|
|
|
+ fieldProps={{ rows: 6 }}
|
|
|
/>
|
|
/>
|
|
|
- </ModalForm>
|
|
|
|
|
- )}
|
|
|
|
|
|
|
+ )}
|
|
|
|
|
+ <ProFormTextArea
|
|
|
|
|
+ name="remark"
|
|
|
|
|
+ label="备注说明"
|
|
|
|
|
+ placeholder="请输入"
|
|
|
|
|
+ fieldProps={{
|
|
|
|
|
+ rows: 4,
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ </ModalForm>
|
|
|
|
|
|
|
|
{actionType == 'DETAIL' && (
|
|
{actionType == 'DETAIL' && (
|
|
|
<div className="FillingMana-detail">
|
|
<div className="FillingMana-detail">
|
|
@@ -621,13 +849,25 @@ const IndicatorMana = () => {
|
|
|
<div className="detail-noAuthRecord-title">暂无内容</div> */}
|
|
<div className="detail-noAuthRecord-title">暂无内容</div> */}
|
|
|
<div className="currentBigTab1content_header">
|
|
<div className="currentBigTab1content_header">
|
|
|
<span>{currentEditRow?.onlineRemark}</span>
|
|
<span>{currentEditRow?.onlineRemark}</span>
|
|
|
- <div className="btn" onClick={openReportModal}>
|
|
|
|
|
- <IconFont type="iconpeizhi" /> 报告管理
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ {canManageReport && (
|
|
|
|
|
+ <div className='btn' onClick={openReportModal}>
|
|
|
|
|
+ <IconFont type='iconpeizhi' /> 报告管理
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
</div>
|
|
</div>
|
|
|
- {currentEditRow && currentEditRow.onlineReportCode && (
|
|
|
|
|
|
|
+ {(currentEditRow && currentEditRow.onlineReportCode) && (
|
|
|
<FrameComponent
|
|
<FrameComponent
|
|
|
- link={`/platform/setting/embeddedDashboard/${currentEditRow.onlineReportCode}?noTopbar=true&noMenu=true`}
|
|
|
|
|
|
|
+ link={`/platform/setting/embeddedDashboard/${currentEditRow.onlineReportCode}?noTopbar=true&noMenu=true&reload=${reportReloadKey}&urlParams=${encodeURIComponent(
|
|
|
|
|
+ (() => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const base = withBaseParams({});
|
|
|
|
|
+ const raw = currentEditRow?.onlineReportParam ? JSON.parse(currentEditRow.onlineReportParam) : {};
|
|
|
|
|
+ return JSON.stringify({ ...base, ...raw });
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return JSON.stringify(withBaseParams({}));
|
|
|
|
|
+ }
|
|
|
|
|
+ })()
|
|
|
|
|
+ )}`}
|
|
|
/>
|
|
/>
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
@@ -708,11 +948,50 @@ const IndicatorMana = () => {
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
|
)}
|
|
)}
|
|
|
- {actionType != 'DETAIL' && (
|
|
|
|
|
|
|
+ {actionType == 'ANALYZE' && (
|
|
|
|
|
+ <div className="FillingMana-detail">
|
|
|
|
|
+ <div className="FillingMana-detail-header">
|
|
|
|
|
+ <div className="FillingMana-detail-header-title">
|
|
|
|
|
+ <div className="backBtn" onClick={() => set_currentEditRow(undefined)}>
|
|
|
|
|
+ <IconFont style={{ fontSize: 15 }} type={'iconfanhui'} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span>{currentEditRow?.name}</span>
|
|
|
|
|
+ {canManageReport && (
|
|
|
|
|
+ <div className='btn' onClick={openReportModal} style={{ marginLeft: 'auto' }}>
|
|
|
|
|
+ <IconFont type='iconpeizhi' /> 报告管理
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="FillingMana-detail-header-title-sub">
|
|
|
|
|
+ <span>指标编码:{currentEditRow?.code}</span>
|
|
|
|
|
+ <span>指标定义:{currentEditRow?.targetDefinition}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="currentBigTab1content">
|
|
|
|
|
+ {(currentEditRow && currentEditRow.analysisReportCode) && (
|
|
|
|
|
+ <FrameComponent
|
|
|
|
|
+ link={`/platform/setting/embeddedDashboard/${currentEditRow.analysisReportCode}?noTopbar=true&noMenu=true&reload=${reportReloadKey}&urlParams=${encodeURIComponent(
|
|
|
|
|
+ (() => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const base = withBaseParams({});
|
|
|
|
|
+ const raw = currentEditRow?.analysisReportParam ? JSON.parse(currentEditRow.analysisReportParam) : {};
|
|
|
|
|
+ return JSON.stringify({ ...base, ...raw });
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return JSON.stringify(withBaseParams({}));
|
|
|
|
|
+ }
|
|
|
|
|
+ })()
|
|
|
|
|
+ )}`}
|
|
|
|
|
+ />
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+ {(!actionType || actionType === 'NORMAL') && (
|
|
|
<div className="content">
|
|
<div className="content">
|
|
|
<div className="left">
|
|
<div className="left">
|
|
|
{/* <TreeDirectory data={indicatorCateTreeData} onSelectChange={(info) => onSelectChangehandle(info)} /> */}
|
|
{/* <TreeDirectory data={indicatorCateTreeData} onSelectChange={(info) => onSelectChangehandle(info)} /> */}
|
|
|
<KCIMLeftList
|
|
<KCIMLeftList
|
|
|
|
|
+ key={`${location.pathname}${location.search}`}
|
|
|
searchKey={'name'}
|
|
searchKey={'name'}
|
|
|
listType="tree"
|
|
listType="tree"
|
|
|
dataSource={indicatorCateTreeData}
|
|
dataSource={indicatorCateTreeData}
|