2025-12-21 19:28:31 +08:00

206 lines
5.2 KiB
TypeScript

import { Pool } from 'pg'
// 创建数据库连接池
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20, // 最大连接数
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
})
// 测试连接
pool.on('connect', () => {
console.log('✅ Database connected')
})
pool.on('error', (err) => {
console.error('❌ Unexpected database error:', err)
})
export default pool
// 用户接口
export interface User {
id: number
name: string
email: string
password: string
email_verified: boolean
created_at: Date
updated_at: Date
}
// 订单接口
export interface Order {
id: number
order_no: string
user_id: number
product_type: string // 'standard' | 'deployment' | 'custom'
product_name: string
amount: number
status: string // 'pending' | 'paid' | 'failed' | 'cancelled'
payment_method?: string
trade_no?: string
callback_data?: string
created_at: Date
updated_at: Date
paid_at?: Date
}
// 数据库查询函数
export const db = {
// 根据邮箱查找用户
async findUserByEmail(email: string): Promise<User | null> {
const result = await pool.query(
'SELECT * FROM users WHERE email = $1',
[email]
)
return result.rows[0] || null
},
// 根据ID查找用户
async findUserById(id: number): Promise<User | null> {
const result = await pool.query(
'SELECT * FROM users WHERE id = $1',
[id]
)
return result.rows[0] || null
},
// 创建新用户
async createUser(
name: string,
email: string,
password: string
): Promise<User> {
const result = await pool.query(
'INSERT INTO users (name, email, password, email_verified, created_at, updated_at) VALUES ($1, $2, $3, $4, NOW(), NOW()) RETURNING *',
[name, email, password, false]
)
return result.rows[0]
},
// 更新用户
async updateUser(id: number, data: Partial<User>): Promise<User> {
const fields = []
const values = []
let index = 1
if (data.name !== undefined) {
fields.push(`name = $${index++}`)
values.push(data.name)
}
if (data.email !== undefined) {
fields.push(`email = $${index++}`)
values.push(data.email)
}
if (data.password !== undefined) {
fields.push(`password = $${index++}`)
values.push(data.password)
}
if (data.email_verified !== undefined) {
fields.push(`email_verified = $${index++}`)
values.push(data.email_verified)
}
fields.push(`updated_at = NOW()`)
values.push(id)
const query = `UPDATE users SET ${fields.join(', ')} WHERE id = $${index} RETURNING *`
const result = await pool.query(query, values)
return result.rows[0]
},
// 删除用户
async deleteUser(id: number): Promise<boolean> {
const result = await pool.query('DELETE FROM users WHERE id = $1', [id])
return (result.rowCount ?? 0) > 0
},
// 获取所有用户(用于管理)
async getAllUsers(): Promise<User[]> {
const result = await pool.query(
'SELECT id, name, email, email_verified, created_at FROM users ORDER BY created_at DESC'
)
return result.rows
},
// ========== 订单相关操作 ==========
// 创建订单
async createOrder(
orderNo: string,
userId: number,
productType: string,
productName: string,
amount: number
): Promise<Order> {
const result = await pool.query(
'INSERT INTO orders (order_no, user_id, product_type, product_name, amount, status, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW()) RETURNING *',
[orderNo, userId, productType, productName, amount, 'pending']
)
return result.rows[0]
},
// 根据订单号查找订单
async findOrderByOrderNo(orderNo: string): Promise<Order | null> {
const result = await pool.query(
'SELECT * FROM orders WHERE order_no = $1',
[orderNo]
)
return result.rows[0] || null
},
// 根据ID查找订单
async findOrderById(id: number): Promise<Order | null> {
const result = await pool.query(
'SELECT * FROM orders WHERE id = $1',
[id]
)
return result.rows[0] || null
},
// 更新订单状态
async updateOrderStatus(
orderNo: string,
status: string,
tradeNo?: string,
paymentMethod?: string,
callbackData?: string
): Promise<Order> {
const updates = ['status = $2', 'updated_at = NOW()']
const values: any[] = [orderNo, status]
let index = 3
if (tradeNo) {
updates.push(`trade_no = $${index++}`)
values.push(tradeNo)
}
if (paymentMethod) {
updates.push(`payment_method = $${index++}`)
values.push(paymentMethod)
}
if (callbackData) {
updates.push(`callback_data = $${index++}`)
values.push(callbackData)
}
if (status === 'paid') {
updates.push('paid_at = NOW()')
}
const query = `UPDATE orders SET ${updates.join(', ')} WHERE order_no = $1 RETURNING *`
const result = await pool.query(query, values)
return result.rows[0]
},
// 获取用户的订单列表
async getUserOrders(userId: number): Promise<Order[]> {
const result = await pool.query(
'SELECT * FROM orders WHERE user_id = $1 ORDER BY created_at DESC',
[userId]
)
return result.rows
},
}