fix: 修复 Doris 数据库建表语法兼容性问题
核心问题:数据库为 Apache Doris 而非标准 MySQL,建表语法完全不同 关键修改: 1. 去除所有 MySQL 特有语法(ENGINE、DEFAULT、IF NOT EXISTS) 2. 使用 Doris 必需语法:DISTRIBUTED BY HASH + PROPERTIES 3. 所有 NULL/NOT NULL 和 DEFAULT 值重新适配 4. 修复四个文件的建表语句: - config/route.ts(配置表) - report/history/route.ts(历史表) - report-generator.ts(生成器) - init-tables.ts(初始化脚本) 测试结果: ✅ 配置创建 API 测试通过(HTTP 200) ✅ 所有静态检查通过 ✅ Doris 建表语法完全兼容 Coze-Commit-Type: user Coze-User-ID: 3722323274763196 Coze-Conversation-ID: 9894087
This commit is contained in:
BIN
assets/image.png
Normal file
BIN
assets/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
@@ -69,18 +69,53 @@ export async function POST(request: NextRequest) {
|
||||
// 获取连接
|
||||
const connection = await pool.getConnection();
|
||||
|
||||
// 尝试创建表(如果已存在会失败,但不影响后续操作)
|
||||
try {
|
||||
await connection.query(`
|
||||
CREATE TABLE t_daily_report_config (
|
||||
id BIGINT NOT NULL COMMENT '配置ID',
|
||||
config_name VARCHAR(100) NOT NULL COMMENT '配置名称',
|
||||
split_type VARCHAR(20) NOT NULL COMMENT '拆分方式',
|
||||
split_value VARCHAR(100) NOT NULL COMMENT '拆分值',
|
||||
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
|
||||
selected_fields VARCHAR(3000) NOT NULL COMMENT '选择的字段列表',
|
||||
sum_fields VARCHAR(3000) NULL COMMENT '求和字段列表',
|
||||
create_time DATETIME NULL COMMENT '创建时间',
|
||||
update_time DATETIME NULL COMMENT '更新时间',
|
||||
is_active TINYINT NULL COMMENT '是否启用'
|
||||
)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES("replication_num" = "1")
|
||||
`);
|
||||
console.log('配置表创建成功');
|
||||
} catch (tableError: any) {
|
||||
// 如果表已存在,忽略错误
|
||||
if (tableError.message && tableError.message.includes('already exists')) {
|
||||
console.log('配置表已存在');
|
||||
} else {
|
||||
console.error('创建表失败:', tableError);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成ID(使用时间戳)
|
||||
const id = Date.now();
|
||||
const now = new Date();
|
||||
|
||||
// 插入配置
|
||||
await connection.query(
|
||||
`INSERT INTO t_daily_report_config
|
||||
(config_name, split_type, split_value, split_name, selected_fields, sum_fields)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||
(id, config_name, split_type, split_value, split_name, selected_fields, sum_fields, create_time, update_time, is_active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1)`,
|
||||
[
|
||||
id,
|
||||
config_name,
|
||||
split_type,
|
||||
split_value,
|
||||
split_name || null,
|
||||
JSON.stringify(selected_fields),
|
||||
sum_fields ? JSON.stringify(sum_fields) : null
|
||||
sum_fields ? JSON.stringify(sum_fields) : null,
|
||||
now,
|
||||
now
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -10,6 +10,39 @@ export async function GET(request: NextRequest) {
|
||||
const splitType = searchParams.get('splitType');
|
||||
const reportDate = searchParams.get('reportDate');
|
||||
|
||||
// 获取连接并确保表存在
|
||||
const connection = await pool.getConnection();
|
||||
try {
|
||||
await connection.query(`
|
||||
CREATE TABLE t_daily_report_history (
|
||||
id BIGINT NOT NULL COMMENT '记录ID',
|
||||
report_date DATE NOT NULL COMMENT '报表日期',
|
||||
start_time DATETIME NOT NULL COMMENT '报表开始时间',
|
||||
end_time DATETIME NOT NULL COMMENT '报表结束时间',
|
||||
split_type VARCHAR(20) NOT NULL COMMENT '拆分方式',
|
||||
split_value VARCHAR(100) NOT NULL COMMENT '拆分值',
|
||||
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
|
||||
config_id BIGINT NULL COMMENT '使用的配置ID',
|
||||
total_orders INT NULL COMMENT '订单总数',
|
||||
total_amount DECIMALV3 NULL COMMENT '总金额',
|
||||
sum_results VARCHAR(3000) NULL COMMENT '求和结果',
|
||||
file_path VARCHAR(500) NULL COMMENT '生成的文件路径',
|
||||
create_time DATETIME NULL COMMENT '生成时间',
|
||||
status TINYINT NULL COMMENT '状态'
|
||||
)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES("replication_num" = "1")
|
||||
`);
|
||||
console.log('历史表创建成功');
|
||||
} catch (tableError: any) {
|
||||
if (tableError.message && tableError.message.includes('already exists')) {
|
||||
console.log('历史表已存在');
|
||||
} else {
|
||||
console.error('创建历史表失败:', tableError);
|
||||
}
|
||||
}
|
||||
connection.release();
|
||||
|
||||
// 构建查询条件
|
||||
let whereClause = 'WHERE 1=1';
|
||||
const queryParams: any[] = [];
|
||||
|
||||
@@ -1,38 +1,40 @@
|
||||
import pool from './db';
|
||||
|
||||
// 创建配置表和历史表的SQL语句
|
||||
// 创建配置表和历史表的SQL语句(Doris兼容)
|
||||
const createTablesSQL = `
|
||||
-- 日报配置表(用户字段选择配置)
|
||||
CREATE TABLE IF NOT EXISTS t_daily_report_config (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '配置ID',
|
||||
CREATE TABLE t_daily_report_config (
|
||||
id BIGINT NOT NULL COMMENT '配置ID',
|
||||
config_name VARCHAR(100) NOT NULL COMMENT '配置名称',
|
||||
split_type VARCHAR(20) NOT NULL COMMENT '拆分方式:company_id 或 user_id',
|
||||
split_value VARCHAR(100) NOT NULL COMMENT '拆分值(企业ID或用户ID)',
|
||||
split_name VARCHAR(200) COMMENT '拆分显示名称(企业名称或用户姓名)',
|
||||
selected_fields JSON NOT NULL COMMENT '用户选择的字段列表(JSON数组)',
|
||||
sum_fields JSON COMMENT '需要求和的字段列表(JSON数组)',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
is_active TINYINT DEFAULT 1 COMMENT '是否启用:0禁用 1启用'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='日报字段配置表';
|
||||
split_name VARCHAR(200) NULL COMMENT '拆分显示名称(企业名称或用户姓名)',
|
||||
selected_fields VARCHAR(3000) NOT NULL COMMENT '用户选择的字段列表(JSON字符串)',
|
||||
sum_fields VARCHAR(3000) NULL COMMENT '需要求和的字段列表(JSON字符串)',
|
||||
create_time DATETIME NULL COMMENT '创建时间',
|
||||
update_time DATETIME NULL COMMENT '更新时间',
|
||||
is_active TINYINT NULL COMMENT '是否启用:0禁用 1启用'
|
||||
)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES("replication_num" = "1");
|
||||
|
||||
-- 日报生成历史记录表
|
||||
CREATE TABLE IF NOT EXISTS t_daily_report_history (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '记录ID',
|
||||
CREATE TABLE t_daily_report_history (
|
||||
id BIGINT NOT NULL COMMENT '记录ID',
|
||||
report_date DATE NOT NULL COMMENT '报表日期',
|
||||
start_time DATETIME NOT NULL COMMENT '报表开始时间',
|
||||
end_time DATETIME NOT NULL COMMENT '报表结束时间',
|
||||
split_type VARCHAR(20) NOT NULL COMMENT '拆分方式:company_id 或 user_id',
|
||||
split_value VARCHAR(100) NOT NULL COMMENT '拆分值(企业ID或用户ID)',
|
||||
split_name VARCHAR(200) COMMENT '拆分显示名称',
|
||||
config_id BIGINT COMMENT '使用的配置ID',
|
||||
total_orders INT DEFAULT 0 COMMENT '订单总数',
|
||||
total_amount DECIMAL(15,2) DEFAULT 0 COMMENT '总金额',
|
||||
sum_results JSON COMMENT '求和结果(JSON对象)',
|
||||
file_path VARCHAR(500) COMMENT '生成的文件路径',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '生成时间',
|
||||
status TINYINT DEFAULT 1 COMMENT '状态:0失败 1成功'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='日报生成历史表';
|
||||
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
|
||||
config_id BIGINT NULL COMMENT '使用的配置ID',
|
||||
total_orders INT NULL COMMENT '订单总数',
|
||||
total_amount DECIMALV3 NULL COMMENT '总金额',
|
||||
sum_results VARCHAR(3000) NULL COMMENT '求和结果(JSON字符串)',
|
||||
file_path VARCHAR(500) NULL COMMENT '生成的文件路径',
|
||||
create_time DATETIME NULL COMMENT '生成时间',
|
||||
status TINYINT NULL COMMENT '状态:0失败 1成功'
|
||||
)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES("replication_num" = "1");
|
||||
`;
|
||||
|
||||
// 初始化数据库表
|
||||
@@ -49,10 +51,10 @@ export async function initDatabaseTables(): Promise<void> {
|
||||
}
|
||||
|
||||
connection.release();
|
||||
console.log('数据库表初始化成功');
|
||||
console.log('数据库表初始化成功(Doris兼容语法)');
|
||||
console.log('创建了以下表:');
|
||||
console.log('1. t_daily_report_config - 日报字段配置表(包含拆分值和显示名称)');
|
||||
console.log('2. t_daily_report_history - 日报生成历史表(包含求和结果)');
|
||||
console.log('1. t_daily_report_config - 日报字段配置表');
|
||||
console.log('2. t_daily_report_history - 日报生成历史表');
|
||||
} catch (error) {
|
||||
console.error('数据库表初始化失败:', error);
|
||||
throw error;
|
||||
|
||||
@@ -224,12 +224,47 @@ export async function generateBatchReports(configId: number): Promise<ReportResu
|
||||
// 保存到历史记录表
|
||||
const connection2 = await pool.getConnection();
|
||||
|
||||
// 确保历史表存在
|
||||
try {
|
||||
await connection2.query(`
|
||||
CREATE TABLE t_daily_report_history (
|
||||
id BIGINT NOT NULL COMMENT '记录ID',
|
||||
report_date DATE NOT NULL COMMENT '报表日期',
|
||||
start_time DATETIME NOT NULL COMMENT '报表开始时间',
|
||||
end_time DATETIME NOT NULL COMMENT '报表结束时间',
|
||||
split_type VARCHAR(20) NOT NULL COMMENT '拆分方式',
|
||||
split_value VARCHAR(100) NOT NULL COMMENT '拆分值',
|
||||
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
|
||||
config_id BIGINT NULL COMMENT '使用的配置ID',
|
||||
total_orders INT NULL COMMENT '订单总数',
|
||||
total_amount DECIMALV3 NULL COMMENT '总金额',
|
||||
sum_results VARCHAR(3000) NULL COMMENT '求和结果',
|
||||
file_path VARCHAR(500) NULL COMMENT '生成的文件路径',
|
||||
create_time DATETIME NULL COMMENT '生成时间',
|
||||
status TINYINT NULL COMMENT '状态'
|
||||
)
|
||||
DISTRIBUTED BY HASH(id) BUCKETS 1
|
||||
PROPERTIES("replication_num" = "1")
|
||||
`);
|
||||
console.log('历史表创建成功');
|
||||
} catch (tableError: any) {
|
||||
if (tableError.message && tableError.message.includes('already exists')) {
|
||||
console.log('历史表已存在');
|
||||
} else {
|
||||
console.error('创建历史表失败:', tableError);
|
||||
}
|
||||
}
|
||||
|
||||
const historyId = Date.now();
|
||||
const now = new Date();
|
||||
|
||||
if (result.success) {
|
||||
await connection2.query(
|
||||
`INSERT INTO t_daily_report_history
|
||||
(report_date, start_time, end_time, split_type, split_value, split_name, config_id, total_orders, total_amount, sum_results, file_path, status)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
(id, report_date, start_time, end_time, split_type, split_value, split_name, config_id, total_orders, total_amount, sum_results, file_path, create_time, status)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
historyId,
|
||||
result.reportDate,
|
||||
result.startTime,
|
||||
result.endTime,
|
||||
@@ -241,15 +276,17 @@ export async function generateBatchReports(configId: number): Promise<ReportResu
|
||||
result.totalAmount,
|
||||
result.sumResults ? JSON.stringify(result.sumResults) : null,
|
||||
result.filePath || null,
|
||||
now,
|
||||
1
|
||||
]
|
||||
);
|
||||
} else {
|
||||
await connection2.query(
|
||||
`INSERT INTO t_daily_report_history
|
||||
(report_date, start_time, end_time, split_type, split_value, split_name, config_id, total_orders, total_amount, status)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
(id, report_date, start_time, end_time, split_type, split_value, split_name, config_id, total_orders, total_amount, create_time, status)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
historyId,
|
||||
result.reportDate,
|
||||
result.startTime,
|
||||
result.endTime,
|
||||
|
||||
Reference in New Issue
Block a user