diff --git a/.agents/skills/grill-me/SKILL.md b/.agents/skills/grill-me/SKILL.md new file mode 100644 index 0000000..9470cfc --- /dev/null +++ b/.agents/skills/grill-me/SKILL.md @@ -0,0 +1,7 @@ +--- +name: grill-me +description: A relentless interview to sharpen a plan or design. +disable-model-invocation: true +--- + +Run a `/grilling` session. diff --git a/.claude/skills/grill-me/SKILL.md b/.claude/skills/grill-me/SKILL.md new file mode 100644 index 0000000..9470cfc --- /dev/null +++ b/.claude/skills/grill-me/SKILL.md @@ -0,0 +1,7 @@ +--- +name: grill-me +description: A relentless interview to sharpen a plan or design. +disable-model-invocation: true +--- + +Run a `/grilling` session. diff --git a/public/login-bg.jpg b/public/login-bg.jpg deleted file mode 100644 index 2aa303a..0000000 Binary files a/public/login-bg.jpg and /dev/null differ diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 0000000..552ae58 --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,11 @@ +{ + "version": 1, + "skills": { + "grill-me": { + "source": "mattpocock/skills", + "sourceType": "github", + "skillPath": "skills/productivity/grill-me/SKILL.md", + "computedHash": "67e31b63e6e9e454cc2f51cd85b9cf1396ee46379a87c07a1450f33c47c1276a" + } + } +} diff --git a/src/api/report-engine/report/index.ts b/src/api/report-engine/report/index.ts new file mode 100644 index 0000000..ab7ad34 --- /dev/null +++ b/src/api/report-engine/report/index.ts @@ -0,0 +1,234 @@ +import request from '/@/utils/request'; + +/** 字段定义 */ +export interface FieldDefine { + id?: number | string; + fieldCode: string; + fieldName: string; + fieldType: 'STRING' | 'INT' | 'FLOAT' | 'BIGINT' | 'DECIMAL' | 'DATE' | 'DATETIME' | 'BOOLEAN'; + dataType?: string; + fieldRole: 'DIMENSION' | 'INDICATOR'; + isAggregatable?: boolean; + isFilterable?: boolean; + isQueryable?: boolean; + isSortable?: boolean; + defaultAggregate?: string; + groupName?: string; + sortOrder: number; + unit?: string; + expression?: string; + status?: string; + validAggregates?: string[]; +} + +/** 报表+字段保存请求参数 */ +export interface ReportWithFieldsData { + businessCode: string; + reportCode: string; + reportName: string; + description?: string; + status?: string; + statTableName: string; + statTableComment?: string; + dateField?: string; + primaryKeys?: string[]; + conflictKeys?: string[]; + fields: FieldDefine[]; +} + +export interface ExtractConfigSaveData { + id?: number; + businessCode: string; + reportCode: string; + extractCode: string; + extractName: string; + sourceTableName: string; + sourceTableAlias?: string; + targetTableName: string; + isEnabled: boolean; + extractType: string; + extractMode: string; + extractKeyField?: string; + batchSize?: number; + status?: string; + groupByFields?: string[]; + filterExpression?: string; + operator?: string; +} + +// --- 业务 Business --- + +export function listBusinesses() { + return request({ + url: '/data-engine/report/businesses', + method: 'get', + }); +} + +export function getBusiness(id: number) { + return request({ + url: '/data-engine/report/business', + method: 'get', + params: { id }, + }); +} + +export function saveBusiness(data: { id?: number; businessCode: string; businessName: string }) { + return request({ + url: '/data-engine/report/business/save', + method: 'post', + data, + }); +} + +export function deleteBusiness(id: number) { + return request({ + url: '/data-engine/report/business', + method: 'delete', + params: { id }, + }); +} + +// --- 报表 Report --- + +export function listReports(businessCode: string, pageNum: number, pageSize: number, reportName?: string) { + const params: any = { businessCode, pageNum, pageSize }; + if (reportName) params.reportName = reportName; + return request({ + url: '/data-engine/report/reports', + method: 'get', + params, + }); +} + +export function getReport(id: number) { + return request({ + url: '/data-engine/report/report', + method: 'get', + params: { id }, + }); +} + +export function saveReport(data: { + businessCode: string; + reportCode: string; + reportName: string; + description?: string; + status?: string; + statTableName: string; + statTableComment?: string; + dateField?: string; + primaryKeys?: string[]; + conflictKeys?: string[]; +}) { + return request({ + url: '/data-engine/report/report/save', + method: 'post', + data, + }); +} + +/** 保存报表及字段(新建 / 编辑统一入口,全量替换字段) */ +export function saveReportWithFields(data: ReportWithFieldsData) { + return request({ + url: '/data-engine/report/report/saveWithFields', + method: 'post', + data, + }); +} + +export function deleteReport(id: number) { + return request({ + url: '/data-engine/report/report', + method: 'delete', + params: { id }, + }); +} + +/** 获取某业务下所有报表(不分页,供下拉选择) */ +export function listAllReports(businessCode: string) { + return request({ + url: '/data-engine/report/reports', + method: 'get', + params: { businessCode, pageNum: 1, pageSize: 9999 }, + }); +} + +// --- 查询相关类型 --- + +export interface ReportFilter { + fieldCode: string; + operator: string; + value: string; +} + +export interface ReportIndicator { + fieldCode: string; + aggregate: string; + alias: string; +} + +export interface ReportOrderBy { + fieldCode: string; + direction: 'ASC' | 'DESC'; +} + +export interface ReportQueryParams { + businessCode: string; + reportCode: string; + dimensions: string[]; + indicators: ReportIndicator[]; + filters: ReportFilter[]; + timeRange: { + startDate: string; + endDate: string; + }; + timeGroup: string; + orderBy: ReportOrderBy[]; + page: number; + pageSize: number; +} + +/** 数据查询 */ +export function reportQuery(data: ReportQueryParams) { + return request({ + url: '/data-engine/report/query', + method: 'post', + data, + }); +} + +/** 按天回刷(支持单天或日期范围) */ +export function execDailyBackfill(data: { businessCode: string; reportCode: string; startDate: string; endDate: string }) { + return request({ + url: '/data-engine/report/backfill', + method: 'post', + data, + }); +} + +// --- 抽取配置 ExtractConfig --- + +export function getExtractConfig(id: number) { + return request({ + url: '/data-engine/report/extractConfig', + method: 'get', + params: { id }, + }); +} + +export function saveExtractConfig(data: Record) { + return request({ + url: '/data-engine/report/extractConfig/save', + method: 'post', + data, + }); +} + +export function deleteExtractConfig(id: number) { + return request({ + url: '/data-engine/report/extractConfig', + method: 'delete', + params: { id }, + }); +} diff --git a/src/views/report-engine/query/index.vue b/src/views/report-engine/query/index.vue new file mode 100644 index 0000000..e1ffb9f --- /dev/null +++ b/src/views/report-engine/query/index.vue @@ -0,0 +1,627 @@ + + + + + + + diff --git a/src/views/report-engine/report/components/BusinessManager.vue b/src/views/report-engine/report/components/BusinessManager.vue new file mode 100644 index 0000000..a1fc772 --- /dev/null +++ b/src/views/report-engine/report/components/BusinessManager.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/src/views/report-engine/report/components/ExtractConfigForm.vue b/src/views/report-engine/report/components/ExtractConfigForm.vue new file mode 100644 index 0000000..2790f87 --- /dev/null +++ b/src/views/report-engine/report/components/ExtractConfigForm.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/src/views/report-engine/report/components/FieldEditor.vue b/src/views/report-engine/report/components/FieldEditor.vue new file mode 100644 index 0000000..25074b2 --- /dev/null +++ b/src/views/report-engine/report/components/FieldEditor.vue @@ -0,0 +1,398 @@ + + + + + + + diff --git a/src/views/report-engine/report/components/ReportForm.vue b/src/views/report-engine/report/components/ReportForm.vue new file mode 100644 index 0000000..ab7047e --- /dev/null +++ b/src/views/report-engine/report/components/ReportForm.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/src/views/report-engine/report/index.vue b/src/views/report-engine/report/index.vue new file mode 100644 index 0000000..5611f85 --- /dev/null +++ b/src/views/report-engine/report/index.vue @@ -0,0 +1,520 @@ + + + + + + +