diff --git a/webapp/packages/supersonic-fe/package.json b/webapp/packages/supersonic-fe/package.json index 3054f6432..297647140 100644 --- a/webapp/packages/supersonic-fe/package.json +++ b/webapp/packages/supersonic-fe/package.json @@ -100,7 +100,7 @@ "sql-formatter": "^2.3.3", "supersonic-chat-sdk": "0.0.0", "umi": "3.5", - "umi-request": "^1.0.8" + "umi-request": "^1.4.0" }, "devDependencies": { "@ant-design/pro-cli": "^2.0.2", diff --git a/webapp/packages/supersonic-fe/src/components/MDatePicker/index.tsx b/webapp/packages/supersonic-fe/src/components/MDatePicker/index.tsx index d6171a268..a1bdf942d 100644 --- a/webapp/packages/supersonic-fe/src/components/MDatePicker/index.tsx +++ b/webapp/packages/supersonic-fe/src/components/MDatePicker/index.tsx @@ -75,14 +75,6 @@ const MDatePicker: React.FC = ({ initialValues?.staticParams?.dateRangeType || DateRangeType.DAY, ); - // const [pickerType, setPickerType] = useState(() => { - // // if (staticFormData.dateRangeType) { - // // return DateRangeTypeToPickerMap[staticFormData.dateRangeType]; - // // } - // return DateRangePicker.DATE; - // }); - - // const [dateRangeValue, setDateRangeValue] = useState([]); const staticDefaultConfig = { dateSettingType: DateSettingType.STATIC, @@ -92,8 +84,7 @@ const MDatePicker: React.FC = ({ dateMultiple: [], dateRangeStringDesc: '', }; - // const { getMaxPartitionData } = useModel('useMaxPartitionData'); - // const { globalViewId } = useModel('useViewsData'); + const [latestDateMap, setLatestDateMap] = useState({ maxPartition: moment().format('YYYY-MM-DD'), }); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx index 35934379b..1336d492d 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx @@ -83,12 +83,17 @@ const MetricFilter: React.FC = ({ initFilterValues = {}, onFiltersChange - + + + + + + diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx index ba2d90c51..1107860f0 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx @@ -1,10 +1,11 @@ import React, { useState, useEffect, useRef } from 'react'; import { SemanticNodeType } from '../../enum'; import moment from 'moment'; -import { message } from 'antd'; -import { queryStruct } from '@/pages/SemanticModel/service'; +import { message, Row, Col, Button } from 'antd'; +import { queryStruct, downloadCosFile } from '@/pages/SemanticModel/service'; import TrendChart from '@/pages/SemanticModel/Metric/components/MetricTrend'; import MDatePicker from '@/components/MDatePicker'; +import { useModel } from 'umi'; import { DateRangeType, DateSettingType } from '@/components/MDatePicker/type'; import { ISemantic } from '../../data'; @@ -24,6 +25,7 @@ const MetricTrendSection: React.FC = ({ nodeData }) => { const [metricTrendLoading, setMetricTrendLoading] = useState(false); const [metricColumnConfig, setMetricColumnConfig] = useState(); const [authMessage, setAuthMessage] = useState(''); + const [downloadLoding, setDownloadLoding] = useState(false); const [periodDate, setPeriodDate] = useState<{ startDate: string; endDate: string; @@ -34,17 +36,28 @@ const MetricTrendSection: React.FC = ({ nodeData }) => { dateField: dateFieldMap[DateRangeType.DAY], }); - const getMetricTrendData = async () => { - setMetricTrendLoading(true); + const getMetricTrendData = async (download = false) => { + if (download) { + setDownloadLoding(true); + } else { + setMetricTrendLoading(true); + } + const { modelId, bizName, name } = nodeData; indicatorFields.current = [{ name, column: bizName }]; - const { code, data, msg } = await queryStruct({ + const res = await queryStruct({ modelId, bizName, dateField: periodDate.dateField, startDate: periodDate.startDate, endDate: periodDate.endDate, + download, }); + if (download) { + setDownloadLoding(false); + return; + } + const { code, data, msg } = res; setMetricTrendLoading(false); if (code === 200) { const { resultList, columns, queryAuthorization } = data; @@ -78,42 +91,52 @@ const MetricTrendSection: React.FC = ({ nodeData }) => { return ( <>
- { - const [startDate, endDate] = value; - const { dateSettingType, dynamicParams, staticParams } = config; - let dateField = dateFieldMap[DateRangeType.DAY]; - if (DateSettingType.DYNAMIC === dateSettingType) { - dateField = dateFieldMap[dynamicParams.dateRangeType]; - } - if (DateSettingType.STATIC === dateSettingType) { - dateField = dateFieldMap[staticParams.dateRangeType]; - } - setPeriodDate({ startDate, endDate, dateField }); - }} - disabledAdvanceSetting={true} - /> + + + { + const [startDate, endDate] = value; + const { dateSettingType, dynamicParams, staticParams } = config; + let dateField = dateFieldMap[DateRangeType.DAY]; + if (DateSettingType.DYNAMIC === dateSettingType) { + dateField = dateFieldMap[dynamicParams.dateRangeType]; + } + if (DateSettingType.STATIC === dateSettingType) { + dateField = dateFieldMap[staticParams.dateRangeType]; + } + setPeriodDate({ startDate, endDate, dateField }); + }} + disabledAdvanceSetting={true} + /> + + + + +
- {authMessage && ( -
- 指标存在如下权限问题: {authMessage} -
- )} -
指标存在如下权限问题: {authMessage}
+ {authMessage &&
{authMessage}
} = ({ domainManger, dispatch }) => { + const { initialState = {} } = useModel('@@initialState'); + + const { currentUser = {} } = initialState as any; + const { selectDomainId, selectModelId: modelId } = domainManger; const [createModalVisible, setCreateModalVisible] = useState(false); const defaultPagination = { @@ -59,6 +63,7 @@ const ClassMetricTable: React.FC = ({ domainManger, dispatch }) => { const { code, data, msg } = await queryMetric({ ...pagination, ...params, + createdBy: params.onlyShowMe ? currentUser.name : null, pageSize: params.showType ? 100 : defaultPagination.pageSize, }); setLoading(false); @@ -184,15 +189,6 @@ const ClassMetricTable: React.FC = ({ domainManger, dispatch }) => { title: '描述', search: false, }, - // { - // dataIndex: 'type', - // title: '指标类型', - // valueEnum: { - // ATOMIC: '原子指标', - // DERIVED: '衍生指标', - // }, - // }, - { dataIndex: 'updatedAt', title: '更新时间', diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/NodeInfoDrawer.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/NodeInfoDrawer.tsx index 289ea5153..c24d5037a 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/NodeInfoDrawer.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/NodeInfoDrawer.tsx @@ -62,13 +62,11 @@ const NodeInfoDrawer: React.FC = ({ } const { alias, - fullPath, bizName, createdBy, createdAt, updatedAt, description, - // domainName, sensitiveLevel, modelName, nodeType, @@ -111,13 +109,11 @@ const NodeInfoDrawer: React.FC = ({ { title: '指标趋势', render: () => ( -
- - - - - -
+ + + + + ), }, { diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts b/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts index 4a5ee782d..1eb2abcaf 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts @@ -1,4 +1,7 @@ import request from 'umi-request'; +import axios from 'axios'; +import { AUTH_TOKEN_KEY } from '@/common/constants'; +import moment from 'moment'; const getRunningEnv = () => { return window.location.pathname.includes('/chatSetting/') ? 'chat' : 'semantic'; @@ -366,47 +369,69 @@ export function searchDictLatestTaskList(data: any): Promise { }); } -export function queryStruct({ +const downloadStruct = (blob: Blob) => { + const fieldName = `supersonic_${moment().format('YYYYMMDDhhmmss')}.xlsx`; + const link = document.createElement('a'); + link.href = URL.createObjectURL(new Blob([blob])); + link.download = fieldName; + document.body.appendChild(link); + link.click(); + URL.revokeObjectURL(link.href); + document.body.removeChild(link); +}; + +export async function queryStruct({ modelId, bizName, dateField = 'sys_imp_date', startDate, endDate, + download = false, }: { modelId: number; bizName: string; dateField: string; startDate: string; endDate: string; + download?: boolean; }): Promise { - return request(`${process.env.API_BASE_URL}query/struct`, { - method: 'POST', - data: { - modelId, - groups: [dateField], - aggregators: [ - { - column: bizName, - // func: 'SUM', - nameCh: 'null', - args: null, + const response = await request( + `${process.env.API_BASE_URL}query/${download ? 'download/' : ''}struct`, + { + method: 'POST', + ...(download ? { responseType: 'blob', getResponse: true } : {}), + data: { + modelId, + groups: [dateField], + aggregators: [ + { + column: bizName, + // func: 'SUM', + nameCh: 'null', + args: null, + }, + ], + orders: [], + dimensionFilters: [], + metricFilters: [], + params: [], + dateInfo: { + dateMode: 'BETWEEN', + startDate, + endDate, + dateList: [], + unit: 7, + period: 'DAY', + text: 'null', }, - ], - orders: [], - dimensionFilters: [], - metricFilters: [], - params: [], - dateInfo: { - dateMode: 'BETWEEN', - startDate, - endDate, - dateList: [], - unit: 7, - period: 'DAY', - text: 'null', + limit: 365, + nativeQuery: false, }, - limit: 365, - nativeQuery: false, }, - }); + ); + if (download) { + downloadStruct(response.data); + } else { + return response; + } } diff --git a/webapp/packages/supersonic-fe/src/services/request.ts b/webapp/packages/supersonic-fe/src/services/request.ts index ce3588267..7c5b7f122 100644 --- a/webapp/packages/supersonic-fe/src/services/request.ts +++ b/webapp/packages/supersonic-fe/src/services/request.ts @@ -39,11 +39,13 @@ const responseInterceptor = async (response: Response) => { const contextpath = response.headers.get('contextpath'); win.location.href = contextpath; } else { - const data: Result = await response?.clone()?.json?.(); - if (Number(data.code) === 403) { - history.push('/login'); - return response; - } + try { + const data: Result = await response?.clone()?.json?.(); + if (Number(data.code) === 403) { + history.push('/login'); + return response; + } + } catch (e) {} } return response;