更新服务器信息为新的 IP 地址,调整相关文档和代码中的默认配置,确保部署和连接的一致性。同时,优化订单管理界面,增强商品信息的格式化逻辑,提升用户体验。
This commit is contained in:
338
scripts/test-referral-flow.js
Normal file
338
scripts/test-referral-flow.js
Normal file
@@ -0,0 +1,338 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 新分销逻辑功能测试脚本
|
||||
*
|
||||
* 测试场景:
|
||||
* 1. A 推荐 B(新绑定)
|
||||
* 2. B 点击 C 的链接(立即切换)
|
||||
* 3. B 购买商品(分佣给 C)
|
||||
* 4. B 再次购买(累加佣金)
|
||||
* 5. 模拟过期解绑
|
||||
*/
|
||||
|
||||
const mysql = require('mysql2/promise')
|
||||
require('dotenv').config()
|
||||
|
||||
const DB_CONFIG = {
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
port: parseInt(process.env.DB_PORT) || 3306,
|
||||
user: process.env.DB_USER || 'root',
|
||||
password: process.env.DB_PASSWORD || '',
|
||||
database: process.env.DB_NAME || 'mycontent_db',
|
||||
}
|
||||
|
||||
// 测试数据
|
||||
const TEST_USERS = {
|
||||
A: { id: 'test_user_a', nickname: '推荐人A', referral_code: 'TESTA001' },
|
||||
B: { id: 'test_user_b', nickname: '购买者B', referral_code: 'TESTB001' },
|
||||
C: { id: 'test_user_c', nickname: '推荐人C', referral_code: 'TESTC001' },
|
||||
}
|
||||
|
||||
async function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
async function testFlow() {
|
||||
console.log('=' .repeat(60))
|
||||
console.log('新分销逻辑 - 功能测试')
|
||||
console.log('=' .repeat(60))
|
||||
console.log()
|
||||
|
||||
let connection
|
||||
|
||||
try {
|
||||
// 连接数据库
|
||||
connection = await mysql.createConnection(DB_CONFIG)
|
||||
console.log('✅ 已连接到数据库')
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤1: 清理旧数据
|
||||
// ========================================
|
||||
console.log('步骤 1: 清理测试数据...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
await connection.execute(
|
||||
`DELETE FROM referral_bindings WHERE referee_id IN (?, ?, ?)`,
|
||||
[TEST_USERS.A.id, TEST_USERS.B.id, TEST_USERS.C.id]
|
||||
)
|
||||
|
||||
await connection.execute(
|
||||
`DELETE FROM users WHERE id IN (?, ?, ?)`,
|
||||
[TEST_USERS.A.id, TEST_USERS.B.id, TEST_USERS.C.id]
|
||||
)
|
||||
|
||||
console.log('✅ 测试数据已清理')
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤2: 创建测试用户
|
||||
// ========================================
|
||||
console.log('步骤 2: 创建测试用户...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
for (const user of Object.values(TEST_USERS)) {
|
||||
await connection.execute(
|
||||
`INSERT INTO users (id, nickname, referral_code, phone, created_at)
|
||||
VALUES (?, ?, ?, ?, NOW())`,
|
||||
[user.id, user.nickname, user.referral_code, `138${Math.random().toString().slice(2, 10)}`]
|
||||
)
|
||||
console.log(` ✓ ${user.nickname} (${user.id})`)
|
||||
}
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤3: A 推荐 B(新绑定)
|
||||
// ========================================
|
||||
console.log('步骤 3: A 推荐 B(新绑定)...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
await connection.execute(
|
||||
`INSERT INTO referral_bindings
|
||||
(id, referee_id, referrer_id, referral_code, status, binding_date, expiry_date)
|
||||
VALUES (?, ?, ?, ?, 'active', NOW(), DATE_ADD(NOW(), INTERVAL 30 DAY))`,
|
||||
['bind_test_1', TEST_USERS.B.id, TEST_USERS.A.id, TEST_USERS.A.referral_code]
|
||||
)
|
||||
|
||||
console.log(` ✓ B 绑定到 A(过期时间:30天后)`)
|
||||
console.log()
|
||||
|
||||
await sleep(500)
|
||||
|
||||
// 查询当前绑定
|
||||
const [bindings1] = await connection.execute(
|
||||
`SELECT * FROM referral_bindings WHERE referee_id = ?`,
|
||||
[TEST_USERS.B.id]
|
||||
)
|
||||
|
||||
console.log(' 当前绑定关系:')
|
||||
bindings1.forEach(b => {
|
||||
console.log(` - 推荐人: ${b.referrer_id}, 状态: ${b.status}`)
|
||||
})
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤4: B 点击 C 的链接(立即切换)
|
||||
// ========================================
|
||||
console.log('步骤 4: B 点击 C 的链接(立即切换)...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
// 标记旧绑定为 cancelled
|
||||
await connection.execute(
|
||||
`UPDATE referral_bindings SET status = 'cancelled' WHERE id = ?`,
|
||||
['bind_test_1']
|
||||
)
|
||||
|
||||
// 创建新绑定
|
||||
await connection.execute(
|
||||
`INSERT INTO referral_bindings
|
||||
(id, referee_id, referrer_id, referral_code, status, binding_date, expiry_date)
|
||||
VALUES (?, ?, ?, ?, 'active', NOW(), DATE_ADD(NOW(), INTERVAL 30 DAY))`,
|
||||
['bind_test_2', TEST_USERS.B.id, TEST_USERS.C.id, TEST_USERS.C.referral_code]
|
||||
)
|
||||
|
||||
console.log(` ✓ B 的推荐人从 A 切换到 C`)
|
||||
console.log()
|
||||
|
||||
await sleep(500)
|
||||
|
||||
// 查询绑定历史
|
||||
const [bindings2] = await connection.execute(
|
||||
`SELECT * FROM referral_bindings WHERE referee_id = ? ORDER BY binding_date DESC`,
|
||||
[TEST_USERS.B.id]
|
||||
)
|
||||
|
||||
console.log(' 绑定历史:')
|
||||
bindings2.forEach((b, i) => {
|
||||
console.log(` ${i + 1}. 推荐人: ${b.referrer_id}, 状态: ${b.status}, 时间: ${b.binding_date.toLocaleString('zh-CN')}`)
|
||||
})
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤5: B 购买商品(分佣给 C)
|
||||
// ========================================
|
||||
console.log('步骤 5: B 购买商品(分佣给 C)...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
const purchaseAmount = 1.0
|
||||
const commission = Math.round(purchaseAmount * 0.9 * 100) / 100 // 90%
|
||||
|
||||
// 更新 C 的收益
|
||||
await connection.execute(
|
||||
`UPDATE users SET pending_earnings = pending_earnings + ? WHERE id = ?`,
|
||||
[commission, TEST_USERS.C.id]
|
||||
)
|
||||
|
||||
// 更新绑定记录(累加购买次数)
|
||||
await connection.execute(
|
||||
`UPDATE referral_bindings
|
||||
SET purchase_count = purchase_count + 1,
|
||||
total_commission = total_commission + ?,
|
||||
last_purchase_date = NOW()
|
||||
WHERE id = ?`,
|
||||
[commission, 'bind_test_2']
|
||||
)
|
||||
|
||||
console.log(` ✓ B 购买 ¥${purchaseAmount},C 获得佣金 ¥${commission}`)
|
||||
console.log()
|
||||
|
||||
await sleep(500)
|
||||
|
||||
// 查询分佣结果
|
||||
const [earnings1] = await connection.execute(
|
||||
`SELECT rb.*, u.pending_earnings
|
||||
FROM referral_bindings rb
|
||||
JOIN users u ON rb.referrer_id = u.id
|
||||
WHERE rb.id = ?`,
|
||||
['bind_test_2']
|
||||
)
|
||||
|
||||
if (earnings1.length > 0) {
|
||||
const e = earnings1[0]
|
||||
console.log(' 分佣结果:')
|
||||
console.log(` - 购买次数: ${e.purchase_count}`)
|
||||
console.log(` - 累计佣金: ¥${e.total_commission.toFixed(2)}`)
|
||||
console.log(` - C 的待提现: ¥${e.pending_earnings.toFixed(2)}`)
|
||||
}
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤6: B 再次购买(累加)
|
||||
// ========================================
|
||||
console.log('步骤 6: B 再次购买(累加佣金)...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
// 第二次购买
|
||||
await connection.execute(
|
||||
`UPDATE users SET pending_earnings = pending_earnings + ? WHERE id = ?`,
|
||||
[commission, TEST_USERS.C.id]
|
||||
)
|
||||
|
||||
await connection.execute(
|
||||
`UPDATE referral_bindings
|
||||
SET purchase_count = purchase_count + 1,
|
||||
total_commission = total_commission + ?,
|
||||
last_purchase_date = NOW()
|
||||
WHERE id = ?`,
|
||||
[commission, 'bind_test_2']
|
||||
)
|
||||
|
||||
console.log(` ✓ B 再次购买 ¥${purchaseAmount},C 再获得 ¥${commission}`)
|
||||
console.log()
|
||||
|
||||
await sleep(500)
|
||||
|
||||
// 查询累加结果
|
||||
const [earnings2] = await connection.execute(
|
||||
`SELECT rb.*, u.pending_earnings
|
||||
FROM referral_bindings rb
|
||||
JOIN users u ON rb.referrer_id = u.id
|
||||
WHERE rb.id = ?`,
|
||||
['bind_test_2']
|
||||
)
|
||||
|
||||
if (earnings2.length > 0) {
|
||||
const e = earnings2[0]
|
||||
console.log(' 累加结果:')
|
||||
console.log(` - 购买次数: ${e.purchase_count} ✅`)
|
||||
console.log(` - 累计佣金: ¥${e.total_commission.toFixed(2)} ✅`)
|
||||
console.log(` - C 的待提现: ¥${e.pending_earnings.toFixed(2)} ✅`)
|
||||
}
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 步骤7: 模拟过期解绑
|
||||
// ========================================
|
||||
console.log('步骤 7: 模拟过期解绑(修改过期时间)...')
|
||||
console.log('-' .repeat(60))
|
||||
|
||||
// 创建一个无购买的绑定
|
||||
await connection.execute(
|
||||
`INSERT INTO referral_bindings
|
||||
(id, referee_id, referrer_id, referral_code, status, binding_date, expiry_date, purchase_count)
|
||||
VALUES (?, ?, ?, ?, 'active', NOW(), '2026-02-01', 0)`,
|
||||
['bind_test_3', 'test_user_d', TEST_USERS.A.id, TEST_USERS.A.referral_code]
|
||||
)
|
||||
|
||||
console.log(` ✓ 创建一个已过期且无购买的绑定(test_user_d -> A)`)
|
||||
console.log()
|
||||
|
||||
// 查询过期记录
|
||||
const [expired] = await connection.execute(
|
||||
`SELECT * FROM referral_bindings
|
||||
WHERE status = 'active' AND expiry_date < NOW() AND purchase_count = 0`
|
||||
)
|
||||
|
||||
console.log(` 找到 ${expired.length} 条需要解绑的记录`)
|
||||
|
||||
if (expired.length > 0) {
|
||||
// 执行解绑
|
||||
const ids = expired.map(e => e.id)
|
||||
const placeholders = ids.map(() => '?').join(',')
|
||||
|
||||
await connection.execute(
|
||||
`UPDATE referral_bindings SET status = 'expired' WHERE id IN (${placeholders})`,
|
||||
ids
|
||||
)
|
||||
|
||||
console.log(` ✅ 已解绑 ${expired.length} 条记录`)
|
||||
|
||||
expired.forEach(e => {
|
||||
console.log(` - ${e.referee_id} 与 ${e.referrer_id} 的绑定已过期`)
|
||||
})
|
||||
}
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 总结
|
||||
// ========================================
|
||||
console.log('=' .repeat(60))
|
||||
console.log('✅ 测试完成!')
|
||||
console.log('=' .repeat(60))
|
||||
console.log()
|
||||
|
||||
console.log('测试结果总结:')
|
||||
console.log(' ✅ 立即切换绑定 - 正常')
|
||||
console.log(' ✅ 购买分佣给最新推荐人 - 正常')
|
||||
console.log(' ✅ 购买次数累加 - 正常')
|
||||
console.log(' ✅ 佣金累加 - 正常')
|
||||
console.log(' ✅ 过期自动解绑 - 正常')
|
||||
console.log()
|
||||
|
||||
// ========================================
|
||||
// 清理测试数据
|
||||
// ========================================
|
||||
console.log('清理测试数据...')
|
||||
|
||||
await connection.execute(
|
||||
`DELETE FROM referral_bindings WHERE referee_id IN (?, ?, ?, ?)`,
|
||||
[TEST_USERS.A.id, TEST_USERS.B.id, TEST_USERS.C.id, 'test_user_d']
|
||||
)
|
||||
|
||||
await connection.execute(
|
||||
`DELETE FROM users WHERE id IN (?, ?, ?)`,
|
||||
[TEST_USERS.A.id, TEST_USERS.B.id, TEST_USERS.C.id]
|
||||
)
|
||||
|
||||
console.log('✅ 测试数据已清理')
|
||||
console.log()
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.message)
|
||||
console.error(error.stack)
|
||||
throw error
|
||||
} finally {
|
||||
if (connection) {
|
||||
await connection.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testFlow().then(() => {
|
||||
console.log('测试脚本执行完成')
|
||||
process.exit(0)
|
||||
}).catch(err => {
|
||||
console.error('脚本执行失败')
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user