From 057df422336fdbcb33146638c78a8247919a330b Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Fri, 26 Sep 2025 17:29:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20BI=E6=8A=A5=E8=A1=A8=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bi-report-design/public/svg/ascending.svg | 1 + .../bi-report-design/public/svg/config.svg | 1 + .../public/svg/descending.svg | 1 + .../bi-time-select/bi-time-select.scss | 18 +++ .../bi-time-select/bi-time-select.tsx | 145 ++++++++++++++++++ .../bi-report-design/src/components/index.ts | 2 + .../base/bar-converter-base.ts | 15 +- .../base/echart-converter-base.ts | 59 +++++-- .../base/zone-converter-base.ts | 2 + .../echart-converter/pie-converter.ts | 9 +- .../echart-converter/radar-converter.ts | 10 +- .../grid-converter/grid-converter-base.ts | 4 +- .../bi-report-draggable.scss | 8 + .../bi-report-draggable.tsx | 142 +++++++++++------ .../src/interface/i-bi-period-data.ts | 64 ++++++++ .../src/interface/i-data-item-provider.ts | 10 +- .../bi-report-design/src/interface/index.ts | 1 + .../providers/data-item/data-item-provider.ts | 15 +- .../data-item/dimension-col-provider.ts | 22 +++ .../providers/data-item/dimension-provider.ts | 34 ++-- .../src/providers/data-item/group-provider.ts | 4 +- .../providers/data-item/measure-provider.ts | 28 ---- .../providers/data-item/period-provider.ts | 49 +++++- .../src/utils/report-design-ctx.ts | 56 +++++++ .../src/utils/ui-field-mapping.ts | 2 + .../src/theme/studio-dark/editor.scss | 9 ++ 26 files changed, 564 insertions(+), 147 deletions(-) create mode 100644 packages/bi-report-design/public/svg/ascending.svg create mode 100644 packages/bi-report-design/public/svg/config.svg create mode 100644 packages/bi-report-design/public/svg/descending.svg create mode 100644 packages/bi-report-design/src/components/bi-time-select/bi-time-select.scss create mode 100644 packages/bi-report-design/src/components/bi-time-select/bi-time-select.tsx create mode 100644 packages/bi-report-design/src/interface/i-bi-period-data.ts diff --git a/packages/bi-report-design/public/svg/ascending.svg b/packages/bi-report-design/public/svg/ascending.svg new file mode 100644 index 00000000..0310f7aa --- /dev/null +++ b/packages/bi-report-design/public/svg/ascending.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/bi-report-design/public/svg/config.svg b/packages/bi-report-design/public/svg/config.svg new file mode 100644 index 00000000..a5739e23 --- /dev/null +++ b/packages/bi-report-design/public/svg/config.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/bi-report-design/public/svg/descending.svg b/packages/bi-report-design/public/svg/descending.svg new file mode 100644 index 00000000..7cf14d28 --- /dev/null +++ b/packages/bi-report-design/public/svg/descending.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/bi-report-design/src/components/bi-time-select/bi-time-select.scss b/packages/bi-report-design/src/components/bi-time-select/bi-time-select.scss new file mode 100644 index 00000000..a575a7f2 --- /dev/null +++ b/packages/bi-report-design/src/components/bi-time-select/bi-time-select.scss @@ -0,0 +1,18 @@ +@include b('bi-time-select') { + width: 100%; + padding: getCssVar(spacing, base-loose) getCssVar(spacing, loose); + @include e('header') { + display: flex; + width: 100%; + } + @include e('content') { + padding: getCssVar(spacing, loose) 0; + } + @include e('footer') { + display: flex; + justify-content: end; + margin-top: getCssVar(spacing, base-tight); + } +} + + diff --git a/packages/bi-report-design/src/components/bi-time-select/bi-time-select.tsx b/packages/bi-report-design/src/components/bi-time-select/bi-time-select.tsx new file mode 100644 index 00000000..d97c57c4 --- /dev/null +++ b/packages/bi-report-design/src/components/bi-time-select/bi-time-select.tsx @@ -0,0 +1,145 @@ +import { + h, + ref, + Ref, + watch, + PropType, + defineComponent, + resolveComponent, +} from 'vue'; +import { + IModal, + getEditorProvider, + IEditorContainerController, +} from '@ibiz-template/runtime'; +import { IDateRange } from '@ibiz/model-core'; +import { useNamespace } from '@ibiz-template/vue3-util'; +import { IBIPeriodData } from '../../interface'; +import './bi-time-select.scss'; + +export default defineComponent({ + name: 'IBizBITimeSelect', + props: { + context: { + type: Object as PropType, + required: true, + }, + params: { + type: Object as PropType, + required: true, + }, + value: { + type: Object as PropType, + default: () => {}, + }, + modal: { type: Object as PropType, required: true }, + }, + setup(props) { + const ns = useNamespace('bi-time-select'); + // 编辑器模型 + const editorModel: IDateRange = { + appId: '', + editorType: 'DATERANGE_SWITCHUNIT', + dateTimeFormat: 'YYYY-MM-DD', + }; + + // 编辑器provider + const editorProvider = ref(); + // 编辑器值 + const editor = ref(); + // 当前选择值 + const curValue: Ref = ref({ + pop: 1, + yoy: 1, + end: 0, + start: -7, + unit: 'DAY', + type: 'DYNAMIC', + }); + + // 值改变 + const onValueChange = (value: IData) => { + curValue.value = value; + }; + + // 初始化 + const init = async () => { + editorProvider.value = await getEditorProvider(editorModel); + if (editorProvider.value) { + editor.value = await editorProvider.value.createController( + editorModel, + { + context: props.context, + params: props.params, + } as IEditorContainerController, + ); + } + }; + + // 监听值改变 + watch( + () => props.value, + newVal => { + if (newVal) curValue.value = newVal; + }, + { + immediate: true, + }, + ); + + init(); + + /** + * 绘制编辑器 + * + * @return {*} + */ + const renderEditor = () => { + if (editor.value) { + const component = resolveComponent('IBizDateRangeSelect'); + return h(component, { + value: props.value, + controller: editor.value, + onChange: (val: IData): void => { + onValueChange(val); + }, + }); + } + }; + + // 取消 + const onCancel = () => { + props.modal.dismiss({ ok: false }); + }; + + // 确认 + const onOK = () => { + props.modal.dismiss({ ok: true, data: [curValue.value] }); + }; + + return { + ns, + renderEditor, + onOK, + onCancel, + }; + }, + render() { + return ( +
+
+ 配置 +
+
{this.renderEditor()}
+
+ + 取消 + + + 确认 + +
+
+ ); + }, +}); diff --git a/packages/bi-report-design/src/components/index.ts b/packages/bi-report-design/src/components/index.ts index 5c91a780..e2e85b57 100644 --- a/packages/bi-report-design/src/components/index.ts +++ b/packages/bi-report-design/src/components/index.ts @@ -1,10 +1,12 @@ import { App } from 'vue'; import IBizBIChartType from './bi-chart-type/bi-chart-type'; import BIReportChartShell from './bi-report-chart-shell'; +import IBizBITimeSelect from './bi-time-select/bi-time-select'; export default { install(app: App) { app.component('IBizBIChartType', IBizBIChartType); + app.component('IBizBITimeSelect', IBizBITimeSelect); app.use(BIReportChartShell); }, }; diff --git a/packages/bi-report-design/src/controller/converter/echart-converter/base/bar-converter-base.ts b/packages/bi-report-design/src/controller/converter/echart-converter/base/bar-converter-base.ts index 8ccfb62b..6b77adbb 100644 --- a/packages/bi-report-design/src/controller/converter/echart-converter/base/bar-converter-base.ts +++ b/packages/bi-report-design/src/controller/converter/echart-converter/base/bar-converter-base.ts @@ -115,18 +115,11 @@ export class BarConverterBase extends MultiSeriesConverter { // 显示数据范围 if (series_label_data_range && series_label_data_range !== 'all') { - const value = seriesModel.valueField; // 只显示最大最小值 - const numbers = items - .filter((_item: IData) => - Object.prototype.hasOwnProperty.call(_item, value), - ) - .map((item: IData) => Number(item[value]) || 0); - const max = Math.max(...numbers) || 0; - const min = Math.min(...numbers) || 0; - options.formatter = `function(param) { - if(param.value[0] === ${max} || param.value[0] === ${min}){ - return param.value[0]; + const { max, min } = this.calcMaxMin(seriesModel, data, items); + options.formatter = `function(param) { + if(param.value[1] === ${max} || param.value[1] === ${min}){ + return param.value[1]; } return ''; }`; diff --git a/packages/bi-report-design/src/controller/converter/echart-converter/base/echart-converter-base.ts b/packages/bi-report-design/src/controller/converter/echart-converter/base/echart-converter-base.ts index b53ea124..460e91d8 100644 --- a/packages/bi-report-design/src/controller/converter/echart-converter/base/echart-converter-base.ts +++ b/packages/bi-report-design/src/controller/converter/echart-converter/base/echart-converter-base.ts @@ -240,6 +240,54 @@ export abstract class EchartConverterBase extends ConverterBase { return { 'EC.yAxis': JSON.stringify(options) }; } + /** + * @description 计算最大值最小值 + * @param {IModel} seriesModel + * @param {IData} data + * @param {IData[]} items + * @returns {*} {{ max: number; min: number }} + * @memberof EchartConverterBase + */ + calcMaxMin( + seriesModel: IModel, + data: IData, + items: IData[], + ): { max: number; min: number } { + const { valueField, catalogField, seriesField } = seriesModel; + const catalogFields = data.dimensions?.map(d => d.codename.toLowerCase()); + const count = items.reduce((acc, item) => { + let catalogName = ''; + if (catalogFields.length) { + catalogFields.forEach(key => { + catalogName += item[key]; + }); + } else { + catalogName = item[catalogField]; + } + const name = seriesField + ? `${item[seriesField]}_${catalogName}` + : `${catalogName}`; + const value = item[valueField]; + // 如果分组不存在,初始化结构 + if (!acc[name]) { + acc[name] = { + sum: 0, + max: -Infinity, // 初始化为极小值 + min: Infinity, // 初始化为极大值 + }; + } + // 更新统计值 + acc[name].sum += value; + acc[name].max = Math.max(acc[name].max, value); + acc[name].min = Math.min(acc[name].min, value); + return acc; + }, {}); + const allSums = Object.values(count).map(item => item.sum); + const max = Math.max(...allSums); + const min = Math.min(...allSums); + return { max, min }; + } + /** * 获取标签参数 * @@ -282,16 +330,9 @@ export abstract class EchartConverterBase extends ConverterBase { // 显示数据范围 if (series_label_data_range && series_label_data_range !== 'all') { - const value = seriesModel.valueField; // 只显示最大最小值 - const numbers = items - .filter((_item: IData) => - Object.prototype.hasOwnProperty.call(_item, value), - ) - .map((item: IData) => Number(item[value]) || 0); - const max = Math.max(...numbers) || 0; - const min = Math.min(...numbers) || 0; - options.formatter = `function(param) { + const { max, min } = this.calcMaxMin(seriesModel, data, items); + options.formatter = `function(param) { if(param.value[1] === ${max} || param.value[1] === ${min}){ return param.value[1]; } diff --git a/packages/bi-report-design/src/controller/converter/echart-converter/base/zone-converter-base.ts b/packages/bi-report-design/src/controller/converter/echart-converter/base/zone-converter-base.ts index a3fa1329..c8ae862c 100644 --- a/packages/bi-report-design/src/controller/converter/echart-converter/base/zone-converter-base.ts +++ b/packages/bi-report-design/src/controller/converter/echart-converter/base/zone-converter-base.ts @@ -61,6 +61,8 @@ export class ZoneConverterBase extends MultiSeriesConverter { nameGap: 50, }); Object.assign(tempOption.axisLabel, { + width: 100, + lineHeight: 1, rich: { top: { padding: [0, 0, 15, 0], diff --git a/packages/bi-report-design/src/controller/converter/echart-converter/pie-converter.ts b/packages/bi-report-design/src/controller/converter/echart-converter/pie-converter.ts index 9f46357d..d4698020 100644 --- a/packages/bi-report-design/src/controller/converter/echart-converter/pie-converter.ts +++ b/packages/bi-report-design/src/controller/converter/echart-converter/pie-converter.ts @@ -138,15 +138,8 @@ export class PieConverter extends MultiSeriesConverter { } }; Object.assign(labelLayoutOption, { 'EC.labelLayout': labelLayout }); - const value = seriesModel.valueField; // 只显示最大最小值 - const numbers = items - .filter((_item: IData) => - Object.prototype.hasOwnProperty.call(_item, value), - ) - .map((item: IData) => Number(item[value]) || 0); - const max = Math.max(...numbers) || 0; - const min = Math.min(...numbers) || 0; + const { max, min } = this.calcMaxMin(seriesModel, data, items); options.formatter = `function(param) { let tempName = param.name; const { data } = param; diff --git a/packages/bi-report-design/src/controller/converter/echart-converter/radar-converter.ts b/packages/bi-report-design/src/controller/converter/echart-converter/radar-converter.ts index 831fd917..dfeb767c 100644 --- a/packages/bi-report-design/src/controller/converter/echart-converter/radar-converter.ts +++ b/packages/bi-report-design/src/controller/converter/echart-converter/radar-converter.ts @@ -108,15 +108,7 @@ export class RadarConverter extends MultiSeriesConverter { // 显示数据范围 if (series_label_data_range && series_label_data_range !== 'all') { - const value = seriesModel.valueField; - // 只显示最大最小值 - const numbers = items - .filter((_item: IData) => - Object.prototype.hasOwnProperty.call(_item, value), - ) - .map((item: IData) => Number(item[value]) || 0); - const max = Math.max(...numbers) || 0; - const min = Math.min(...numbers) || 0; + const { min, max } = this.calcMaxMin(seriesModel, data, items); options.formatter = `function(param) { if(param.value === ${max} || param.value === ${min}){ return param.value; diff --git a/packages/bi-report-design/src/controller/converter/grid-converter/grid-converter-base.ts b/packages/bi-report-design/src/controller/converter/grid-converter/grid-converter-base.ts index 9677bdf6..2b62e8fd 100644 --- a/packages/bi-report-design/src/controller/converter/grid-converter/grid-converter-base.ts +++ b/packages/bi-report-design/src/controller/converter/grid-converter/grid-converter-base.ts @@ -89,8 +89,8 @@ export abstract class GridConverterBase extends ConverterBase { } if (grid_function_setting.indexOf('showPercent') !== -1) { Object.assign(ctrlParams, { - percentkeys: data.measures!.map((x: IData) => - x.codename.toLowerCase(), + percentkeys: JSON.stringify( + data.measures!.map((x: IData) => x.codename.toLowerCase()), ), }); } diff --git a/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.scss b/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.scss index 0de3d948..051569c4 100644 --- a/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.scss +++ b/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.scss @@ -120,6 +120,10 @@ padding: 8px 12px; cursor: pointer; + > div { + pointer-events: none; + } + @include e(icon) { display: flex; flex: 0 0 auto; @@ -164,6 +168,10 @@ } } +@include b('bi-report-draggable-action-popover') { + border-radius: 4px; +} + // 暗色主题 :root.studio_dark { @include b('bi-report-draggable-item'){ diff --git a/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.tsx b/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.tsx index 7eb1157e..db5d049e 100644 --- a/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.tsx +++ b/packages/bi-report-design/src/editors/bi-report-draggable/bi-report-draggable.tsx @@ -1,22 +1,25 @@ +/* eslint-disable no-case-declarations */ import { useNamespace } from '@ibiz-template/vue3-util'; import { - defineComponent, + h, + ref, + watch, nextTick, onMounted, onUnmounted, - ref, - watch, + defineComponent, + resolveComponent, } from 'vue'; import draggable from 'vuedraggable'; -import { FormItemController } from '@ibiz-template/runtime'; +import { FormItemController, IModal, IModalData } from '@ibiz-template/runtime'; import { IActionItem } from '@ibiz-template-plugin/design-base'; import { SortableEvent } from 'sortablejs'; import { generateOrderValue } from 'qx-util'; -import './bi-report-draggable.scss'; import { DataItemProviderFactory } from '../../providers'; import { resource } from '../../global'; import { BIReportDesignViewController } from '../../views'; import { getCustomEditorEmits, getCustomInputProps } from '../params'; +import './bi-report-draggable.scss'; export default defineComponent({ name: 'IBizBIReportDraggable', @@ -71,7 +74,8 @@ export default defineComponent({ const isDragging = ref(false); // 视图控制器 - const view = formItemController?.form?.view as BIReportDesignViewController; + const view = formItemController?.form + ?.view as unknown as BIReportDesignViewController; // 是否必填 const isRequired = @@ -99,9 +103,7 @@ export default defineComponent({ // 处理素材变更 const handleMaterialChange = (e: IData) => { - if (!e || !type || e.type !== type.toUpperCase()) { - return; - } + if (!e || !type || e.type !== type.toUpperCase()) return; materialItems.value = reportDesignCtx?.getCubeItems(type.toUpperCase()) || []; }; @@ -110,9 +112,7 @@ export default defineComponent({ // 处理拖拽目标变更 const handleDragTargetChange = async (e: IData) => { - if (!e || e.dragType !== type) { - return; - } + if (!e || e.dragType !== type) return; const item = e.dragTarget; if (item) { allowDropState.value = await dataItemProvider.allowDragging( @@ -132,12 +132,23 @@ export default defineComponent({ // 更新值 const updateValue = () => { - emit('change', [...items.value]); + emit( + 'change', + items.value.map(item => ({ + sort: item.sort, + params: item.params, + caption: item.caption, + codename: item.codename, + birepitemtype: item.birepitemtype, + pssysbicubedimensionid: item.pssysbicubedimensionid, + pssysbireportitemid: item.pssysbireportitemid, + })), + ); if (valueItem) { emit( 'change', items.value - .map(entity => entity.pssysbireportitemid) + .map(entity => entity.codename) .filter(Boolean) .join(','), valueItem, @@ -223,9 +234,7 @@ export default defineComponent({ // 处理项添加 const handleAdd = async (evt: SortableEvent) => { const item = (evt.item as IData)?._underlying_vm_; - if (!item) { - return; - } + if (!item) return; const container = evt.to; const originalEvent: DragEvent = (evt as IData).originalEvent; const target = originalEvent?.target as HTMLElement; @@ -307,6 +316,15 @@ export default defineComponent({ }, ); + /** + * @description 关闭行为飘窗 + */ + const closeActionPop = () => { + if (processing.value) return; + actionPop.value.visible = false; + actionPop.value.key = ''; + }; + // 处理行为点击 const handleActionClick = async ( e: MouseEvent, @@ -315,17 +333,58 @@ export default defineComponent({ index: number, ) => { e.stopPropagation(); - if (action.type === 'EDIT') { - editorItem.value = item; - editorValue.value = item.caption || ''; - nextTick(() => { - inputRef.value?.focus?.(); - }); - } else if (action.type === 'REMOVE') { - await dataItemProvider.removeItem(c.context, c.params, item); - items.value.splice(index, 1); - updateValue(); + processing.value = true; + switch (action.type) { + case 'EDIT': + editorItem.value = item; + editorValue.value = item.caption || ''; + nextTick(() => { + inputRef.value?.focus?.(); + }); + break; + case 'REMOVE': + await dataItemProvider.removeItem(c.context, c.params, item); + items.value.splice(index, 1); + updateValue(); + break; + case 'SORT': + item.sort = item.sort !== 'desc' ? 'desc' : 'asc'; + updateValue(); + break; + case 'PERIOD_CONFIG': + const popover = ibiz.overlay.createPopover( + (modal: IModal) => { + return h(resolveComponent('IBizBITimeSelect'), { + modal, + params: c.params, + context: c.context, + value: item.params, + }); + }, + undefined, + { + noArrow: true, + width: '400px', + autoClose: true, + placement: 'right', + modalClass: `${ns.b('action-popover')}`, + }, + ); + await popover.present(e.target as HTMLElement); + const result: IModalData = await popover.onWillDismiss(); + if (result.ok) { + item.params = { + ...result.data?.[0], + field: item.codename.toLowerCase(), + }; + updateValue(); + } + break; + default: + break; } + processing.value = false; + closeActionPop(); }; // 处理编辑框失去焦点 @@ -343,7 +402,7 @@ export default defineComponent({ { ...item, pssysbireportitemname: text }, ); items.value[index] = targetEntity; - emit('change', [...items.value]); + updateValue(); }; // 处理键盘点击 @@ -357,21 +416,13 @@ export default defineComponent({ } }; - // 处理行为气泡外部点击 - const handleOutClick = () => { - if (!processing.value) { - actionPop.value.visible = false; - actionPop.value.key = ''; - } - }; - onMounted(() => { - window.addEventListener('pointerup', handleOutClick); + window.addEventListener('click', closeActionPop); view?.evt.on('onDragTargetChange', handleDragTargetChange); }); onUnmounted(() => { - window.removeEventListener('pointerup', handleOutClick); + window.removeEventListener('click', closeActionPop); view?.evt.off('onDragTargetChange', handleDragTargetChange); reportDesignCtx?.off(handleMaterialChange); }); @@ -380,22 +431,22 @@ export default defineComponent({ ns, c, type, - caption, items, - dataItemProvider, + caption, + inputRef, actionPop, - editorValue, editorItem, - inputRef, isDragging, isRequired, + editorValue, allowDropState, - renderIcon, + dataItemProvider, handleAdd, - handleUpdate, - handleActionClick, + renderIcon, handleBlur, + handleUpdate, handleKeyDown, + handleActionClick, }; }, render() { @@ -503,6 +554,7 @@ export default defineComponent({ this.controller!.context, this.controller!.params, item, + this.data, ); return (
diff --git a/packages/bi-report-design/src/interface/i-bi-period-data.ts b/packages/bi-report-design/src/interface/i-bi-period-data.ts new file mode 100644 index 00000000..2033d380 --- /dev/null +++ b/packages/bi-report-design/src/interface/i-bi-period-data.ts @@ -0,0 +1,64 @@ +/* eslint-disable prettier/prettier */ +/** + * @description 同环比数据接口 + * @export + * @interface IBIPeriodData + */ +export interface IBIPeriodData { + /** + * @description 属性名 + * @type {string} + * @memberof IBIPeriodData + */ + field: string; + + /** + * @description 单位 + * @type {('DAY' | 'WEEK' | 'MONTH' | 'QUARTER' | 'YEAR')} + * @memberof IBIPeriodData + */ + unit: 'DAY' | 'WEEK' | 'MONTH' | 'QUARTER' | 'YEAR'; + + /** + * @description 类型 + * + * STATIC:需指定开始及结束时间(以秒为单位) + * + * DYNAMIC:相对于当前时间的前后偏移,(以当前选择的单位为单位) + * @type {('STATIC' | 'DYNAMIC')} + * @memberof IBIPeriodData + */ + type: 'STATIC' | 'DYNAMIC'; + + /** + * @description 起始时间 + * + * 静态类型以秒为单位,动态类型以选择的单位为单位 + * @type {number} + * @memberof IBIPeriodData + */ + start: number; + + /** + * @description 结束时间 + * + * 静态类型以秒为单位,动态类型以选择的单位为单位 + * @type {number} + * @memberof IBIPeriodData + */ + end: number; + + /** + * @description 环比次数,默认为1 + * @type {number} + * @memberof IBIPeriodData + */ + pop: number; + + /** + * @description 同比次数,默认为1 + * @type {number} + * @memberof IBIPeriodData + */ + yoy: number; +} diff --git a/packages/bi-report-design/src/interface/i-data-item-provider.ts b/packages/bi-report-design/src/interface/i-data-item-provider.ts index 0c9875d8..15abccbd 100644 --- a/packages/bi-report-design/src/interface/i-data-item-provider.ts +++ b/packages/bi-report-design/src/interface/i-data-item-provider.ts @@ -11,21 +11,21 @@ import { AppDataEntity } from '@ibiz-template/runtime'; */ export interface IDataItemProvider { /** - * 获取行为项 - * - * @author tony001 - * @date 2024-12-10 13:12:31 + * @description 获取行为项 * @param {string} type * @param {IContext} context * @param {IParams} params * @param {IData} data - * @return {*} {IActionItem[]} + * @param {IData} [report] + * @returns {*} {IActionItem[]} + * @memberof IDataItemProvider */ getActions( type: string, context: IContext, params: IParams, data: IData, + report?: IData, ): IActionItem[]; /** diff --git a/packages/bi-report-design/src/interface/index.ts b/packages/bi-report-design/src/interface/index.ts index a9106879..d2c30558 100644 --- a/packages/bi-report-design/src/interface/index.ts +++ b/packages/bi-report-design/src/interface/index.ts @@ -3,3 +3,4 @@ export type { IDataItemProvider } from './i-data-item-provider'; export type { IReportChartProvider } from './i-report-chart-provider'; export type { IReportChartController } from './i-report-chart-controller'; export type { IReportChartConverter } from './i-report-chart-converter'; +export type { IBIPeriodData } from './i-bi-period-data'; diff --git a/packages/bi-report-design/src/providers/data-item/data-item-provider.ts b/packages/bi-report-design/src/providers/data-item/data-item-provider.ts index 0f819d8d..715e8c14 100644 --- a/packages/bi-report-design/src/providers/data-item/data-item-provider.ts +++ b/packages/bi-report-design/src/providers/data-item/data-item-provider.ts @@ -35,6 +35,11 @@ export class DataItemProvider implements IDataItemProvider { * @type {IActionItem[]} */ protected actions: IActionItem[] = [ + { + type: 'EDIT', + tooltip: '设置显示名', + icon: './svg/edit.svg', + }, { type: 'REMOVE', tooltip: '删除', @@ -237,21 +242,21 @@ export class DataItemProvider implements IDataItemProvider { } /** - * 获取行为项 - * - * @author tony001 - * @date 2024-12-12 17:12:17 + * @description 获取行为项 * @param {string} type * @param {IContext} context * @param {IParams} params * @param {IData} data - * @return {*} {IActionItem[]} + * @param {IData} [report] + * @returns {*} {IActionItem[]} + * @memberof DataItemProvider */ getActions( type: string, context: IContext, params: IParams, data: IData, + report?: IData, ): IActionItem[] { return this.actions; } diff --git a/packages/bi-report-design/src/providers/data-item/dimension-col-provider.ts b/packages/bi-report-design/src/providers/data-item/dimension-col-provider.ts index cb4370e9..d62c4803 100644 --- a/packages/bi-report-design/src/providers/data-item/dimension-col-provider.ts +++ b/packages/bi-report-design/src/providers/data-item/dimension-col-provider.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { AppDataEntity } from '@ibiz-template/runtime'; import { RuntimeError } from '@ibiz-template/core'; +import { IActionItem } from '@ibiz-template-plugin/design-base'; import { DimensionProvider } from './dimension-provider'; export class DimensionColProvider extends DimensionProvider { @@ -103,4 +105,24 @@ export class DimensionColProvider extends DimensionProvider { throw new RuntimeError('删除维度列失败'); } } + + /** + * @description 获取行为项 + * @param {string} type + * @param {IContext} context + * @param {IParams} params + * @param {IData} data + * @param {IData} [report] + * @returns {*} {IActionItem[]} + * @memberof DimensionColProvider + */ + getActions( + type: string, + context: IContext, + params: IParams, + data: IData, + report?: IData, + ): IActionItem[] { + return this.actions; + } } diff --git a/packages/bi-report-design/src/providers/data-item/dimension-provider.ts b/packages/bi-report-design/src/providers/data-item/dimension-provider.ts index 297bd15f..104156ef 100644 --- a/packages/bi-report-design/src/providers/data-item/dimension-provider.ts +++ b/packages/bi-report-design/src/providers/data-item/dimension-provider.ts @@ -34,9 +34,11 @@ export class DimensionProvider extends DataItemProvider { pssysbicubedimensionid: data.pssysbicubedimensionid, pssysbicubedimensionname: data.pssysbicubedimensionname, pssysbireportitemname: data.pssysbicubedimensionname, + caption: data.pssysbicubedimensionname, codename: data.codename, birepitemtype: 'DIMENSION', validflag: 1, + sort: 'asc', }); if (res.ok && res.data) { return res.data as AppDataEntity; @@ -97,9 +99,7 @@ export class DimensionProvider extends DataItemProvider { const groupTags = params.group_tags.split(','); if (groupTags && groupTags.length > 0) { allDimensions.forEach(dimension => { - if (!groupTags.includes(dimension.pssysbireportitemid)) { - result.push(dimension); - } + if (!groupTags.includes(dimension.codename)) result.push(dimension); }); } } else { @@ -133,28 +133,32 @@ export class DimensionProvider extends DataItemProvider { } /** - * 获取行为项 - * - * @author tony001 - * @date 2024-12-12 19:12:06 + * @description 获取行为项 * @param {string} type * @param {IContext} context * @param {IParams} params * @param {IData} data - * @return {*} {IActionItem[]} + * @param {IData} [report] + * @returns {*} {IActionItem[]} + * @memberof DimensionProvider */ getActions( type: string, context: IContext, params: IParams, data: IData, + report?: IData, ): IActionItem[] { - const tempActions: IActionItem[] = clone(this.actions); - tempActions.unshift({ - type: 'EDIT', - tooltip: '设置显示名', - icon: './svg/edit.svg', - }); - return tempActions; + const actions: IActionItem[] = clone(this.actions); + if ( + report?.chart_type && + ['GRID', 'CROSSTABLE'].includes(report.chart_type) + ) + actions.unshift({ + type: 'SORT', + tooltip: data.sort !== 'desc' ? '降序' : '升序', + icon: `./svg/${data.sort !== 'desc' ? 'descending' : 'ascending'}.svg`, + }); + return actions; } } diff --git a/packages/bi-report-design/src/providers/data-item/group-provider.ts b/packages/bi-report-design/src/providers/data-item/group-provider.ts index 70016b03..e181583d 100644 --- a/packages/bi-report-design/src/providers/data-item/group-provider.ts +++ b/packages/bi-report-design/src/providers/data-item/group-provider.ts @@ -104,9 +104,7 @@ export class GroupProvider extends DimensionProvider { const groupTags = params.group_tags.split(','); if (groupTags && groupTags.length > 0) { allDimensions.forEach(dimension => { - if (groupTags.includes(dimension.pssysbireportitemid)) { - result.push(dimension); - } + if (groupTags.includes(dimension.codename)) result.push(dimension); }); } } diff --git a/packages/bi-report-design/src/providers/data-item/measure-provider.ts b/packages/bi-report-design/src/providers/data-item/measure-provider.ts index 42c6a6e2..f462cda4 100644 --- a/packages/bi-report-design/src/providers/data-item/measure-provider.ts +++ b/packages/bi-report-design/src/providers/data-item/measure-provider.ts @@ -2,8 +2,6 @@ /* eslint-disable no-await-in-loop */ import { AppDataEntity } from '@ibiz-template/runtime'; import { RuntimeError } from '@ibiz-template/core'; -import { IActionItem } from '@ibiz-template-plugin/design-base'; -import { clone } from 'ramda'; import { DataItemProvider } from './data-item-provider'; /** @@ -130,30 +128,4 @@ export class MeasureProvider extends DataItemProvider { ): Promise<{ ok: boolean; message?: string }> { return { ok: true }; } - - /** - * 获取行为项 - * - * @author tony001 - * @date 2024-12-12 17:12:40 - * @param {string} type - * @param {IContext} context - * @param {IParams} params - * @param {IData} data - * @return {*} {IActionItem[]} - */ - getActions( - type: string, - context: IContext, - params: IParams, - data: IData, - ): IActionItem[] { - const tempActions: IActionItem[] = clone(this.actions); - tempActions.unshift({ - type: 'EDIT', - tooltip: '设置显示名', - icon: './svg/edit.svg', - }); - return tempActions; - } } diff --git a/packages/bi-report-design/src/providers/data-item/period-provider.ts b/packages/bi-report-design/src/providers/data-item/period-provider.ts index 07a52bd0..2d7cff42 100644 --- a/packages/bi-report-design/src/providers/data-item/period-provider.ts +++ b/packages/bi-report-design/src/providers/data-item/period-provider.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { AppDataEntity } from '@ibiz-template/runtime'; import { createUUID } from 'qx-util'; +import { AppDataEntity } from '@ibiz-template/runtime'; +import { IActionItem } from '@ibiz-template-plugin/design-base'; import { DimensionProvider } from './dimension-provider'; /** @@ -37,6 +38,15 @@ export class PeriodProvider extends DimensionProvider { codename: data.codename, birepitemtype: 'DIMENSION', validflag: 1, + params: { + pop: 1, + yoy: 1, + end: 0, + start: -7, + unit: 'DAY', + type: 'DYNAMIC', + field: data.codename.toLowerCase(), + }, } as unknown as AppDataEntity; } @@ -121,20 +131,45 @@ export class PeriodProvider extends DimensionProvider { } /** - * 是否允许拖入 - * - * @author tony001 - * @date 2024-12-12 17:12:07 + * @description 是否允许拖入 * @param {IContext} context * @param {IParams} params * @param {IData} data - * @return {*} {Promise<{ ok: boolean; message?: string }>} + * @returns {*} {Promise<{ ok: boolean; message?: string }>} + * @memberof PeriodProvider */ async allowDragging( context: IContext, params: IParams, data: IData, ): Promise<{ ok: boolean; message?: string }> { - return { ok: true }; + if (data.datatype && ['DATE', 'TIME', 'DATETIME'].includes(data.datatype)) + return { ok: true }; + return { ok: false, message: '该维度不支持同环比' }; + } + + /** + * @description 获取行为项 + * @param {string} type + * @param {IContext} context + * @param {IParams} params + * @param {IData} data + * @param {IData} [report] + * @returns {*} {IActionItem[]} + * @memberof PeriodProvider + */ + getActions( + type: string, + context: IContext, + params: IParams, + data: IData, + report?: IData, + ): IActionItem[] { + const action = { + tooltip: '配置', + type: 'PERIOD_CONFIG', + icon: `./svg/config.svg`, + }; + return [action, ...this.actions]; } } diff --git a/packages/bi-report-design/src/utils/report-design-ctx.ts b/packages/bi-report-design/src/utils/report-design-ctx.ts index 7def3781..3471cffa 100644 --- a/packages/bi-report-design/src/utils/report-design-ctx.ts +++ b/packages/bi-report-design/src/utils/report-design-ctx.ts @@ -32,6 +32,13 @@ export class ReportDesignCtx { */ cubeDimensionItems: IData[] = []; + /** + * @description 立方体实体属性集合 + * @type {IData[]} + * @memberof ReportDesignCtx + */ + cubeDEFields: IData[] = []; + /** * 事件对象 * @@ -155,8 +162,57 @@ export class ReportDesignCtx { * @return {*} {Promise} */ protected async load(): Promise { + await this.loadDEFieldsByCube(); await this.loadCubeMeasure(); await this.loadCubeDimension(); + this.handleCubeData(); + } + + /** + * @description 通过立方体加载实体属性 + * @protected + * @returns {*} {Promise} + * @memberof ReportDesignCtx + */ + protected async loadDEFieldsByCube(): Promise { + try { + const app = ibiz.hub.getApp(this.view.model.appId); + const cubeRes = await app.deService.exec( + 'bireportdesign.pssysbicube', + 'get', + this.view.context, + ); + if (cubeRes.ok) { + const result = await app.deService.exec( + 'bireportdesign.psdefield', + 'fetchdefault', + { ...this.view.context, psdataentity: cubeRes.data.psdeid }, + ); + if (result.ok) this.cubeDEFields = result.data as IData[]; + } + } catch (error) { + ibiz.log.error(error); + } + } + + /** + * @description 处理立方体数据 + * @protected + * @memberof ReportDesignCtx + */ + protected handleCubeData(): void { + this.cubeMeasureItems.forEach(measure => { + const deField = this.cubeDEFields.find( + field => measure.psdefid === field.psdefieldid, + ); + measure.datatype = deField?.psdatatypeid; + }); + this.cubeDimensionItems.forEach(dimension => { + const deField = this.cubeDEFields.find( + field => dimension.psdefid === field.psdefieldid, + ); + dimension.datatype = deField?.psdatatypeid; + }); } /** diff --git a/packages/bi-report-design/src/utils/ui-field-mapping.ts b/packages/bi-report-design/src/utils/ui-field-mapping.ts index 1ebd445b..4d9efc42 100644 --- a/packages/bi-report-design/src/utils/ui-field-mapping.ts +++ b/packages/bi-report-design/src/utils/ui-field-mapping.ts @@ -175,6 +175,8 @@ export const UIStyleFieldMapping = { grid_agg_col_position: 'grid_agg_col_position', // 表格功能设置 grid_function_setting: 'grid_function_setting', + // 表格列排序 + grid_col_sort: 'grid_col_sort', }; // 界面数据属性集合 export const UIDataFields = [ diff --git a/packages/studio-theme/src/theme/studio-dark/editor.scss b/packages/studio-theme/src/theme/studio-dark/editor.scss index d73a1592..9540ca1b 100644 --- a/packages/studio-theme/src/theme/studio-dark/editor.scss +++ b/packages/studio-theme/src/theme/studio-dark/editor.scss @@ -65,4 +65,13 @@ background-color: getCssVar(color, fill, 2); } } + + // 日期选择编辑器 + .#{bem(date-range-select-date-range-select)} { + .#{bem(date-range-select,date-type,item-icon)} { + svg { + fill: getCssVar(color, primary, light-active); + } + } + } } -- Gitee