25 changed files with 0 additions and 3150 deletions
@ -1 +0,0 @@ |
|||||
PATH=C:\Program Files (x86)\Razer Chroma SDK\bin;C:\Program Files\Razer Chroma SDK\bin;C:\Program Files\Java\jdk1.8.0_202\bin;C:\Program Files\Java\jdk1.8.0_202;C:\Program Files\Common Files\Oracle\Java\javapath;D:\vm\bin\;C:\Program Files (x86)\Razer Chroma SDK\bin;D:\apache-tomcat-8.0.32\bin;C:\Program Files\Razer Chroma SDK\bin;C:\Program Files (x86)\Razer\ChromaBroadcast\bin;C:\Program Files\Razer\ChromaBroadcast\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\ruanjian\Git\cmd;C:\Program Files (x86)\Microsoft SQL Server\160\DTS\Binn\;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\;C:\Users\18477\AppData\Local\nvm;C:\nvm4w\nodejs;C:\Users\18477\AppData\Roaming\MySQL;C:\Program Files\MySQL\MySQL Server 8.0\bin;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;C:\Program Files\dotnet\;C:\Program Files\MySQL\MySQL Shell 8.0\bin\;C:\Program Files\Java\jdk1.8.0_202\bin;D:\python\Scripts\;D:\python\;C:\Users\18477\AppData\Local\Microsoft\WindowsApps;C:\Users\18477\.dotnet\tools;D:\pycharm\PyCharm 2024.3.2\bin;;D:\VS Code\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2025.2.3\bin;C:\Users\18477\AppData\Local\nvm;C:\nvm4w\nodejs; |
|
||||
@ -1,41 +0,0 @@ |
|||||
const { Sequelize } = require('sequelize'); |
|
||||
require('dotenv').config(); |
|
||||
|
|
||||
// 创建数据库连接
|
|
||||
const sequelize = new Sequelize( |
|
||||
process.env.DB_DATABASE || 'wechat_app', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD === undefined ? null : process.env.DB_PASSWORD, |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
timezone: '+08:00' |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
// 添加department字段到usermanagements表
|
|
||||
async function addDepartmentColumn() { |
|
||||
try { |
|
||||
// 连接数据库
|
|
||||
await sequelize.authenticate(); |
|
||||
console.log('✅ 数据库连接成功'); |
|
||||
|
|
||||
// 使用queryInterface添加字段
|
|
||||
await sequelize.getQueryInterface().addColumn('usermanagements', 'department', { |
|
||||
type: Sequelize.STRING(255), |
|
||||
defaultValue: null, |
|
||||
comment: '部门信息' |
|
||||
}); |
|
||||
|
|
||||
console.log('✅ 成功添加department字段到usermanagements表'); |
|
||||
} catch (error) { |
|
||||
console.error('❌ 添加字段失败:', error.message); |
|
||||
} finally { |
|
||||
// 关闭数据库连接
|
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行函数
|
|
||||
addDepartmentColumn(); |
|
||||
@ -1,70 +0,0 @@ |
|||||
// 检查chat_online_status表的当前状态
|
|
||||
const { Sequelize } = require('sequelize'); |
|
||||
|
|
||||
// 数据库配置 - 与server-mysql.js保持一致
|
|
||||
const sequelize = new Sequelize('chat', 'root', '', { |
|
||||
host: 'localhost', |
|
||||
port: 3306, |
|
||||
dialect: 'mysql', |
|
||||
pool: { |
|
||||
max: 10, |
|
||||
min: 0, |
|
||||
acquire: 30000, |
|
||||
idle: 10000 |
|
||||
}, |
|
||||
define: { |
|
||||
freezeTableName: true, |
|
||||
timestamps: false |
|
||||
}, |
|
||||
logging: console.log |
|
||||
}); |
|
||||
|
|
||||
async function checkOnlineStatus() { |
|
||||
try { |
|
||||
console.log('正在连接数据库...'); |
|
||||
await sequelize.authenticate(); |
|
||||
console.log('数据库连接成功'); |
|
||||
|
|
||||
// 查询所有客服的在线状态
|
|
||||
console.log('\n查询chat_online_status表中所有客服(type=2)的记录:'); |
|
||||
const [managerStatuses] = await sequelize.query( |
|
||||
'SELECT * FROM chat_online_status WHERE type = 2 ORDER BY userId, type', |
|
||||
{ type: Sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
if (managerStatuses.length === 0) { |
|
||||
console.log('没有找到客服的在线状态记录'); |
|
||||
} else { |
|
||||
console.log(`找到 ${managerStatuses.length} 条客服在线状态记录:`); |
|
||||
managerStatuses.forEach(record => { |
|
||||
console.log(`- userId: ${record.userId || 'NULL'}, type: ${record.type}, is_online: ${record.is_online}, connection_id: ${record.connection_id}, last_heartbeat: ${record.last_heartbeat}, updated_at: ${record.updated_at}`); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 查询表中所有记录(包括用户和客服)以了解整体情况
|
|
||||
console.log('\n查询chat_online_status表中所有记录:'); |
|
||||
const [allStatuses] = await sequelize.query( |
|
||||
'SELECT * FROM chat_online_status ORDER BY type, userId', |
|
||||
{ type: Sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
console.log(`总共 ${allStatuses.length} 条记录`); |
|
||||
|
|
||||
// 检查是否存在userId为NULL的记录
|
|
||||
const nullUserIdRecords = allStatuses.filter(record => record.userId === null); |
|
||||
if (nullUserIdRecords.length > 0) { |
|
||||
console.log(`\n发现 ${nullUserIdRecords.length} 条userId为NULL的记录:`); |
|
||||
nullUserIdRecords.forEach(record => { |
|
||||
console.log(`- userId: NULL, type: ${record.type}, is_online: ${record.is_online}`); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('检查在线状态时出错:', error); |
|
||||
} finally { |
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行检查
|
|
||||
checkOnlineStatus(); |
|
||||
@ -1,133 +0,0 @@ |
|||||
// 查询用户入驻相关数据
|
|
||||
require('dotenv').config(); |
|
||||
const { Sequelize } = require('sequelize'); |
|
||||
|
|
||||
// 创建数据库连接
|
|
||||
const sequelize = new Sequelize( |
|
||||
process.env.DB_DATABASE || 'wechat_app', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD === undefined ? null : process.env.DB_PASSWORD, |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
timezone: '+08:00' |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
async function checkSettlementData() { |
|
||||
try { |
|
||||
await sequelize.authenticate(); |
|
||||
console.log('✅ 数据库连接成功\n'); |
|
||||
|
|
||||
// 1. 查询所有用户的基本信息和入驻状态
|
|
||||
console.log('=== 用户入驻状态检查 ===\n'); |
|
||||
|
|
||||
const users = await sequelize.query(` |
|
||||
SELECT |
|
||||
id, userId, openid, name, phoneNumber, type, |
|
||||
collaborationid, cooperation, company, |
|
||||
province, city, district, detailedaddress, |
|
||||
businesslicenseurl, proofurl, brandurl, |
|
||||
partnerstatus, reasonforfailure, |
|
||||
created_at, updated_at |
|
||||
FROM users |
|
||||
ORDER BY updated_at DESC |
|
||||
LIMIT 50 |
|
||||
`, { type: Sequelize.QueryTypes.SELECT });
|
|
||||
|
|
||||
console.log(`找到 ${users.length} 个用户记录\n`); |
|
||||
|
|
||||
// 2. 按入驻状态分组统计
|
|
||||
const statusCount = {}; |
|
||||
users.forEach(u => { |
|
||||
const status = u.partnerstatus || '未申请'; |
|
||||
statusCount[status] = (statusCount[status] || 0) + 1; |
|
||||
}); |
|
||||
|
|
||||
console.log('📊 入驻状态统计:'); |
|
||||
Object.entries(statusCount).forEach(([status, count]) => { |
|
||||
console.log(` ${status}: ${count} 人`); |
|
||||
}); |
|
||||
console.log(); |
|
||||
|
|
||||
// 3. 显示每个用户的详细信息
|
|
||||
console.log('👥 用户详细信息:'); |
|
||||
console.log('='.repeat(100)); |
|
||||
|
|
||||
users.forEach((user, index) => { |
|
||||
console.log(`\n【用户 ${index + 1}】`); |
|
||||
console.log(` ID: ${user.id}`); |
|
||||
console.log(` userId: ${user.userId}`); |
|
||||
console.log(` openid: ${user.openid ? user.openid.substring(0, 20) + '...' : '空'}`); |
|
||||
console.log(` 姓名: ${user.name || '空'}`); |
|
||||
console.log(` 手机号: ${user.phoneNumber || '空'}`); |
|
||||
console.log(` 用户类型: ${user.type || '空'}`); |
|
||||
console.log(` ───── 入驻信息 ─────`); |
|
||||
console.log(` 合作商身份(collaborationid): ${user.collaborationid || '空'}`); |
|
||||
console.log(` 合作模式(cooperation): ${user.cooperation || '空'}`); |
|
||||
console.log(` 公司名称(company): ${user.company || '空'}`); |
|
||||
console.log(` 省份: ${user.province || '空'}`); |
|
||||
console.log(` 城市: ${user.city || '空'}`); |
|
||||
console.log(` 区县: ${user.district || '空'}`); |
|
||||
console.log(` 详细地址: ${user.detailedaddress || '空'}`); |
|
||||
console.log(` 营业执照: ${user.businesslicenseurl ? '已上传' : '空'}`); |
|
||||
console.log(` 证明材料: ${user.proofurl ? '已上传' : '空'}`); |
|
||||
console.log(` 品牌授权: ${user.brandurl ? '已上传' : '空'}`); |
|
||||
console.log(` ───── 审核状态 ─────`); |
|
||||
console.log(` 入驻状态(partnerstatus): ${user.partnerstatus || '空'}`); |
|
||||
console.log(` 失败原因: ${user.reasonforfailure || '空'}`); |
|
||||
console.log(` 创建时间: ${user.created_at}`); |
|
||||
console.log(` 更新时间: ${user.updated_at}`); |
|
||||
}); |
|
||||
|
|
||||
// 4. 特别检查有openid但partnerstatus为空的记录
|
|
||||
console.log('\n\n=== 重点检查:已登录但未提交入驻的用户 ===\n'); |
|
||||
|
|
||||
const notApplied = users.filter(u => u.openid && !u.partnerstatus); |
|
||||
console.log(`有 ${notApplied.length} 个用户已登录但未提交入驻申请`); |
|
||||
|
|
||||
if (notApplied.length > 0) { |
|
||||
console.log('\n这些用户的openid:'); |
|
||||
notApplied.forEach(u => { |
|
||||
console.log(` - userId: ${u.userId}, openid: ${u.openid.substring(0, 30)}...`); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 5. 检查是否有审核中的用户
|
|
||||
console.log('\n\n=== 审核中的用户 ===\n'); |
|
||||
const underReview = users.filter(u => u.partnerstatus === 'underreview'); |
|
||||
console.log(`有 ${underReview.length} 个用户正在审核中`); |
|
||||
|
|
||||
if (underReview.length > 0) { |
|
||||
underReview.forEach(u => { |
|
||||
console.log(` - userId: ${u.userId}, 公司: ${u.company || '空'}, 身份: ${u.collaborationid || '空'}`); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 6. 检查users表的字段结构
|
|
||||
console.log('\n\n=== users表字段结构 ===\n'); |
|
||||
const tableStructure = await sequelize.query('DESCRIBE users', { type: Sequelize.QueryTypes.SELECT }); |
|
||||
const settlementFields = [ |
|
||||
'collaborationid', 'cooperation', 'company', 'province', 'city', 'district', |
|
||||
'detailedaddress', 'businesslicenseurl', 'proofurl', 'brandurl', |
|
||||
'partnerstatus', 'reasonforfailure' |
|
||||
]; |
|
||||
|
|
||||
console.log('入驻相关字段:'); |
|
||||
tableStructure.forEach(field => { |
|
||||
if (settlementFields.includes(field.Field)) { |
|
||||
console.log(` ${field.Field}: ${field.Type} ${field.Null === 'NO' ? 'NOT NULL' : ''} Default: ${field.Default || '无'}`); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 查询失败:', error.message); |
|
||||
console.error(error.stack); |
|
||||
} finally { |
|
||||
await sequelize.close(); |
|
||||
console.log('\n✅ 查询完成'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
checkSettlementData(); |
|
||||
@ -1,107 +0,0 @@ |
|||||
// 清理临时userId数据脚本
|
|
||||
// 此脚本用于删除chat_conversations和chat_messages表中所有临时userId的数据
|
|
||||
// 临时userId格式:temp_1765852836234
|
|
||||
|
|
||||
const mysql = require('mysql2/promise'); |
|
||||
|
|
||||
async function cleanupTempUserIds() { |
|
||||
let connection; |
|
||||
|
|
||||
try { |
|
||||
// 创建数据库连接
|
|
||||
connection = await mysql.createConnection({ |
|
||||
host: '1.95.162.61', |
|
||||
port: 3306, |
|
||||
user: 'root', |
|
||||
password: 'schl@2025', |
|
||||
database: 'wechat_app' |
|
||||
}); |
|
||||
|
|
||||
console.log('✓ 数据库连接成功'); |
|
||||
|
|
||||
// ============== 清理chat_conversations表中的临时userId数据 ==============
|
|
||||
console.log('\n=== 清理chat_conversations表中的临时userId数据 ==='); |
|
||||
|
|
||||
// 1. 统计需要删除的临时userId会话记录
|
|
||||
const [convTempCount] = await connection.execute( |
|
||||
'SELECT COUNT(*) as count FROM chat_conversations WHERE userId LIKE ? OR managerId LIKE ?', |
|
||||
['temp_%', 'temp_%'] |
|
||||
); |
|
||||
console.log(`找到 ${convTempCount[0].count} 条临时userId的会话记录`); |
|
||||
|
|
||||
// 2. 删除临时userId的会话记录
|
|
||||
if (convTempCount[0].count > 0) { |
|
||||
const [convResult] = await connection.execute( |
|
||||
'DELETE FROM chat_conversations WHERE userId LIKE ? OR managerId LIKE ?', |
|
||||
['temp_%', 'temp_%'] |
|
||||
); |
|
||||
console.log(`成功删除chat_conversations表中的 ${convResult.affectedRows} 条临时userId记录`); |
|
||||
} |
|
||||
|
|
||||
// ============== 清理chat_messages表中的临时userId数据 ==============
|
|
||||
console.log('\n=== 清理chat_messages表中的临时userId数据 ==='); |
|
||||
|
|
||||
// 1. 统计需要删除的临时userId消息记录
|
|
||||
const [msgTempCount] = await connection.execute( |
|
||||
'SELECT COUNT(*) as count FROM chat_messages WHERE sender_id LIKE ? OR receiver_id LIKE ?', |
|
||||
['temp_%', 'temp_%'] |
|
||||
); |
|
||||
console.log(`找到 ${msgTempCount[0].count} 条临时userId的消息记录`); |
|
||||
|
|
||||
// 2. 删除临时userId的消息记录
|
|
||||
if (msgTempCount[0].count > 0) { |
|
||||
const [msgResult] = await connection.execute( |
|
||||
'DELETE FROM chat_messages WHERE sender_id LIKE ? OR receiver_id LIKE ?', |
|
||||
['temp_%', 'temp_%'] |
|
||||
); |
|
||||
console.log(`成功删除chat_messages表中的 ${msgResult.affectedRows} 条临时userId记录`); |
|
||||
} |
|
||||
|
|
||||
// ============== 验证清理结果 ==============
|
|
||||
console.log('\n=== 验证清理结果 ==='); |
|
||||
|
|
||||
// 再次检查chat_conversations表中是否还有临时userId记录
|
|
||||
const [convVerify] = await connection.execute( |
|
||||
'SELECT COUNT(*) as count FROM chat_conversations WHERE userId LIKE ? OR managerId LIKE ?', |
|
||||
['temp_%', 'temp_%'] |
|
||||
); |
|
||||
console.log(`chat_conversations表中剩余临时userId记录数: ${convVerify[0].count}`); |
|
||||
|
|
||||
// 再次检查chat_messages表中是否还有临时userId记录
|
|
||||
const [msgVerify] = await connection.execute( |
|
||||
'SELECT COUNT(*) as count FROM chat_messages WHERE sender_id LIKE ? OR receiver_id LIKE ?', |
|
||||
['temp_%', 'temp_%'] |
|
||||
); |
|
||||
console.log(`chat_messages表中剩余临时userId记录数: ${msgVerify[0].count}`); |
|
||||
|
|
||||
// ============== 检查剩余的有效数据 ==============
|
|
||||
console.log('\n=== 检查剩余的有效数据 ==='); |
|
||||
|
|
||||
// 检查chat_conversations表中的有效记录数
|
|
||||
const [convValid] = await connection.execute( |
|
||||
'SELECT COUNT(*) as count FROM chat_conversations' |
|
||||
); |
|
||||
console.log(`chat_conversations表中有效会话记录数: ${convValid[0].count}`); |
|
||||
|
|
||||
// 检查chat_messages表中的有效记录数
|
|
||||
const [msgValid] = await connection.execute( |
|
||||
'SELECT COUNT(*) as count FROM chat_messages' |
|
||||
); |
|
||||
console.log(`chat_messages表中有效消息记录数: ${msgValid[0].count}`); |
|
||||
|
|
||||
console.log('\n✅ 清理完成!所有临时userId数据已被删除。'); |
|
||||
console.log('✅ 现在数据库中只保留了真实userId的数据。'); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 清理过程中发生错误:', error); |
|
||||
} finally { |
|
||||
if (connection) { |
|
||||
await connection.end(); |
|
||||
console.log('✅ 数据库连接已关闭'); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行清理操作
|
|
||||
console.log('========== 开始清理临时userId数据 =========='); |
|
||||
cleanupTempUserIds().catch(console.error); |
|
||||
@ -1,29 +0,0 @@ |
|||||
const { Sequelize } = require('sequelize'); |
|
||||
const sequelize = new Sequelize('wechat_app', 'root', 'schl@2025', { |
|
||||
host: '1.95.162.61', |
|
||||
port: 3306, |
|
||||
dialect: 'mysql', |
|
||||
logging: false |
|
||||
}); |
|
||||
|
|
||||
async function cleanup() { |
|
||||
try { |
|
||||
// 删除测试会话相关的消息
|
|
||||
await sequelize.query('DELETE FROM chat_messages WHERE conversation_id = ?', { |
|
||||
replacements: ['conv_1765767582602'] |
|
||||
}); |
|
||||
|
|
||||
// 删除测试会话
|
|
||||
await sequelize.query('DELETE FROM chat_conversations WHERE conversation_id = ?', { |
|
||||
replacements: ['conv_1765767582602'] |
|
||||
}); |
|
||||
|
|
||||
console.log('测试会话记录已删除'); |
|
||||
} catch (e) { |
|
||||
console.error('删除错误:', e.message); |
|
||||
} finally { |
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
cleanup(); |
|
||||
@ -1,143 +0,0 @@ |
|||||
// 毛重字段(grossWeight)处理逻辑完整修复脚本
|
|
||||
// 此脚本用于统一所有API接口对grossWeight字段的处理逻辑
|
|
||||
|
|
||||
const fs = require('fs'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 定义配置
|
|
||||
const config = { |
|
||||
serverFilePath: path.join(__dirname, 'server-mysql.js'), |
|
||||
backupFilePath: path.join(__dirname, 'server-mysql.js.bak.final-fix-' + Date.now()), |
|
||||
logFilePath: path.join(__dirname, 'final-fix-gross-weight-log.txt') |
|
||||
}; |
|
||||
|
|
||||
// 日志函数
|
|
||||
function log(message) { |
|
||||
const timestamp = new Date().toISOString(); |
|
||||
const logMessage = '[' + timestamp + '] ' + message; |
|
||||
console.log(logMessage); |
|
||||
try { |
|
||||
fs.appendFileSync(config.logFilePath, logMessage + '\n'); |
|
||||
} catch (e) { |
|
||||
console.error('写入日志文件失败:', e.message); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 读取文件内容
|
|
||||
function readFile(filePath) { |
|
||||
try { |
|
||||
return fs.readFileSync(filePath, 'utf8'); |
|
||||
} catch (error) { |
|
||||
log('读取文件失败: ' + error.message); |
|
||||
throw error; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 写入文件内容
|
|
||||
function writeFile(filePath, content) { |
|
||||
try { |
|
||||
fs.writeFileSync(filePath, content, 'utf8'); |
|
||||
log('文件已成功写入: ' + filePath); |
|
||||
} catch (error) { |
|
||||
log('写入文件失败: ' + error.message); |
|
||||
throw error; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 创建备份文件
|
|
||||
function createBackup() { |
|
||||
try { |
|
||||
const content = readFile(config.serverFilePath); |
|
||||
writeFile(config.backupFilePath, content); |
|
||||
log('已创建备份文件: ' + config.backupFilePath); |
|
||||
} catch (error) { |
|
||||
log('创建备份文件失败: ' + error.message); |
|
||||
throw error; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 主函数
|
|
||||
function main() { |
|
||||
log('===== 开始执行毛重字段处理逻辑完整修复 ====='); |
|
||||
|
|
||||
try { |
|
||||
// 创建备份
|
|
||||
createBackup(); |
|
||||
|
|
||||
// 读取文件内容
|
|
||||
let content = readFile(config.serverFilePath); |
|
||||
|
|
||||
// 修复1: 统一中间件中的毛重处理逻辑,确保所有空值都设为5
|
|
||||
const searchPatterns = [ |
|
||||
'product.grossWeight = 0;', |
|
||||
'product.grossWeight = 0; // 空值设置为0' |
|
||||
]; |
|
||||
|
|
||||
let fixesApplied = 0; |
|
||||
searchPatterns.forEach(pattern => { |
|
||||
if (content.includes(pattern)) { |
|
||||
const originalCount = (content.match(new RegExp(pattern, 'g')) || []).length; |
|
||||
content = content.replace(new RegExp(pattern, 'g'), 'product.grossWeight = 5; // 空值设置为5'); |
|
||||
const fixedCount = (content.match(/product\.grossWeight = 5;/g) || []).length - originalCount; |
|
||||
fixesApplied += fixedCount; |
|
||||
log('修复中间件中的毛重默认值: 替换了' + fixedCount + '处'); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
if (fixesApplied > 0) { |
|
||||
log('修复1完成: 已统一所有中间件中的毛重默认值为5'); |
|
||||
} else { |
|
||||
log('修复1跳过: 所有中间件中的毛重默认值已经是5'); |
|
||||
} |
|
||||
|
|
||||
// 修复2: 在商品上传接口添加毛重处理逻辑
|
|
||||
const uploadApiSearch = 'app.post(\'/api/products/upload\', async (req, res) => {'; |
|
||||
if (content.includes(uploadApiSearch)) { |
|
||||
// 查找上传接口的位置
|
|
||||
const uploadApiStart = content.indexOf(uploadApiSearch); |
|
||||
const uploadApiEnd = content.indexOf('});', uploadApiStart) + 3; |
|
||||
const uploadApiContent = content.substring(uploadApiStart, uploadApiEnd); |
|
||||
|
|
||||
// 检查是否已经包含毛重处理逻辑
|
|
||||
if (uploadApiContent.includes('grossWeight') && uploadApiContent.includes('parseFloat')) { |
|
||||
log('修复2跳过: 商品上传接口已经包含毛重处理逻辑'); |
|
||||
} else { |
|
||||
// 查找商品数据处理的位置(在try块内)
|
|
||||
const tryBlockStart = uploadApiContent.indexOf('try {'); |
|
||||
const tryBlockEnd = uploadApiContent.lastIndexOf('} catch'); |
|
||||
|
|
||||
if (tryBlockStart !== -1 && tryBlockEnd !== -1) { |
|
||||
// 在try块开始处添加毛重处理逻辑
|
|
||||
const tryBlockContent = uploadApiContent.substring(tryBlockStart, tryBlockEnd); |
|
||||
const weightHandlingCode = `try {\n // 修复毛重字段处理逻辑\n if (req.body && req.body.productData) {\n let processedGrossWeight = 5; // 默认值为5\n if (req.body.productData.grossWeight !== null && req.body.productData.grossWeight !== undefined && req.body.productData.grossWeight !== \'\') {\n const numValue = parseFloat(req.body.productData.grossWeight);\n if (!isNaN(numValue) && isFinite(numValue)) {\n processedGrossWeight = numValue;\n }\n }\n req.body.productData.grossWeight = processedGrossWeight;\n console.log(\'修复后 - 毛重值处理: 原始值=\' + (req.body.productData.grossWeight || \'undefined\') + ', 处理后=\' + processedGrossWeight);\n }`; |
|
||||
|
|
||||
// 替换原代码
|
|
||||
const fixedUploadApiContent = uploadApiContent.replace(tryBlockContent, weightHandlingCode); |
|
||||
content = content.replace(uploadApiContent, fixedUploadApiContent); |
|
||||
log('修复2完成: 在商品上传接口添加了毛重处理逻辑'); |
|
||||
} else { |
|
||||
log('修复2失败: 无法在商品上传接口中找到try-catch块'); |
|
||||
} |
|
||||
} |
|
||||
} else { |
|
||||
log('修复2跳过: 未找到商品上传接口'); |
|
||||
} |
|
||||
|
|
||||
// 写入修复后的内容
|
|
||||
writeFile(config.serverFilePath, content); |
|
||||
|
|
||||
log('===== 毛重字段处理逻辑完整修复完成 ====='); |
|
||||
log('修复内容总结:'); |
|
||||
log('1. 统一了所有中间件中的毛重默认值为5'); |
|
||||
log('2. 在商品上传接口中添加了毛重处理逻辑,将空值设为5,有效数字转换为float类型'); |
|
||||
log('3. 创建了备份文件,以便需要时恢复'); |
|
||||
|
|
||||
} catch (error) { |
|
||||
log('修复过程中发生错误: ' + error.message); |
|
||||
log('===== 毛重字段处理逻辑完整修复失败 ====='); |
|
||||
process.exit(1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行主函数
|
|
||||
main(); |
|
||||
@ -1,123 +0,0 @@ |
|||||
const fs = require('fs'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 读取server-mysql.js文件内容
|
|
||||
function readServerFile() { |
|
||||
return fs.readFileSync(path.join(__dirname, 'server-mysql.js'), 'utf8'); |
|
||||
} |
|
||||
|
|
||||
// 验证毛重字段处理逻辑
|
|
||||
function verifyGrossWeightHandling() { |
|
||||
try { |
|
||||
const fileContent = readServerFile(); |
|
||||
|
|
||||
// 初始化验证结果
|
|
||||
const verificationResult = { |
|
||||
totalIssues: 0, |
|
||||
successPoints: 0, |
|
||||
issues: [], |
|
||||
successDetails: [] |
|
||||
}; |
|
||||
|
|
||||
// 检查响应中间件中的/products/list接口
|
|
||||
const listMiddlewarePattern = /data\.products\s*=\s*data\.products\.map\(product\s*=>\s*\{[\s\S]*?product\.grossWeight\s*=\s*([^;]+);/; |
|
||||
const listMiddlewareMatch = fileContent.match(listMiddlewarePattern); |
|
||||
|
|
||||
if (listMiddlewareMatch && listMiddlewareMatch[1].includes('0')) { |
|
||||
verificationResult.successPoints++; |
|
||||
verificationResult.successDetails.push('✓ 响应中间件(/products/list)已正确设置空毛重默认值为0'); |
|
||||
} else { |
|
||||
verificationResult.totalIssues++; |
|
||||
verificationResult.issues.push('✗ 响应中间件(/products/list)未正确设置空毛重默认值'); |
|
||||
} |
|
||||
|
|
||||
// 检查响应中间件中的/data接口
|
|
||||
const dataMiddlewarePattern = /data\.data\.products\s*=\s*data\.data\.products\.map\(product\s*=>\s*\{[\s\S]*?product\.grossWeight\s*=\s*([^;]+);/; |
|
||||
const dataMiddlewareMatch = fileContent.match(dataMiddlewarePattern); |
|
||||
|
|
||||
if (dataMiddlewareMatch && dataMiddlewareMatch[1].includes('0')) { |
|
||||
verificationResult.successPoints++; |
|
||||
verificationResult.successDetails.push('✓ 响应中间件(/data)已正确设置空毛重默认值为0'); |
|
||||
} else { |
|
||||
verificationResult.totalIssues++; |
|
||||
verificationResult.issues.push('✗ 响应中间件(/data)未正确设置空毛重默认值'); |
|
||||
} |
|
||||
|
|
||||
// 检查商品上传接口
|
|
||||
const uploadApiPattern = /app\.post\('\/api\/products\/upload',[\s\S]*?let\s+processedGrossWeight\s*=\s*(\d+)/; |
|
||||
const uploadApiMatch = fileContent.match(uploadApiPattern); |
|
||||
|
|
||||
if (uploadApiMatch && uploadApiMatch[1] === '0') { |
|
||||
verificationResult.successPoints++; |
|
||||
verificationResult.successDetails.push('✓ 商品上传接口已正确设置空毛重默认值为0'); |
|
||||
} else { |
|
||||
verificationResult.totalIssues++; |
|
||||
verificationResult.issues.push('✗ 商品上传接口未正确设置空毛重默认值'); |
|
||||
} |
|
||||
|
|
||||
// 检查编辑商品API
|
|
||||
const editApiPattern = /parsedValue:\s*product\.grossWeight\s*===\s*''\s*\|\|\s*product\.grossWeight\s*===\s*null\s*\|\|\s*product\.grossWeight\s*===\s*undefined\s*\?\s*(\d+)/; |
|
||||
const editApiMatch = fileContent.match(editApiPattern); |
|
||||
|
|
||||
if (editApiMatch && editApiMatch[1] === '0') { |
|
||||
verificationResult.successPoints++; |
|
||||
verificationResult.successDetails.push('✓ 编辑商品API已正确设置空毛重默认值为0'); |
|
||||
} else { |
|
||||
verificationResult.totalIssues++; |
|
||||
verificationResult.issues.push('✗ 编辑商品API未正确设置空毛重默认值'); |
|
||||
} |
|
||||
|
|
||||
// 检查是否还有设置为5的地方
|
|
||||
const remaining5Pattern = /grossWeight\s*=\s*5/g; |
|
||||
const remaining5Matches = fileContent.match(remaining5Pattern); |
|
||||
|
|
||||
if (remaining5Matches && remaining5Matches.length > 0) { |
|
||||
verificationResult.totalIssues += remaining5Matches.length; |
|
||||
verificationResult.issues.push(`✗ 发现${remaining5Matches.length}处仍将毛重设置为5的地方`); |
|
||||
} else { |
|
||||
verificationResult.successPoints++; |
|
||||
verificationResult.successDetails.push('✓ 未发现仍将毛重设置为5的残留代码'); |
|
||||
} |
|
||||
|
|
||||
// 检查是否正确实现了空值返回0的逻辑
|
|
||||
const emptyValueHandlingPattern = /product\.grossWeight\s*===\s*null\s*\|\|\s*product\.grossWeight\s*===\s*undefined\s*\|\|\s*product\.grossWeight\s*===\s*''\s*\?\s*0/g; |
|
||||
const emptyValueMatches = fileContent.match(emptyValueHandlingPattern); |
|
||||
|
|
||||
if (emptyValueMatches && emptyValueMatches.length > 0) { |
|
||||
verificationResult.successPoints++; |
|
||||
verificationResult.successDetails.push(`✓ 发现${emptyValueMatches.length}处正确实现了空值返回0的逻辑`); |
|
||||
} |
|
||||
|
|
||||
// 输出验证结果
|
|
||||
console.log('\n======== 毛重字段处理逻辑全面验证结果 ========'); |
|
||||
console.log('\n成功项:'); |
|
||||
verificationResult.successDetails.forEach(detail => console.log(detail)); |
|
||||
|
|
||||
console.log('\n问题项:'); |
|
||||
if (verificationResult.issues.length === 0) { |
|
||||
console.log('✓ 未发现任何问题'); |
|
||||
} else { |
|
||||
verificationResult.issues.forEach(issue => console.log(issue)); |
|
||||
} |
|
||||
|
|
||||
console.log('\n总体评估:'); |
|
||||
if (verificationResult.totalIssues === 0) { |
|
||||
console.log('✅ 验证成功: 所有毛重字段处理逻辑已正确实现'); |
|
||||
console.log(' 已满足要求: 空值时小程序和数据库均返回0,非空值返回实际值'); |
|
||||
} else { |
|
||||
console.log(`❌ 验证失败: 发现${verificationResult.totalIssues}个问题需要修复`); |
|
||||
} |
|
||||
|
|
||||
console.log('=============================================='); |
|
||||
|
|
||||
// 设置退出码
|
|
||||
process.exit(verificationResult.totalIssues > 0 ? 1 : 0); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('验证过程中发生错误:', error); |
|
||||
process.exit(1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行验证
|
|
||||
verifyGrossWeightHandling(); |
|
||||
@ -1,155 +0,0 @@ |
|||||
const { Sequelize } = require('sequelize'); |
|
||||
const fs = require('fs'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 读取环境变量
|
|
||||
const envPath = path.join(__dirname, '.env'); |
|
||||
if (fs.existsSync(envPath)) { |
|
||||
const envContent = fs.readFileSync(envPath, 'utf8'); |
|
||||
const envVars = envContent.split('\n').filter(line => line.trim() && !line.startsWith('#')); |
|
||||
envVars.forEach(line => { |
|
||||
const [key, value] = line.split('=').map(part => part.trim()); |
|
||||
process.env[key] = value; |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 数据库连接配置
|
|
||||
const sequelize = new Sequelize( |
|
||||
process.env.DB_NAME || 'wechat_app', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD || '', |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
logging: false, |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
} |
|
||||
); |
|
||||
|
|
||||
// 定义模型 - 简化版
|
|
||||
const User = sequelize.define('User', { |
|
||||
userId: { |
|
||||
type: sequelize.Sequelize.STRING(100), |
|
||||
primaryKey: true, |
|
||||
allowNull: false |
|
||||
}, |
|
||||
nickName: sequelize.Sequelize.STRING(100), |
|
||||
phoneNumber: sequelize.Sequelize.STRING(20) |
|
||||
}, { |
|
||||
tableName: 'users', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
const Contact = sequelize.define('Contact', { |
|
||||
id: { |
|
||||
type: sequelize.Sequelize.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: sequelize.Sequelize.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
nickName: sequelize.Sequelize.STRING(100), |
|
||||
phoneNumber: sequelize.Sequelize.STRING(20) |
|
||||
}, { |
|
||||
tableName: 'contacts', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
const UserManagement = sequelize.define('UserManagement', { |
|
||||
id: { |
|
||||
type: sequelize.Sequelize.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: sequelize.Sequelize.STRING(100), |
|
||||
allowNull: false |
|
||||
} |
|
||||
}, { |
|
||||
tableName: 'usermanagements', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// 修复函数
|
|
||||
async function fixMissingAssociations() { |
|
||||
try { |
|
||||
console.log('========================================'); |
|
||||
console.log('开始修复用户关联表记录'); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
// 连接数据库
|
|
||||
await sequelize.authenticate(); |
|
||||
console.log('✅ 数据库连接成功'); |
|
||||
|
|
||||
// 获取所有用户
|
|
||||
const users = await User.findAll(); |
|
||||
console.log(`📊 共找到 ${users.length} 个用户记录`); |
|
||||
|
|
||||
let contactsCreated = 0; |
|
||||
let managementsCreated = 0; |
|
||||
|
|
||||
// 为每个用户检查并创建关联记录
|
|
||||
for (let i = 0; i < users.length; i++) { |
|
||||
const user = users[i]; |
|
||||
console.log(`\n🔄 处理用户 ${i + 1}/${users.length}: ${user.userId}`); |
|
||||
|
|
||||
// 检查并创建联系人记录
|
|
||||
try { |
|
||||
const existingContact = await Contact.findOne({ |
|
||||
where: { userId: user.userId } |
|
||||
}); |
|
||||
|
|
||||
if (!existingContact) { |
|
||||
await Contact.create({ |
|
||||
userId: user.userId, |
|
||||
nickName: user.nickName || '默认联系人', |
|
||||
phoneNumber: user.phoneNumber || '' |
|
||||
}); |
|
||||
console.log('✅ 创建了联系人记录'); |
|
||||
contactsCreated++; |
|
||||
} else { |
|
||||
console.log('✅ 联系人记录已存在'); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('❌ 创建联系人记录失败:', error.message); |
|
||||
} |
|
||||
|
|
||||
// 检查并创建用户管理记录
|
|
||||
try { |
|
||||
const existingManagement = await UserManagement.findOne({ |
|
||||
where: { userId: user.userId } |
|
||||
}); |
|
||||
|
|
||||
if (!existingManagement) { |
|
||||
await UserManagement.create({ |
|
||||
userId: user.userId |
|
||||
}); |
|
||||
console.log('✅ 创建了用户管理记录'); |
|
||||
managementsCreated++; |
|
||||
} else { |
|
||||
console.log('✅ 用户管理记录已存在'); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('❌ 创建用户管理记录失败:', error.message); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
console.log('\n========================================'); |
|
||||
console.log('修复完成!'); |
|
||||
console.log(`📈 共创建了 ${contactsCreated} 条联系人记录`); |
|
||||
console.log(`📈 共创建了 ${managementsCreated} 条用户管理记录`); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 修复过程中发生错误:', error); |
|
||||
} finally { |
|
||||
// 关闭数据库连接
|
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 运行修复
|
|
||||
fixMissingAssociations(); |
|
||||
@ -1,356 +0,0 @@ |
|||||
// 注意:此文件是MongoDB版本的扩展实现,已被禁用
|
|
||||
// 数据库扩展 - 用于连接userlogin数据库并关联表
|
|
||||
const { Sequelize, DataTypes, Model } = require('sequelize'); |
|
||||
const path = require('path'); |
|
||||
require('dotenv').config({ path: path.resolve(__dirname, '.env') }); |
|
||||
|
|
||||
// 注意:不再直接导入User模型以避免循环依赖
|
|
||||
// User模型将通过setupAssociations函数的参数传入
|
|
||||
let User = null; |
|
||||
|
|
||||
// 创建到userlogin数据库的连接
|
|
||||
const sequelizeUserLogin = new Sequelize( |
|
||||
process.env.DB_DATABASE_USERLOGIN || 'userlogin', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD, |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
pool: { |
|
||||
max: 10, |
|
||||
min: 0, |
|
||||
acquire: 30000, |
|
||||
idle: 10000 |
|
||||
}, |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
} |
|
||||
); |
|
||||
|
|
||||
// 测试userlogin数据库连接
|
|
||||
async function testUserLoginDbConnection() { |
|
||||
try { |
|
||||
await sequelizeUserLogin.authenticate(); |
|
||||
console.log('userlogin数据库连接成功'); |
|
||||
} catch (error) { |
|
||||
console.error('userlogin数据库连接失败:', error); |
|
||||
console.error('请注意:如果不需要使用userlogin数据库,可以忽略此错误'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 定义userlogin数据库中的表模型
|
|
||||
|
|
||||
// contact表模型
|
|
||||
class Contact extends Model { } |
|
||||
Contact.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
name: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
phone: { |
|
||||
type: DataTypes.STRING(20), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
email: { |
|
||||
type: DataTypes.STRING(100) |
|
||||
}, |
|
||||
address: { |
|
||||
type: DataTypes.TEXT |
|
||||
}, |
|
||||
created_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize: sequelizeUserLogin, |
|
||||
modelName: 'Contact', |
|
||||
tableName: 'contact', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// enterprise表模型
|
|
||||
class Enterprise extends Model { } |
|
||||
Enterprise.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
enterpriseName: { |
|
||||
type: DataTypes.STRING(255), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
businessLicense: { |
|
||||
type: DataTypes.STRING(255) |
|
||||
}, |
|
||||
address: { |
|
||||
type: DataTypes.TEXT |
|
||||
}, |
|
||||
contactPerson: { |
|
||||
type: DataTypes.STRING(100) |
|
||||
}, |
|
||||
contactPhone: { |
|
||||
type: DataTypes.STRING(20) |
|
||||
}, |
|
||||
created_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize: sequelizeUserLogin, |
|
||||
modelName: 'Enterprise', |
|
||||
tableName: 'enterprise', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// managers表模型
|
|
||||
class Manager extends Model { } |
|
||||
Manager.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
managerName: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
managerPhone: { |
|
||||
type: DataTypes.STRING(20), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
role: { |
|
||||
type: DataTypes.STRING(50), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
created_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize: sequelizeUserLogin, |
|
||||
modelName: 'Manager', |
|
||||
tableName: 'managers', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// publicseademand表模型
|
|
||||
class PublicSeaDemand extends Model { } |
|
||||
PublicSeaDemand.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
demandType: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
description: { |
|
||||
type: DataTypes.TEXT |
|
||||
}, |
|
||||
status: { |
|
||||
type: DataTypes.STRING(50), |
|
||||
defaultValue: 'pending' |
|
||||
}, |
|
||||
created_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize: sequelizeUserLogin, |
|
||||
modelName: 'PublicSeaDemand', |
|
||||
tableName: 'publicseademand', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// rootdb表模型
|
|
||||
class RootDb extends Model { } |
|
||||
RootDb.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
dataKey: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
dataValue: { |
|
||||
type: DataTypes.TEXT |
|
||||
}, |
|
||||
created_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize: sequelizeUserLogin, |
|
||||
modelName: 'RootDb', |
|
||||
tableName: 'rootdb', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// login表模型
|
|
||||
class Login extends Model { } |
|
||||
Login.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
loginTime: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
}, |
|
||||
loginIp: { |
|
||||
type: DataTypes.STRING(50) |
|
||||
}, |
|
||||
deviceInfo: { |
|
||||
type: DataTypes.TEXT |
|
||||
}, |
|
||||
status: { |
|
||||
type: DataTypes.STRING(20), |
|
||||
defaultValue: 'success' |
|
||||
} |
|
||||
}, { |
|
||||
sequelize: sequelizeUserLogin, |
|
||||
modelName: 'Login', |
|
||||
tableName: 'login', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// 设置模型关联关系
|
|
||||
function setupAssociations(mainUserModel) { |
|
||||
// 确保使用传入的User模型,不再依赖默认的User变量
|
|
||||
if (!mainUserModel) { |
|
||||
console.error('User模型未提供,无法设置关联关系'); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
// 关联User与Contact(一对多)
|
|
||||
// 使用唯一的别名userContacts以避免可能的冲突
|
|
||||
mainUserModel.hasMany(Contact, { |
|
||||
foreignKey: 'userId', |
|
||||
sourceKey: 'userId', |
|
||||
as: 'userContacts' |
|
||||
}); |
|
||||
|
|
||||
// 反向关联Contact与User
|
|
||||
Contact.belongsTo(mainUserModel, { |
|
||||
foreignKey: 'userId', |
|
||||
targetKey: 'userId', |
|
||||
as: 'user' |
|
||||
}); |
|
||||
|
|
||||
// 关联User与Enterprise(一对多)
|
|
||||
mainUserModel.hasMany(Enterprise, { |
|
||||
foreignKey: 'userId', |
|
||||
sourceKey: 'userId', |
|
||||
as: 'userEnterprises' |
|
||||
}); |
|
||||
|
|
||||
// 反向关联Enterprise与User
|
|
||||
Enterprise.belongsTo(mainUserModel, { |
|
||||
foreignKey: 'userId', |
|
||||
targetKey: 'userId', |
|
||||
as: 'user' |
|
||||
}); |
|
||||
|
|
||||
// 关联User与Manager(一对多)
|
|
||||
mainUserModel.hasMany(Manager, { |
|
||||
foreignKey: 'userId', |
|
||||
sourceKey: 'userId', |
|
||||
as: 'userManagers' |
|
||||
}); |
|
||||
|
|
||||
// 反向关联Manager与User
|
|
||||
Manager.belongsTo(mainUserModel, { |
|
||||
foreignKey: 'userId', |
|
||||
targetKey: 'userId', |
|
||||
as: 'user' |
|
||||
}); |
|
||||
|
|
||||
// 关联User与PublicSeaDemand(一对多)
|
|
||||
mainUserModel.hasMany(PublicSeaDemand, { |
|
||||
foreignKey: 'userId', |
|
||||
sourceKey: 'userId', |
|
||||
as: 'userPublicSeaDemands' |
|
||||
}); |
|
||||
|
|
||||
// 反向关联PublicSeaDemand与User
|
|
||||
PublicSeaDemand.belongsTo(mainUserModel, { |
|
||||
foreignKey: 'userId', |
|
||||
targetKey: 'userId', |
|
||||
as: 'user' |
|
||||
}); |
|
||||
|
|
||||
// 关联User与RootDb(一对多)
|
|
||||
mainUserModel.hasMany(RootDb, { |
|
||||
foreignKey: 'userId', |
|
||||
sourceKey: 'userId', |
|
||||
as: 'userRootDbs' |
|
||||
}); |
|
||||
|
|
||||
// 反向关联RootDb与User
|
|
||||
RootDb.belongsTo(mainUserModel, { |
|
||||
foreignKey: 'userId', |
|
||||
targetKey: 'userId', |
|
||||
as: 'user' |
|
||||
}); |
|
||||
|
|
||||
// 关联User与Login(一对多)
|
|
||||
mainUserModel.hasMany(Login, { |
|
||||
foreignKey: 'userId', |
|
||||
sourceKey: 'userId', |
|
||||
as: 'userLoginRecords' |
|
||||
}); |
|
||||
|
|
||||
console.log('已设置wechat_app数据库的User模型与userlogin数据库表的关联关系'); |
|
||||
} catch (error) { |
|
||||
console.error('设置模型关联关系时出错:', error); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 导出所有模型和连接
|
|
||||
module.exports = { |
|
||||
sequelizeUserLogin, |
|
||||
testUserLoginDbConnection, |
|
||||
Contact, |
|
||||
Enterprise, |
|
||||
Manager, |
|
||||
PublicSeaDemand, |
|
||||
RootDb, |
|
||||
Login, |
|
||||
setupAssociations, |
|
||||
User // 导出User模型(可能是实际的模型或临时模型)
|
|
||||
}; |
|
||||
@ -1,116 +0,0 @@ |
|||||
// WebSocket调试脚本 - 专注于连接和认证
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
// 服务器地址
|
|
||||
const SERVER_URL = 'ws://localhost:3003'; |
|
||||
const customerServiceId = '22'; // 刘杨的ID
|
|
||||
|
|
||||
console.log('=== WebSocket认证详细调试 ==='); |
|
||||
console.log(`连接服务器: ${SERVER_URL}`); |
|
||||
|
|
||||
// 创建WebSocket连接
|
|
||||
const ws = new WebSocket(SERVER_URL, { |
|
||||
perMessageDeflate: false, |
|
||||
headers: { |
|
||||
'User-Agent': 'Debug-Client', |
|
||||
'Connection': 'Upgrade' |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
// 连接事件
|
|
||||
ws.on('open', () => { |
|
||||
console.log('✅ WebSocket连接已建立'); |
|
||||
|
|
||||
// 延迟100ms发送认证消息,确保连接完全就绪
|
|
||||
setTimeout(() => { |
|
||||
// 使用正确的认证格式 - 必须有type: 'auth'
|
|
||||
const authMessage = { |
|
||||
type: 'auth', // 必须是'auth'才能被服务器识别为认证消息
|
|
||||
managerId: customerServiceId, |
|
||||
userType: 'manager' // 用户类型使用不同的字段名
|
|
||||
}; |
|
||||
|
|
||||
const messageString = JSON.stringify(authMessage); |
|
||||
console.log('📤 发送认证消息:', messageString); |
|
||||
console.log(' 消息长度:', messageString.length, '字节'); |
|
||||
|
|
||||
try { |
|
||||
const sent = ws.send(messageString); |
|
||||
console.log(' 发送结果:', sent ? '成功放入发送队列' : '发送失败'); |
|
||||
} catch (e) { |
|
||||
console.error(' 发送时异常:', e.message); |
|
||||
} |
|
||||
}, 100); |
|
||||
}); |
|
||||
|
|
||||
// 接收消息事件
|
|
||||
ws.on('message', (data) => { |
|
||||
console.log('📥 收到服务器消息:'); |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log(' 消息内容:', JSON.stringify(message, null, 2)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('🎉 认证成功!'); |
|
||||
} else if (message.type === 'auth_error') { |
|
||||
console.log('❌ 认证失败:', message.message); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error(' 解析消息失败:', e.message); |
|
||||
console.log(' 原始消息:', data.toString()); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
// 关闭事件
|
|
||||
ws.on('close', (code, reason) => { |
|
||||
console.log('❌ WebSocket连接已关闭'); |
|
||||
console.log(' 关闭代码:', code); |
|
||||
console.log(' 关闭原因:', reason.toString()); |
|
||||
|
|
||||
// 常见关闭代码说明
|
|
||||
if (code === 1000) console.log(' 说明: 正常关闭'); |
|
||||
if (code === 1001) console.log(' 说明: 终端离开'); |
|
||||
if (code === 1006) console.log(' 说明: 连接意外关闭'); |
|
||||
if (code === 1011) console.log(' 说明: 服务器内部错误'); |
|
||||
}); |
|
||||
|
|
||||
// 错误事件
|
|
||||
ws.on('error', (error) => { |
|
||||
console.error('❌ WebSocket错误:'); |
|
||||
console.error(' 错误类型:', error.name); |
|
||||
console.error(' 错误消息:', error.message); |
|
||||
console.error(' 错误堆栈:', error.stack); |
|
||||
}); |
|
||||
|
|
||||
// 发送缓冲区事件
|
|
||||
ws.on('drain', () => { |
|
||||
console.log('🗑️ 发送缓冲区已清空'); |
|
||||
}); |
|
||||
|
|
||||
// 连接超时处理
|
|
||||
setTimeout(() => { |
|
||||
if (ws.readyState === WebSocket.OPEN) { |
|
||||
console.log('⏰ 10秒超时,关闭连接'); |
|
||||
ws.close(); |
|
||||
} |
|
||||
}, 10000); |
|
||||
|
|
||||
// 定期检查连接状态
|
|
||||
let checkInterval = setInterval(() => { |
|
||||
const state = { |
|
||||
0: 'CONNECTING', |
|
||||
1: 'OPEN', |
|
||||
2: 'CLOSING', |
|
||||
3: 'CLOSED' |
|
||||
}[ws.readyState]; |
|
||||
|
|
||||
console.log(`🔄 连接状态: ${state}`); |
|
||||
|
|
||||
if (ws.readyState === WebSocket.CLOSED) { |
|
||||
clearInterval(checkInterval); |
|
||||
console.log('\n=== 调试结束 ==='); |
|
||||
} |
|
||||
}, 1000); |
|
||||
|
|
||||
console.log('=== 开始调试 ==='); |
|
||||
console.log('按Ctrl+C停止调试'); |
|
||||
@ -1,193 +0,0 @@ |
|||||
// 完整聊天流程调试脚本
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
const WS_URL = 'ws://localhost:3003'; |
|
||||
const TEST_MANAGER_ID = '22'; |
|
||||
const TEST_CUSTOMER_ID = 'test_customer_1'; |
|
||||
let customerWs = null; |
|
||||
let managerWs = null; |
|
||||
let currentConversationId = null; |
|
||||
|
|
||||
// 启动调试
|
|
||||
async function startDebug() { |
|
||||
console.log('=== 启动完整聊天流程调试 ==='); |
|
||||
|
|
||||
try { |
|
||||
// 连接客服WebSocket
|
|
||||
await connectManager(); |
|
||||
|
|
||||
// 连接客户WebSocket
|
|
||||
await connectCustomer(); |
|
||||
|
|
||||
// 等待连接稳定
|
|
||||
await new Promise(resolve => setTimeout(resolve, 2000)); |
|
||||
|
|
||||
// 客户发送消息
|
|
||||
await customerSendMessage(); |
|
||||
|
|
||||
// 等待客服收到消息
|
|
||||
await new Promise(resolve => setTimeout(resolve, 3000)); |
|
||||
|
|
||||
// 如果会话ID有效,客服回复消息
|
|
||||
if (currentConversationId) { |
|
||||
await managerReplyMessage(currentConversationId); |
|
||||
} |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 调试过程中出现错误:', error); |
|
||||
} finally { |
|
||||
console.log('=== 调试结束 ==='); |
|
||||
if (customerWs && customerWs.readyState === WebSocket.OPEN) { |
|
||||
customerWs.close(); |
|
||||
} |
|
||||
if (managerWs && managerWs.readyState === WebSocket.OPEN) { |
|
||||
managerWs.close(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 连接客服WebSocket
|
|
||||
function connectManager() { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
managerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
managerWs.on('open', () => { |
|
||||
console.log('✅ 客服WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
userType: 'manager' |
|
||||
}); |
|
||||
managerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('message', (data) => { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客服收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客服认证成功'); |
|
||||
resolve(); |
|
||||
} else if (message.type === 'new_message' && message.payload) { |
|
||||
// 记录会话ID
|
|
||||
if (message.payload.conversationId) { |
|
||||
currentConversationId = message.payload.conversationId; |
|
||||
console.log(`📝 获取到会话ID: ${currentConversationId}`); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('error', (error) => { |
|
||||
console.error('❌ 客服WebSocket错误:', error); |
|
||||
reject(error); |
|
||||
}); |
|
||||
|
|
||||
setTimeout(() => { |
|
||||
reject(new Error('客服连接或认证超时')); |
|
||||
}, 5000); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 连接客户WebSocket
|
|
||||
function connectCustomer() { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
customerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
customerWs.on('open', () => { |
|
||||
console.log('✅ 客户WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
userId: TEST_CUSTOMER_ID, |
|
||||
userType: 'user' |
|
||||
}); |
|
||||
customerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
customerWs.on('message', (data) => { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客户收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客户认证成功'); |
|
||||
resolve(); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
customerWs.on('error', (error) => { |
|
||||
console.error('❌ 客户WebSocket错误:', error); |
|
||||
reject(error); |
|
||||
}); |
|
||||
|
|
||||
setTimeout(() => { |
|
||||
reject(new Error('客户连接或认证超时')); |
|
||||
}, 5000); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 客户发送消息
|
|
||||
function customerSendMessage() { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
const messageId = 'test_customer_' + Date.now(); |
|
||||
const message = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: messageId, |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
content: '你好,我是测试客户,有问题咨询', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('📤 客户发送消息:', JSON.stringify(message)); |
|
||||
customerWs.send(JSON.stringify(message)); |
|
||||
|
|
||||
// 等待发送确认
|
|
||||
const messageHandler = (data) => { |
|
||||
const response = JSON.parse(data.toString()); |
|
||||
if (response.type === 'message_sent' && response.payload.messageId === messageId) { |
|
||||
customerWs.off('message', messageHandler); |
|
||||
console.log('✅ 客户消息发送成功'); |
|
||||
resolve(); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
customerWs.on('message', messageHandler); |
|
||||
|
|
||||
setTimeout(() => { |
|
||||
customerWs.off('message', messageHandler); |
|
||||
reject(new Error('客户消息发送超时')); |
|
||||
}, 5000); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 客服回复消息
|
|
||||
function managerReplyMessage(conversationId) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
const messageId = 'test_manager_' + Date.now(); |
|
||||
// 尝试使用更简单的格式,只包含最基本的字段
|
|
||||
// 参考客户发送消息的格式,但使用conversationId而不是managerId
|
|
||||
const replyMessage = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
content: '您好,我是客服,请问有什么可以帮助您的?', // 必须字段
|
|
||||
conversationId: conversationId, // 必须字段,确定会话
|
|
||||
contentType: 1 // 必须字段
|
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('📤 客服发送回复消息:', JSON.stringify(replyMessage)); |
|
||||
managerWs.send(JSON.stringify(replyMessage)); |
|
||||
|
|
||||
// 设置超时
|
|
||||
setTimeout(() => { |
|
||||
resolve(); |
|
||||
}, 3000); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 启动调试
|
|
||||
startDebug(); |
|
||||
@ -1,112 +0,0 @@ |
|||||
// 最终调试脚本
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
const WS_URL = 'ws://localhost:3003'; |
|
||||
const TEST_MANAGER_ID = '22'; |
|
||||
const TEST_CONVERSATION_ID = '4fa4b92f-df20-40ae-94b9-f906753a4cfd'; |
|
||||
let managerWs = null; |
|
||||
let startTime = null; |
|
||||
|
|
||||
console.log('=== 启动最终调试 ==='); |
|
||||
console.log(`测试会话ID: ${TEST_CONVERSATION_ID}`); |
|
||||
|
|
||||
// 连接客服WebSocket
|
|
||||
managerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
managerWs.on('open', () => { |
|
||||
console.log('✅ 客服WebSocket连接已建立'); |
|
||||
startTime = Date.now(); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
userType: 'manager' |
|
||||
}); |
|
||||
console.log('📤 客服发送认证消息:', authMsg); |
|
||||
managerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log(`📥 客服收到消息 (${Date.now() - startTime}ms):`, JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客服认证成功'); |
|
||||
|
|
||||
// 等待1秒后发送测试消息
|
|
||||
setTimeout(() => { |
|
||||
sendTestMessage(); |
|
||||
}, 1000); |
|
||||
} |
|
||||
|
|
||||
if (message.type === 'error') { |
|
||||
console.error('❌ 接收到错误消息:', message.message); |
|
||||
|
|
||||
// 如果收到错误,尝试发送替代格式
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n🔄 尝试替代格式...'); |
|
||||
sendAlternativeFormat(); |
|
||||
}, 2000); |
|
||||
} |
|
||||
|
|
||||
if (message.type === 'message_sent') { |
|
||||
console.log('✅ 消息发送成功!'); |
|
||||
|
|
||||
// 5秒后关闭连接
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n=== 调试成功完成 ==='); |
|
||||
managerWs.close(); |
|
||||
}, 5000); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('error', (error) => { |
|
||||
console.error('❌ 客服WebSocket错误:', error); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('close', () => { |
|
||||
console.log('❌ 客服WebSocket连接已关闭'); |
|
||||
}); |
|
||||
|
|
||||
// 发送测试消息
|
|
||||
function sendTestMessage() { |
|
||||
const messageId = 'test_manager_' + Date.now(); |
|
||||
const testMessage = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: messageId, |
|
||||
conversationId: TEST_CONVERSATION_ID, |
|
||||
content: '测试消息:这是客服发送的测试消息', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('\n📤 客服发送消息:', JSON.stringify(testMessage)); |
|
||||
managerWs.send(JSON.stringify(testMessage)); |
|
||||
} |
|
||||
|
|
||||
// 发送替代格式消息
|
|
||||
function sendAlternativeFormat() { |
|
||||
const messageId = 'test_manager_alt_' + Date.now(); |
|
||||
const alternativeMessage = { |
|
||||
type: 'chat_message', |
|
||||
messageId: messageId, |
|
||||
conversationId: TEST_CONVERSATION_ID, |
|
||||
content: '测试替代格式:不使用payload包装', |
|
||||
contentType: 1 |
|
||||
}; |
|
||||
|
|
||||
console.log('📤 客服发送替代格式消息:', JSON.stringify(alternativeMessage)); |
|
||||
managerWs.send(JSON.stringify(alternativeMessage)); |
|
||||
|
|
||||
// 5秒后关闭连接
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n=== 调试结束 ==='); |
|
||||
managerWs.close(); |
|
||||
}, 5000); |
|
||||
} |
|
||||
@ -1,215 +0,0 @@ |
|||||
// 完整流程调试脚本
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
const WS_URL = 'ws://localhost:3003'; |
|
||||
const TEST_MANAGER_ID = '22'; |
|
||||
let managerWs = null; |
|
||||
let userWs = null; |
|
||||
let newConversationId = null; |
|
||||
let testUserId = 'test_customer_' + Date.now(); |
|
||||
|
|
||||
console.log('=== 启动完整流程调试 ==='); |
|
||||
console.log(`测试用户ID: ${testUserId}`); |
|
||||
|
|
||||
// 步骤1: 连接客服并认证
|
|
||||
function connectManager() { |
|
||||
return new Promise((resolve) => { |
|
||||
managerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
managerWs.on('open', () => { |
|
||||
console.log('✅ 客服WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
userType: 'manager' |
|
||||
}); |
|
||||
console.log('📤 客服发送认证消息:', authMsg); |
|
||||
managerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客服收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客服认证成功'); |
|
||||
resolve(); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 客服解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 步骤2: 连接用户并认证
|
|
||||
function connectUser() { |
|
||||
return new Promise((resolve) => { |
|
||||
userWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
userWs.on('open', () => { |
|
||||
console.log('✅ 客户WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
userId: testUserId, |
|
||||
userType: 'user' |
|
||||
}); |
|
||||
console.log('📤 客户发送认证消息:', authMsg); |
|
||||
userWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
userWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客户收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客户认证成功'); |
|
||||
resolve(); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 客户解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 步骤3: 用户发送消息创建新会话
|
|
||||
function userSendMessage() { |
|
||||
return new Promise((resolve) => { |
|
||||
const messageId = 'test_user_' + Date.now(); |
|
||||
const userMessage = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: messageId, |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
content: '你好,我是测试客户,我想咨询一个问题', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('\n📤 客户发送消息:', JSON.stringify(userMessage)); |
|
||||
userWs.send(JSON.stringify(userMessage)); |
|
||||
|
|
||||
// 监听消息发送成功确认
|
|
||||
const userMessageHandler = (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
if (message.type === 'message_sent') { |
|
||||
console.log('✅ 客户消息发送成功确认'); |
|
||||
newConversationId = message.payload.conversationId; |
|
||||
console.log('📝 新创建的会话ID:', newConversationId); |
|
||||
userWs.removeListener('message', userMessageHandler); |
|
||||
resolve(); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 解析用户消息响应失败:', e); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
userWs.addListener('message', userMessageHandler); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 步骤4: 客服使用新会话ID回复消息
|
|
||||
function managerReplyMessage() { |
|
||||
return new Promise((resolve) => { |
|
||||
if (!newConversationId) { |
|
||||
console.error('❌ 没有获取到会话ID'); |
|
||||
resolve(false); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
const messageId = 'test_manager_' + Date.now(); |
|
||||
const replyMessage = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: messageId, |
|
||||
conversationId: newConversationId, |
|
||||
content: '您好,我是客服,请问有什么可以帮助您的?', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('\n📤 客服发送回复消息:', JSON.stringify(replyMessage)); |
|
||||
managerWs.send(JSON.stringify(replyMessage)); |
|
||||
|
|
||||
// 监听回复消息的结果
|
|
||||
const managerMessageHandler = (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客服收到回复结果:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'error') { |
|
||||
console.error('❌ 客服回复失败:', message.message); |
|
||||
managerWs.removeListener('message', managerMessageHandler); |
|
||||
resolve(false); |
|
||||
} else if (message.type === 'message_sent') { |
|
||||
console.log('✅ 客服回复发送成功!'); |
|
||||
managerWs.removeListener('message', managerMessageHandler); |
|
||||
resolve(true); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 解析客服消息响应失败:', e); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
managerWs.addListener('message', managerMessageHandler); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 主函数
|
|
||||
async function main() { |
|
||||
try { |
|
||||
// 连接客服
|
|
||||
await connectManager(); |
|
||||
await new Promise(resolve => setTimeout(resolve, 1000)); |
|
||||
|
|
||||
// 连接用户
|
|
||||
await connectUser(); |
|
||||
await new Promise(resolve => setTimeout(resolve, 1000)); |
|
||||
|
|
||||
// 用户发送消息创建会话
|
|
||||
await userSendMessage(); |
|
||||
await new Promise(resolve => setTimeout(resolve, 2000)); |
|
||||
|
|
||||
// 客服回复消息
|
|
||||
const success = await managerReplyMessage(); |
|
||||
|
|
||||
if (!success) { |
|
||||
console.log('\n🔄 尝试替代格式...'); |
|
||||
// 尝试不使用payload包装
|
|
||||
const messageId = 'test_manager_alt_' + Date.now(); |
|
||||
const alternativeMessage = { |
|
||||
type: 'chat_message', |
|
||||
messageId: messageId, |
|
||||
conversationId: newConversationId, |
|
||||
content: '测试替代格式:不使用payload包装', |
|
||||
contentType: 1 |
|
||||
}; |
|
||||
|
|
||||
console.log('📤 客服发送替代格式消息:', JSON.stringify(alternativeMessage)); |
|
||||
managerWs.send(JSON.stringify(alternativeMessage)); |
|
||||
} |
|
||||
|
|
||||
// 等待5秒后关闭连接
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n=== 调试结束 ==='); |
|
||||
if (managerWs) managerWs.close(); |
|
||||
if (userWs) userWs.close(); |
|
||||
}, 5000); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 调试过程中出错:', error); |
|
||||
if (managerWs) managerWs.close(); |
|
||||
if (userWs) userWs.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 启动调试
|
|
||||
main(); |
|
||||
@ -1,86 +0,0 @@ |
|||||
// 服务器日志调试脚本
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
const WS_URL = 'ws://localhost:3003'; |
|
||||
const TEST_MANAGER_ID = '22'; |
|
||||
let managerWs = null; |
|
||||
|
|
||||
console.log('=== 启动服务器日志调试 ==='); |
|
||||
|
|
||||
// 连接客服WebSocket
|
|
||||
managerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
managerWs.on('open', () => { |
|
||||
console.log('✅ 客服WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
userType: 'manager' |
|
||||
}); |
|
||||
console.log('📤 客服发送认证消息'); |
|
||||
managerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客服收到消息类型:', message.type); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客服认证成功'); |
|
||||
|
|
||||
// 等待2秒后发送测试消息
|
|
||||
setTimeout(() => { |
|
||||
sendTestMessage(); |
|
||||
}, 2000); |
|
||||
} |
|
||||
|
|
||||
if (message.type === 'error') { |
|
||||
console.error('❌ 错误消息:', message.message); |
|
||||
} |
|
||||
|
|
||||
if (message.type === 'message_sent') { |
|
||||
console.log('✅ 消息发送成功!'); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('error', (error) => { |
|
||||
console.error('❌ WebSocket错误:', error); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('close', () => { |
|
||||
console.log('❌ WebSocket连接已关闭'); |
|
||||
}); |
|
||||
|
|
||||
// 发送测试消息
|
|
||||
function sendTestMessage() { |
|
||||
// 使用一个固定的会话ID进行测试
|
|
||||
const conversationId = '4fa4b92f-df20-40ae-94b9-f906753a4cfd'; |
|
||||
const messageId = 'test_debug_' + Date.now(); |
|
||||
|
|
||||
console.log(`\n📤 发送测试消息 - 会话ID: ${conversationId}, 消息ID: ${messageId}`); |
|
||||
|
|
||||
const testMessage = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: messageId, |
|
||||
conversationId: conversationId, |
|
||||
content: '服务器日志调试消息', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
managerWs.send(JSON.stringify(testMessage)); |
|
||||
|
|
||||
// 5秒后退出
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n=== 调试结束 ==='); |
|
||||
managerWs.close(); |
|
||||
process.exit(0); |
|
||||
}, 5000); |
|
||||
} |
|
||||
@ -1,111 +0,0 @@ |
|||||
// 极简调试脚本
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
const WS_URL = 'ws://localhost:3003'; |
|
||||
const TEST_MANAGER_ID = '22'; |
|
||||
let managerWs = null; |
|
||||
|
|
||||
// 启动调试
|
|
||||
function startDebug() { |
|
||||
console.log('=== 启动极简调试 ==='); |
|
||||
|
|
||||
// 连接客服WebSocket
|
|
||||
managerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
managerWs.on('open', () => { |
|
||||
console.log('✅ 客服WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
userType: 'manager' |
|
||||
}); |
|
||||
managerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客服认证成功'); |
|
||||
|
|
||||
// 等待2秒后发送测试消息
|
|
||||
setTimeout(() => { |
|
||||
// 尝试发送测试消息,使用不同的格式
|
|
||||
sendTestMessage(); |
|
||||
}, 2000); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('error', (error) => { |
|
||||
console.error('❌ WebSocket错误:', error); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('close', () => { |
|
||||
console.log('❌ WebSocket连接已关闭'); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 发送测试消息
|
|
||||
function sendTestMessage() { |
|
||||
console.log('\n🔄 测试不同的消息格式...'); |
|
||||
|
|
||||
// 测试格式1: 不使用payload包装
|
|
||||
const format1 = { |
|
||||
type: 'chat_message', |
|
||||
conversationId: '4fa4b92f-df20-40ae-94b9-f906753a4cfd', |
|
||||
content: '测试格式1: 不使用payload包装', |
|
||||
contentType: 1 |
|
||||
}; |
|
||||
|
|
||||
console.log('\n📤 发送格式1:', JSON.stringify(format1)); |
|
||||
managerWs.send(JSON.stringify(format1)); |
|
||||
|
|
||||
// 等待1秒后发送下一个格式
|
|
||||
setTimeout(() => { |
|
||||
// 测试格式2: 使用payload包装,但字段名改为驼峰式
|
|
||||
const format2 = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
conversationId: '4fa4b92f-df20-40ae-94b9-f906753a4cfd', |
|
||||
content: '测试格式2: 使用payload包装', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('\n📤 发送格式2:', JSON.stringify(format2)); |
|
||||
managerWs.send(JSON.stringify(format2)); |
|
||||
|
|
||||
// 等待1秒后发送下一个格式
|
|
||||
setTimeout(() => { |
|
||||
// 测试格式3: 使用payload包装,添加messageId
|
|
||||
const format3 = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: 'test_' + Date.now(), |
|
||||
conversationId: '4fa4b92f-df20-40ae-94b9-f906753a4cfd', |
|
||||
content: '测试格式3: 添加messageId', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('\n📤 发送格式3:', JSON.stringify(format3)); |
|
||||
managerWs.send(JSON.stringify(format3)); |
|
||||
|
|
||||
// 等待5秒后关闭连接
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n=== 调试结束 ==='); |
|
||||
managerWs.close(); |
|
||||
}, 5000); |
|
||||
}, 1000); |
|
||||
}, 1000); |
|
||||
} |
|
||||
|
|
||||
// 启动调试
|
|
||||
startDebug(); |
|
||||
@ -1,191 +0,0 @@ |
|||||
// 详细调试脚本,带更多日志记录
|
|
||||
const WebSocket = require('ws'); |
|
||||
|
|
||||
const WS_URL = 'ws://localhost:3003'; |
|
||||
const TEST_MANAGER_ID = '22'; |
|
||||
const TEST_CONVERSATION_ID = '4fa4b92f-df20-40ae-94b9-f906753a4cfd'; // 使用已知的会话ID
|
|
||||
let managerWs = null; |
|
||||
let userWs = null; |
|
||||
|
|
||||
console.log('=== 启动详细调试 ==='); |
|
||||
console.log(`测试会话ID: ${TEST_CONVERSATION_ID}`); |
|
||||
|
|
||||
// 连接客服WebSocket
|
|
||||
function connectManager() { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
managerWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
managerWs.on('open', () => { |
|
||||
console.log('✅ 客服WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
managerId: TEST_MANAGER_ID, |
|
||||
userType: 'manager' |
|
||||
}); |
|
||||
console.log('📤 客服发送认证消息:', authMsg); |
|
||||
managerWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客服收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客服认证成功'); |
|
||||
resolve(); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 客服解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('error', (error) => { |
|
||||
console.error('❌ 客服WebSocket错误:', error); |
|
||||
reject(error); |
|
||||
}); |
|
||||
|
|
||||
managerWs.on('close', () => { |
|
||||
console.log('❌ 客服WebSocket连接已关闭'); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 连接用户WebSocket
|
|
||||
function connectUser() { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
const userId = 'test_customer_' + Date.now(); |
|
||||
userWs = new WebSocket(WS_URL); |
|
||||
|
|
||||
userWs.on('open', () => { |
|
||||
console.log('✅ 客户WebSocket连接已建立'); |
|
||||
|
|
||||
// 发送认证消息
|
|
||||
const authMsg = JSON.stringify({ |
|
||||
type: 'auth', |
|
||||
userId: userId, |
|
||||
userType: 'user' |
|
||||
}); |
|
||||
console.log('📤 客户发送认证消息:', authMsg); |
|
||||
userWs.send(authMsg); |
|
||||
}); |
|
||||
|
|
||||
userWs.on('message', (data) => { |
|
||||
try { |
|
||||
const message = JSON.parse(data.toString()); |
|
||||
console.log('📥 客户收到消息:', JSON.stringify(message)); |
|
||||
|
|
||||
if (message.type === 'auth_success') { |
|
||||
console.log('✅ 客户认证成功'); |
|
||||
resolve(); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 客户解析消息失败:', e); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
userWs.on('error', (error) => { |
|
||||
console.error('❌ 客户WebSocket错误:', error); |
|
||||
reject(error); |
|
||||
}); |
|
||||
|
|
||||
userWs.on('close', () => { |
|
||||
console.log('❌ 客户WebSocket连接已关闭'); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 发送测试消息
|
|
||||
function sendTestMessage() { |
|
||||
return new Promise((resolve) => { |
|
||||
console.log('\n🔄 客服发送测试消息...'); |
|
||||
|
|
||||
const messageId = 'test_manager_' + Date.now(); |
|
||||
const testMessage = { |
|
||||
type: 'chat_message', |
|
||||
payload: { |
|
||||
messageId: messageId, |
|
||||
conversationId: TEST_CONVERSATION_ID, |
|
||||
content: '测试消息:这是客服发送的测试消息', |
|
||||
contentType: 1 |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
console.log('📤 客服发送消息:', JSON.stringify(testMessage)); |
|
||||
managerWs.send(JSON.stringify(testMessage)); |
|
||||
|
|
||||
// 监听错误响应
|
|
||||
const originalOnMessage = managerWs.onmessage; |
|
||||
managerWs.onmessage = (event) => { |
|
||||
originalOnMessage(event); |
|
||||
try { |
|
||||
const message = JSON.parse(event.data.toString()); |
|
||||
if (message.type === 'error') { |
|
||||
console.error('❌ 接收到错误消息:', message.message); |
|
||||
resolve(false); |
|
||||
} else if (message.type === 'message_sent') { |
|
||||
console.log('✅ 消息发送成功确认'); |
|
||||
resolve(true); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
console.error('❌ 解析响应消息失败:', e); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
// 5秒后超时
|
|
||||
setTimeout(() => { |
|
||||
console.log('⌛ 消息发送超时'); |
|
||||
resolve(false); |
|
||||
}, 5000); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 主函数
|
|
||||
async function main() { |
|
||||
try { |
|
||||
// 连接客服
|
|
||||
await connectManager(); |
|
||||
await new Promise(resolve => setTimeout(resolve, 1000)); |
|
||||
|
|
||||
// 连接用户(可选)
|
|
||||
// await connectUser();
|
|
||||
// await new Promise(resolve => setTimeout(resolve, 1000));
|
|
||||
|
|
||||
// 发送测试消息
|
|
||||
const success = await sendTestMessage(); |
|
||||
|
|
||||
if (!success) { |
|
||||
console.log('\n🔄 尝试另一种格式...'); |
|
||||
|
|
||||
// 尝试不使用payload包装
|
|
||||
const messageId = 'test_manager_alt_' + Date.now(); |
|
||||
const alternativeMessage = { |
|
||||
type: 'chat_message', |
|
||||
messageId: messageId, |
|
||||
conversationId: TEST_CONVERSATION_ID, |
|
||||
content: '测试替代格式:不使用payload包装', |
|
||||
contentType: 1 |
|
||||
}; |
|
||||
|
|
||||
console.log('📤 客服发送替代格式消息:', JSON.stringify(alternativeMessage)); |
|
||||
managerWs.send(JSON.stringify(alternativeMessage)); |
|
||||
} |
|
||||
|
|
||||
// 等待5秒后关闭连接
|
|
||||
setTimeout(() => { |
|
||||
console.log('\n=== 调试结束 ==='); |
|
||||
if (managerWs) managerWs.close(); |
|
||||
if (userWs) userWs.close(); |
|
||||
}, 5000); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 调试过程中出错:', error); |
|
||||
if (managerWs) managerWs.close(); |
|
||||
if (userWs) userWs.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 启动调试
|
|
||||
main(); |
|
||||
@ -1,175 +0,0 @@ |
|||||
// 直接连接数据库检查productQuantity字段的脚本
|
|
||||
const Sequelize = require('sequelize'); |
|
||||
const mysql = require('mysql2/promise'); |
|
||||
|
|
||||
// 数据库连接配置
|
|
||||
const sequelize = new Sequelize( |
|
||||
'minishop', // 数据库名
|
|
||||
'root', // 用户名
|
|
||||
'password', // 密码
|
|
||||
{ |
|
||||
host: 'localhost', |
|
||||
dialect: 'mysql', |
|
||||
pool: { |
|
||||
max: 5, |
|
||||
min: 0, |
|
||||
acquire: 30000, |
|
||||
idle: 10000 |
|
||||
}, |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
} |
|
||||
); |
|
||||
|
|
||||
// 定义购物车模型 - 直接复制自server-mysql.js
|
|
||||
class CartItem extends Sequelize.Model {} |
|
||||
CartItem.init({ |
|
||||
id: { |
|
||||
type: Sequelize.DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
userId: { |
|
||||
type: Sequelize.DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
productId: { |
|
||||
type: Sequelize.DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
productName: { |
|
||||
type: Sequelize.DataTypes.STRING(255), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
specification: { |
|
||||
type: Sequelize.DataTypes.STRING(255) |
|
||||
}, |
|
||||
quantity: { |
|
||||
type: Sequelize.DataTypes.INTEGER, |
|
||||
allowNull: false, |
|
||||
defaultValue: 1 |
|
||||
}, |
|
||||
productQuantity: { |
|
||||
type: Sequelize.DataTypes.INTEGER, |
|
||||
allowNull: false, |
|
||||
defaultValue: 0 |
|
||||
}, |
|
||||
grossWeight: { |
|
||||
type: Sequelize.DataTypes.DECIMAL(10, 2) |
|
||||
}, |
|
||||
yolk: { |
|
||||
type: Sequelize.DataTypes.STRING(100) |
|
||||
}, |
|
||||
price: { |
|
||||
type: Sequelize.DataTypes.DECIMAL(10, 2) |
|
||||
}, |
|
||||
selected: { |
|
||||
type: Sequelize.DataTypes.BOOLEAN, |
|
||||
defaultValue: true |
|
||||
}, |
|
||||
added_at: { |
|
||||
type: Sequelize.DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize, |
|
||||
modelName: 'CartItem', |
|
||||
tableName: 'cart_items', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// 检查数据库结构
|
|
||||
async function checkDatabaseStructure() { |
|
||||
console.log('开始直接检查数据库中的productQuantity字段...'); |
|
||||
|
|
||||
try { |
|
||||
// 检查连接
|
|
||||
await sequelize.authenticate(); |
|
||||
console.log('✅ 数据库连接成功'); |
|
||||
|
|
||||
// 1. 使用原始查询检查表结构
|
|
||||
console.log('\n1. 检查cart_items表结构...'); |
|
||||
const [fields, _] = await sequelize.query('DESCRIBE cart_items'); |
|
||||
|
|
||||
// 查找productQuantity字段
|
|
||||
const productQuantityField = fields.find(field => field.Field === 'productQuantity'); |
|
||||
|
|
||||
if (productQuantityField) { |
|
||||
console.log('✅ 数据库中存在productQuantity字段:'); |
|
||||
console.log(` - 类型: ${productQuantityField.Type}`); |
|
||||
console.log(` - 是否允许NULL: ${productQuantityField.Null === 'YES' ? '是' : '否'}`); |
|
||||
console.log(` - 默认值: ${productQuantityField.Default || '无'}`); |
|
||||
} else { |
|
||||
console.error('❌ 数据库中不存在productQuantity字段!'); |
|
||||
console.log('cart_items表中的所有字段:', fields.map(field => field.Field).join(', ')); |
|
||||
|
|
||||
// 如果不存在,尝试添加这个字段
|
|
||||
console.log('\n尝试添加productQuantity字段到cart_items表...'); |
|
||||
try { |
|
||||
await sequelize.query('ALTER TABLE cart_items ADD COLUMN productQuantity INT NOT NULL DEFAULT 0'); |
|
||||
console.log('✅ 成功添加productQuantity字段'); |
|
||||
} catch (addError) { |
|
||||
console.error('❌ 添加字段失败:', addError.message); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 2. 检查test_user_id的购物车数据
|
|
||||
console.log('\n2. 检查测试用户的购物车数据...'); |
|
||||
const cartItems = await CartItem.findAll({ |
|
||||
where: { |
|
||||
userId: 'test_user_id' |
|
||||
}, |
|
||||
// 明确指定返回所有字段
|
|
||||
attributes: { |
|
||||
exclude: [] // 不排除任何字段
|
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
console.log(`找到 ${cartItems.length} 条购物车记录`); |
|
||||
|
|
||||
if (cartItems.length > 0) { |
|
||||
// 显示第一条记录的所有字段
|
|
||||
console.log('\n第一条购物车记录的所有字段:'); |
|
||||
const firstItem = cartItems[0].toJSON(); |
|
||||
Object.keys(firstItem).forEach(key => { |
|
||||
console.log(` - ${key}: ${firstItem[key]}`); |
|
||||
}); |
|
||||
|
|
||||
// 特别检查productQuantity字段
|
|
||||
console.log('\nproductQuantity字段在数据中的状态:'); |
|
||||
cartItems.forEach((item, index) => { |
|
||||
const data = item.toJSON(); |
|
||||
console.log(` 记录 ${index + 1}: productQuantity = ${data.productQuantity !== undefined ? data.productQuantity : 'undefined'}`); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 3. 尝试直接插入一条带productQuantity的记录
|
|
||||
console.log('\n3. 尝试直接插入一条带productQuantity的记录...'); |
|
||||
const testProductId = 'db_test_' + Date.now(); |
|
||||
const newItem = await CartItem.create({ |
|
||||
userId: 'test_user_id', |
|
||||
productId: testProductId, |
|
||||
productName: '数据库测试商品', |
|
||||
specification: '测试规格', |
|
||||
quantity: 2, |
|
||||
productQuantity: 10, |
|
||||
grossWeight: 1000, |
|
||||
yolk: '测试蛋黄', |
|
||||
price: 50, |
|
||||
selected: true, |
|
||||
added_at: new Date() |
|
||||
}); |
|
||||
|
|
||||
console.log('✅ 成功插入记录'); |
|
||||
console.log('插入的记录详情:', newItem.toJSON()); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('检查过程中发生错误:', error.message); |
|
||||
} finally { |
|
||||
// 关闭连接
|
|
||||
await sequelize.close(); |
|
||||
console.log('\n数据库连接已关闭'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行检查
|
|
||||
checkDatabaseStructure(); |
|
||||
@ -1,61 +0,0 @@ |
|||||
// 查询特定名称商品的创建者
|
|
||||
|
|
||||
const dotenv = require('dotenv'); |
|
||||
const mysql = require('mysql2/promise'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 加载环境变量
|
|
||||
dotenv.config({ path: path.resolve(__dirname, '.env') }); |
|
||||
|
|
||||
// 数据库连接配置
|
|
||||
const dbConfig = { |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
user: process.env.DB_USER || 'root', |
|
||||
password: process.env.DB_PASSWORD || '', |
|
||||
database: process.env.DB_NAME || 'wechat_app', |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
}; |
|
||||
|
|
||||
async function findProductCreator() { |
|
||||
let connection; |
|
||||
try { |
|
||||
// 连接数据库
|
|
||||
connection = await mysql.createConnection(dbConfig); |
|
||||
console.log('数据库连接成功'); |
|
||||
|
|
||||
// 查询名称为88888的商品及其创建者
|
|
||||
const [products] = await connection.query(` |
|
||||
SELECT p.productId, p.productName, p.sellerId, u.userId, u.nickName, u.phoneNumber |
|
||||
FROM products p |
|
||||
LEFT JOIN users u ON p.sellerId = u.userId |
|
||||
WHERE p.productName = '88888' |
|
||||
`);
|
|
||||
|
|
||||
if (products.length === 0) { |
|
||||
console.log('未找到名称为88888的商品'); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
console.log(`找到 ${products.length} 个名称为88888的商品:`); |
|
||||
products.forEach((product, index) => { |
|
||||
console.log(`\n商品 ${index + 1}:`); |
|
||||
console.log(` 商品ID: ${product.productId}`); |
|
||||
console.log(` 商品名称: ${product.productName}`); |
|
||||
console.log(` 创建者ID: ${product.sellerId}`); |
|
||||
console.log(` 创建者昵称: ${product.nickName || '未设置'}`); |
|
||||
console.log(` 创建者手机号: ${product.phoneNumber || '未设置'}`); |
|
||||
}); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('查询失败:', error.message); |
|
||||
} finally { |
|
||||
if (connection) { |
|
||||
await connection.end(); |
|
||||
console.log('\n数据库连接已关闭'); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 执行查询
|
|
||||
findProductCreator(); |
|
||||
@ -1,85 +0,0 @@ |
|||||
// 简单测试服务器 - 不连接数据库,专注于API接口测试和毛重字段处理
|
|
||||
const express = require('express'); |
|
||||
const bodyParser = require('body-parser'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 创建Express应用
|
|
||||
const app = express(); |
|
||||
const PORT = 3000; |
|
||||
|
|
||||
// 中间件
|
|
||||
app.use(bodyParser.json()); |
|
||||
|
|
||||
// 请求日志中间件
|
|
||||
app.use((req, res, next) => { |
|
||||
const now = new Date(); |
|
||||
console.log(`[${now.toISOString()}] 收到请求: ${req.method} ${req.url}`); |
|
||||
next(); |
|
||||
}); |
|
||||
|
|
||||
// 简单测试接口
|
|
||||
app.get('/api/test-connection', (req, res) => { |
|
||||
res.json({ |
|
||||
success: true, |
|
||||
message: '服务器连接测试成功', |
|
||||
timestamp: new Date().toISOString(), |
|
||||
serverInfo: { port: PORT } |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
// 商品发布接口(简化版,专注于毛重处理)
|
|
||||
app.post('/api/product/publish', (req, res) => { |
|
||||
try { |
|
||||
const { openid, product } = req.body; |
|
||||
console.log('收到商品发布请求:', { openid, product }); |
|
||||
|
|
||||
// 验证参数
|
|
||||
if (!openid || !product) { |
|
||||
return res.status(400).json({ success: false, message: '缺少必要参数' }); |
|
||||
} |
|
||||
|
|
||||
// 重点:毛重字段处理逻辑
|
|
||||
let grossWeightValue = product.grossWeight; |
|
||||
console.log('原始毛重值:', grossWeightValue, '类型:', typeof grossWeightValue); |
|
||||
|
|
||||
// 处理各种情况的毛重值
|
|
||||
if (grossWeightValue === '' || grossWeightValue === null || grossWeightValue === undefined || (typeof grossWeightValue === 'object' && grossWeightValue === null)) { |
|
||||
grossWeightValue = null; |
|
||||
console.log('毛重值为空或null,设置为null'); |
|
||||
} else { |
|
||||
// 转换为数字
|
|
||||
const numValue = Number(grossWeightValue); |
|
||||
if (!isNaN(numValue) && isFinite(numValue)) { |
|
||||
grossWeightValue = numValue; |
|
||||
console.log('毛重值成功转换为数字:', grossWeightValue); |
|
||||
} else { |
|
||||
grossWeightValue = null; |
|
||||
console.log('毛重值不是有效数字,设置为null'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 返回处理结果
|
|
||||
return res.json({ |
|
||||
success: true, |
|
||||
message: '商品发布处理成功(模拟)', |
|
||||
processedData: { |
|
||||
productName: product.productName, |
|
||||
price: product.price, |
|
||||
quantity: product.quantity, |
|
||||
grossWeight: grossWeightValue, // 返回处理后的毛重值
|
|
||||
grossWeightType: typeof grossWeightValue |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('发布商品失败:', error); |
|
||||
res.status(500).json({ success: false, message: '服务器错误', error: error.message }); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
// 启动服务器
|
|
||||
app.listen(PORT, () => { |
|
||||
console.log(`修复版服务器运行在 http://localhost:${PORT}`); |
|
||||
console.log('测试接口: http://localhost:3000/api/test-connection'); |
|
||||
console.log('商品发布接口: POST http://localhost:3000/api/product/publish'); |
|
||||
}); |
|
||||
Binary file not shown.
@ -1,218 +0,0 @@ |
|||||
// 更新商品审核状态脚本 - 将商品从pending_review改为reviewed
|
|
||||
const { Sequelize, DataTypes, Model } = require('sequelize'); |
|
||||
require('dotenv').config(); |
|
||||
const readline = require('readline'); |
|
||||
|
|
||||
// 创建读取用户输入的接口
|
|
||||
const rl = readline.createInterface({ |
|
||||
input: process.stdin, |
|
||||
output: process.stdout |
|
||||
}); |
|
||||
|
|
||||
// MySQL数据库连接配置
|
|
||||
const sequelize = new Sequelize( |
|
||||
process.env.DB_DATABASE || 'wechat_app', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD === undefined ? null : process.env.DB_PASSWORD, |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
pool: { |
|
||||
max: 10, |
|
||||
min: 0, |
|
||||
acquire: 30000, |
|
||||
idle: 10000 |
|
||||
}, |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
} |
|
||||
); |
|
||||
|
|
||||
// 定义Product模型
|
|
||||
class Product extends Model { } |
|
||||
Product.init({ |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
autoIncrement: true, |
|
||||
primaryKey: true |
|
||||
}, |
|
||||
productId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false, |
|
||||
unique: true |
|
||||
}, |
|
||||
sellerId: { |
|
||||
type: DataTypes.STRING(100), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
productName: { |
|
||||
type: DataTypes.STRING(255), |
|
||||
allowNull: false |
|
||||
}, |
|
||||
status: { |
|
||||
type: DataTypes.STRING(20), |
|
||||
defaultValue: 'pending_review', |
|
||||
validate: { |
|
||||
isIn: [['pending_review', 'reviewed', 'published', 'sold_out', 'rejected', 'hidden']] |
|
||||
} |
|
||||
}, |
|
||||
created_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW |
|
||||
}, |
|
||||
updated_at: { |
|
||||
type: DataTypes.DATE, |
|
||||
defaultValue: Sequelize.NOW, |
|
||||
onUpdate: Sequelize.NOW |
|
||||
} |
|
||||
}, { |
|
||||
sequelize, |
|
||||
modelName: 'Product', |
|
||||
tableName: 'products', |
|
||||
timestamps: false |
|
||||
}); |
|
||||
|
|
||||
// 测试数据库连接
|
|
||||
async function testDbConnection() { |
|
||||
try { |
|
||||
await sequelize.authenticate(); |
|
||||
console.log('数据库连接成功'); |
|
||||
} catch (error) { |
|
||||
console.error('数据库连接失败:', error); |
|
||||
console.error('请检查.env文件中的数据库配置是否正确'); |
|
||||
process.exit(1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 获取所有待审核商品
|
|
||||
async function getPendingReviewProducts() { |
|
||||
try { |
|
||||
const products = await Product.findAll({ |
|
||||
where: { |
|
||||
status: 'pending_review' |
|
||||
}, |
|
||||
attributes: ['id', 'productId', 'productName', 'created_at'] |
|
||||
}); |
|
||||
return products; |
|
||||
} catch (error) { |
|
||||
console.error('获取待审核商品失败:', error); |
|
||||
return []; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 更新单个商品状态
|
|
||||
async function updateSingleProduct(productId) { |
|
||||
try { |
|
||||
const result = await Product.update( |
|
||||
{ |
|
||||
status: 'reviewed', |
|
||||
updated_at: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
where: { |
|
||||
productId: productId |
|
||||
} |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
if (result[0] > 0) { |
|
||||
console.log(`成功更新商品状态: ${productId}`); |
|
||||
return true; |
|
||||
} else { |
|
||||
console.log(`未找到商品: ${productId} 或该商品状态不是待审核`); |
|
||||
return false; |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error(`更新商品状态失败: ${productId}`, error); |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 更新所有待审核商品状态
|
|
||||
async function updateAllProducts() { |
|
||||
try { |
|
||||
const result = await Product.update( |
|
||||
{ |
|
||||
status: 'reviewed', |
|
||||
updated_at: new Date() |
|
||||
}, |
|
||||
{ |
|
||||
where: { |
|
||||
status: 'pending_review' |
|
||||
} |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
console.log(`成功更新 ${result[0]} 个商品的状态`); |
|
||||
return result[0]; |
|
||||
} catch (error) { |
|
||||
console.error('批量更新商品状态失败:', error); |
|
||||
return 0; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 主函数
|
|
||||
async function main() { |
|
||||
try { |
|
||||
await testDbConnection(); |
|
||||
|
|
||||
// 获取待审核商品列表
|
|
||||
const pendingProducts = await getPendingReviewProducts(); |
|
||||
|
|
||||
if (pendingProducts.length === 0) { |
|
||||
console.log('当前没有待审核的商品'); |
|
||||
rl.close(); |
|
||||
process.exit(0); |
|
||||
} |
|
||||
|
|
||||
console.log(`\n找到 ${pendingProducts.length} 个待审核的商品:`); |
|
||||
pendingProducts.forEach((product, index) => { |
|
||||
console.log(`${index + 1}. ID: ${product.productId}, 名称: ${product.productName}, 创建时间: ${product.created_at.toLocaleString()}`); |
|
||||
}); |
|
||||
|
|
||||
// 询问用户要更新单个还是所有商品
|
|
||||
rl.question('\n请选择操作 (1: 更新单个商品, 2: 更新所有商品, 0: 退出): ', async (choice) => { |
|
||||
switch (choice) { |
|
||||
case '1': |
|
||||
rl.question('请输入要更新的商品ID: ', async (productId) => { |
|
||||
await updateSingleProduct(productId); |
|
||||
rl.close(); |
|
||||
}); |
|
||||
break; |
|
||||
|
|
||||
case '2': |
|
||||
rl.question('确定要更新所有待审核商品的状态吗? (y/n): ', async (confirm) => { |
|
||||
if (confirm.toLowerCase() === 'y') { |
|
||||
await updateAllProducts(); |
|
||||
} else { |
|
||||
console.log('已取消操作'); |
|
||||
} |
|
||||
rl.close(); |
|
||||
}); |
|
||||
break; |
|
||||
|
|
||||
case '0': |
|
||||
console.log('已退出'); |
|
||||
rl.close(); |
|
||||
break; |
|
||||
|
|
||||
default: |
|
||||
console.log('无效的选择'); |
|
||||
rl.close(); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
rl.on('close', () => { |
|
||||
console.log('\n操作已完成,小程序中刷新后即可看到已上架的货源'); |
|
||||
process.exit(0); |
|
||||
}); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('程序执行出错:', error); |
|
||||
rl.close(); |
|
||||
process.exit(1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 启动程序
|
|
||||
main(); |
|
||||
@ -1,285 +0,0 @@ |
|||||
const { Sequelize } = require('sequelize'); |
|
||||
const fs = require('fs'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 读取环境变量
|
|
||||
const envPath = path.join(__dirname, '.env'); |
|
||||
if (fs.existsSync(envPath)) { |
|
||||
const envContent = fs.readFileSync(envPath, 'utf8'); |
|
||||
const envVars = envContent.split('\n').filter(line => line.trim() && !line.startsWith('#')); |
|
||||
envVars.forEach(line => { |
|
||||
const [key, value] = line.split('=').map(part => part.trim()); |
|
||||
process.env[key] = value; |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 数据库连接配置
|
|
||||
const sequelize = new Sequelize( |
|
||||
process.env.DB_NAME || 'wechat_app', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD || '', |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
logging: false, |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
} |
|
||||
); |
|
||||
|
|
||||
/** |
|
||||
* 检查并修复所有用户的关联记录 |
|
||||
* 这个函数会扫描所有用户,并为每个用户创建缺失的关联记录 |
|
||||
*/ |
|
||||
async function checkAndFixAllUserAssociations() { |
|
||||
try { |
|
||||
console.log('========================================'); |
|
||||
console.log('检查并修复所有用户的关联记录'); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
// 连接数据库
|
|
||||
await sequelize.authenticate(); |
|
||||
console.log('✅ 数据库连接成功'); |
|
||||
|
|
||||
// 获取所有用户
|
|
||||
const users = await sequelize.query( |
|
||||
'SELECT userId, nickName, phoneNumber FROM users', |
|
||||
{ type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
console.log(`📊 共找到 ${users.length} 个用户记录`); |
|
||||
|
|
||||
let totalContactsCreated = 0; |
|
||||
let totalManagementsCreated = 0; |
|
||||
let fullyFixedUsers = 0; |
|
||||
let partiallyFixedUsers = 0; |
|
||||
let alreadyFixedUsers = 0; |
|
||||
|
|
||||
// 为每个用户检查并创建关联记录
|
|
||||
for (let i = 0; i < users.length; i++) { |
|
||||
const user = users[i]; |
|
||||
console.log(`\n🔄 处理用户 ${i + 1}/${users.length}: ${user.userId}`); |
|
||||
|
|
||||
let contactsCreated = 0; |
|
||||
let managementsCreated = 0; |
|
||||
|
|
||||
// 检查并创建联系人记录
|
|
||||
try { |
|
||||
const existingContact = await sequelize.query( |
|
||||
'SELECT * FROM contacts WHERE userId = ?', |
|
||||
{ replacements: [user.userId], type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
if (existingContact.length === 0) { |
|
||||
await sequelize.query( |
|
||||
'INSERT INTO contacts (userId, nickName, phoneNumber) VALUES (?, ?, ?)', |
|
||||
{ replacements: [user.userId, user.nickName || '默认联系人', user.phoneNumber || ''] } |
|
||||
); |
|
||||
console.log('✅ 创建了联系人记录'); |
|
||||
contactsCreated++; |
|
||||
} else { |
|
||||
console.log('✅ 联系人记录已存在'); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('❌ 创建联系人记录失败:', error.message); |
|
||||
} |
|
||||
|
|
||||
// 检查并创建用户管理记录
|
|
||||
try { |
|
||||
const existingManagement = await sequelize.query( |
|
||||
'SELECT * FROM usermanagements WHERE userId = ?', |
|
||||
{ replacements: [user.userId], type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
if (existingManagement.length === 0) { |
|
||||
await sequelize.query( |
|
||||
'INSERT INTO usermanagements (userId) VALUES (?)', |
|
||||
{ replacements: [user.userId] } |
|
||||
); |
|
||||
console.log('✅ 创建了用户管理记录'); |
|
||||
managementsCreated++; |
|
||||
} else { |
|
||||
console.log('✅ 用户管理记录已存在'); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('❌ 创建用户管理记录失败:', error.message); |
|
||||
} |
|
||||
|
|
||||
// 更新统计信息
|
|
||||
totalContactsCreated += contactsCreated; |
|
||||
totalManagementsCreated += managementsCreated; |
|
||||
|
|
||||
if (contactsCreated === 0 && managementsCreated === 0) { |
|
||||
alreadyFixedUsers++; |
|
||||
} else if (contactsCreated > 0 || managementsCreated > 0) { |
|
||||
if (contactsCreated > 0 && managementsCreated > 0) { |
|
||||
fullyFixedUsers++; |
|
||||
} else { |
|
||||
partiallyFixedUsers++; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
console.log('\n========================================'); |
|
||||
console.log('修复完成!'); |
|
||||
console.log(`📊 总计: ${users.length} 个用户`); |
|
||||
console.log(`✅ 已经完整的用户: ${alreadyFixedUsers} 个`); |
|
||||
console.log(`🔧 完全修复的用户: ${fullyFixedUsers} 个`); |
|
||||
console.log(`⚠️ 部分修复的用户: ${partiallyFixedUsers} 个`); |
|
||||
console.log(`📈 共创建了 ${totalContactsCreated} 条联系人记录`); |
|
||||
console.log(`📈 共创建了 ${totalManagementsCreated} 条用户管理记录`); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 修复过程中发生错误:', error.message); |
|
||||
console.error('错误详情:', error); |
|
||||
} finally { |
|
||||
// 关闭数据库连接
|
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 监控新用户并自动创建关联记录 |
|
||||
* 这个函数会定期检查新用户,并为其创建关联记录 |
|
||||
*/ |
|
||||
async function monitorAndAutoFixNewUsers(intervalMinutes = 10) { |
|
||||
console.log(`\n🔄 启动新用户监控,每 ${intervalMinutes} 分钟检查一次`); |
|
||||
|
|
||||
// 保存上次检查的最大用户ID
|
|
||||
let lastCheckedUserId = ''; |
|
||||
|
|
||||
async function checkNewUsers() { |
|
||||
try { |
|
||||
// 连接数据库
|
|
||||
await sequelize.authenticate(); |
|
||||
|
|
||||
// 获取最新的用户ID
|
|
||||
const latestUser = await sequelize.query( |
|
||||
'SELECT userId FROM users ORDER BY userId DESC LIMIT 1', |
|
||||
{ type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
if (latestUser.length > 0 && latestUser[0].userId !== lastCheckedUserId) { |
|
||||
console.log(`\n🕵️♂️ 检测到可能的新用户活动,运行完整检查`); |
|
||||
|
|
||||
// 重新运行修复函数检查所有用户
|
|
||||
await checkAndFixAllUserAssociations(); |
|
||||
|
|
||||
// 更新最后检查的用户ID
|
|
||||
lastCheckedUserId = latestUser[0].userId; |
|
||||
} |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 监控过程中发生错误:', error.message); |
|
||||
} finally { |
|
||||
// 关闭数据库连接
|
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 立即运行一次
|
|
||||
await checkNewUsers(); |
|
||||
|
|
||||
// 设置定期检查(在实际部署时启用)
|
|
||||
// setInterval(checkNewUsers, intervalMinutes * 60 * 1000);
|
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 创建一个服务器文件补丁,确保新用户在授权时自动创建关联记录 |
|
||||
*/ |
|
||||
function createServerPatch() { |
|
||||
console.log('\n========================================'); |
|
||||
console.log('创建服务器代码补丁'); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
const patchContent = `/**
|
|
||||
* 用户关联记录创建工具函数 |
|
||||
* 用于在用户授权成功后自动创建contacts和usermanagements表关联记录 |
|
||||
*/ |
|
||||
async function createUserAssociations(user) { |
|
||||
try { |
|
||||
// 确保用户对象有效
|
|
||||
if (!user || !user.userId) { |
|
||||
console.error('创建用户关联记录失败: 用户对象或userId无效'); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
console.log('为用户创建关联记录:', user.userId); |
|
||||
|
|
||||
// 1. 创建或更新联系人记录
|
|
||||
const [contactResult] = await sequelize.query( |
|
||||
'INSERT INTO contacts (userId, nickName, phoneNumber) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE nickName = ?, phoneNumber = ?', |
|
||||
{ replacements: [user.userId, user.nickName || '默认联系人', user.phoneNumber || '', user.nickName || '默认联系人', user.phoneNumber || ''] } |
|
||||
); |
|
||||
|
|
||||
// 2. 创建或更新用户管理记录
|
|
||||
const [managementResult] = await sequelize.query( |
|
||||
'INSERT INTO usermanagements (userId) VALUES (?) ON DUPLICATE KEY UPDATE userId = ?', |
|
||||
{ replacements: [user.userId, user.userId] } |
|
||||
); |
|
||||
|
|
||||
console.log('用户关联记录创建成功:', user.userId); |
|
||||
return true; |
|
||||
} catch (error) { |
|
||||
console.error('创建用户关联记录失败:', error.message); |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 在server-mysql.js文件中的用户授权相关代码后添加:
|
|
||||
// 示例:在用户创建或更新成功后调用
|
|
||||
// const user = { userId: '...', nickName: '...', phoneNumber: '...' };
|
|
||||
// await createUserAssociations(user);`;
|
|
||||
|
|
||||
const patchFilePath = path.join(__dirname, 'user-association-patch.js'); |
|
||||
fs.writeFileSync(patchFilePath, patchContent); |
|
||||
|
|
||||
console.log('✅ 服务器补丁已创建:', patchFilePath); |
|
||||
console.log('请将此补丁中的createUserAssociations函数添加到server-mysql.js文件中,'); |
|
||||
console.log('并在用户授权成功后调用该函数,以确保自动创建关联记录。'); |
|
||||
console.log('========================================'); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 主函数 |
|
||||
*/ |
|
||||
async function main() { |
|
||||
try { |
|
||||
// 1. 先检查并修复所有现有用户
|
|
||||
await checkAndFixAllUserAssociations(); |
|
||||
|
|
||||
// 2. 创建服务器补丁,解决根本问题
|
|
||||
createServerPatch(); |
|
||||
|
|
||||
// 3. 提供使用说明
|
|
||||
console.log('\n========================================'); |
|
||||
console.log('使用说明:'); |
|
||||
console.log('========================================'); |
|
||||
console.log('1. 手动修复现有用户:'); |
|
||||
console.log(' 已完成,所有用户的关联记录已检查并修复'); |
|
||||
console.log('\n2. 长期解决方案:'); |
|
||||
console.log(' a. 请将user-association-patch.js中的createUserAssociations函数添加到server-mysql.js文件'); |
|
||||
console.log(' b. 在用户授权成功后调用该函数'); |
|
||||
console.log(' c. 重启服务器以应用更改'); |
|
||||
console.log('\n3. 可选: 定期检查(适用于临时解决方案):'); |
|
||||
console.log(' 运行: node user-association-auto-fix.js monitor'); |
|
||||
console.log(' 这将每10分钟检查一次新用户并自动修复关联记录'); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 执行过程中发生错误:', error); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 根据命令行参数决定执行模式
|
|
||||
const args = process.argv.slice(2); |
|
||||
const mode = args[0] || 'fix'; |
|
||||
|
|
||||
if (mode === 'monitor') { |
|
||||
// 监控模式
|
|
||||
monitorAndAutoFixNewUsers(); |
|
||||
} else { |
|
||||
// 默认修复模式
|
|
||||
main(); |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
/** |
|
||||
* 用户关联记录创建工具函数 |
|
||||
* 用于在用户授权成功后自动创建contacts和usermanagements表关联记录 |
|
||||
*/ |
|
||||
async function createUserAssociations(user) { |
|
||||
try { |
|
||||
// 确保用户对象有效
|
|
||||
if (!user || !user.userId) { |
|
||||
console.error('创建用户关联记录失败: 用户对象或userId无效'); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
console.log('为用户创建关联记录:', user.userId); |
|
||||
|
|
||||
// 1. 创建或更新联系人记录
|
|
||||
const [contactResult] = await sequelize.query( |
|
||||
'INSERT INTO contacts (userId, nickName, phoneNumber) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE nickName = ?, phoneNumber = ?', |
|
||||
{ replacements: [user.userId, user.nickName || '默认联系人', user.phoneNumber || '', user.nickName || '默认联系人', user.phoneNumber || ''] } |
|
||||
); |
|
||||
|
|
||||
// 2. 创建或更新用户管理记录
|
|
||||
const [managementResult] = await sequelize.query( |
|
||||
'INSERT INTO usermanagements (userId) VALUES (?) ON DUPLICATE KEY UPDATE userId = ?', |
|
||||
{ replacements: [user.userId, user.userId] } |
|
||||
); |
|
||||
|
|
||||
console.log('用户关联记录创建成功:', user.userId); |
|
||||
return true; |
|
||||
} catch (error) { |
|
||||
console.error('创建用户关联记录失败:', error.message); |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 在server-mysql.js文件中的用户授权相关代码后添加:
|
|
||||
// 示例:在用户创建或更新成功后调用
|
|
||||
// const user = { userId: '...', nickName: '...', phoneNumber: '...' };
|
|
||||
// await createUserAssociations(user);
|
|
||||
@ -1,106 +0,0 @@ |
|||||
const { Sequelize } = require('sequelize'); |
|
||||
const fs = require('fs'); |
|
||||
const path = require('path'); |
|
||||
|
|
||||
// 读取环境变量
|
|
||||
const envPath = path.join(__dirname, '.env'); |
|
||||
if (fs.existsSync(envPath)) { |
|
||||
const envContent = fs.readFileSync(envPath, 'utf8'); |
|
||||
const envVars = envContent.split('\n').filter(line => line.trim() && !line.startsWith('#')); |
|
||||
envVars.forEach(line => { |
|
||||
const [key, value] = line.split('=').map(part => part.trim()); |
|
||||
process.env[key] = value; |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 数据库连接配置
|
|
||||
const sequelize = new Sequelize( |
|
||||
process.env.DB_NAME || 'wechat_app', |
|
||||
process.env.DB_USER || 'root', |
|
||||
process.env.DB_PASSWORD || '', |
|
||||
{ |
|
||||
host: process.env.DB_HOST || 'localhost', |
|
||||
port: process.env.DB_PORT || 3306, |
|
||||
dialect: 'mysql', |
|
||||
logging: false, |
|
||||
timezone: '+08:00' // 设置时区为UTC+8
|
|
||||
} |
|
||||
); |
|
||||
|
|
||||
// 查看usermanagements表结构
|
|
||||
async function viewUserManagementsTableStructure() { |
|
||||
try { |
|
||||
console.log('========================================'); |
|
||||
console.log('查看usermanagements表结构'); |
|
||||
console.log('========================================'); |
|
||||
|
|
||||
// 连接数据库
|
|
||||
await sequelize.authenticate(); |
|
||||
console.log('✅ 数据库连接成功'); |
|
||||
|
|
||||
// 查询表结构
|
|
||||
const tableStructure = await sequelize.query( |
|
||||
'SHOW COLUMNS FROM usermanagements', |
|
||||
{ type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
console.log('\nusermanagements表字段信息:'); |
|
||||
tableStructure.forEach(column => { |
|
||||
console.log(`- ${column.Field}: ${column.Type} ${column.Null === 'NO' ? '(NOT NULL)' : ''} ${column.Key === 'PRI' ? '(PRIMARY KEY)' : ''}`); |
|
||||
}); |
|
||||
|
|
||||
// 查询表索引
|
|
||||
const indexes = await sequelize.query( |
|
||||
'SHOW INDEX FROM usermanagements', |
|
||||
{ type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
|
|
||||
if (indexes.length > 0) { |
|
||||
console.log('\nusermanagements表索引信息:'); |
|
||||
indexes.forEach(index => { |
|
||||
console.log(`- 索引名: ${index.Key_name}, 字段: ${index.Column_name}, 唯一: ${index.Non_unique === 0 ? '是' : '否'}`); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 查询表中的最新5条记录
|
|
||||
console.log('\nusermanagements表中的最新5条记录:'); |
|
||||
|
|
||||
// 尝试查找一个可能的时间字段
|
|
||||
const possibleTimeFields = tableStructure |
|
||||
.map(col => col.Field) |
|
||||
.filter(field => field.toLowerCase().includes('time') || field.toLowerCase().includes('date')); |
|
||||
|
|
||||
let latestRecords; |
|
||||
|
|
||||
if (possibleTimeFields.length > 0) { |
|
||||
console.log(`找到可能的时间字段: ${possibleTimeFields.join(', ')}`); |
|
||||
// 使用第一个找到的时间字段排序
|
|
||||
latestRecords = await sequelize.query( |
|
||||
`SELECT userId FROM usermanagements ORDER BY ${possibleTimeFields[0]} DESC LIMIT 5`, |
|
||||
{ type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
} else { |
|
||||
console.log('未找到明显的时间字段,按userId排序'); |
|
||||
latestRecords = await sequelize.query( |
|
||||
'SELECT userId FROM usermanagements ORDER BY userId DESC LIMIT 5', |
|
||||
{ type: sequelize.QueryTypes.SELECT } |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
latestRecords.forEach((record, index) => { |
|
||||
console.log(` ${index + 1}. userId: ${record.userId}`); |
|
||||
}); |
|
||||
|
|
||||
console.log('\n========================================'); |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('❌ 查看表结构过程中发生错误:', error.message); |
|
||||
console.error('错误详情:', error); |
|
||||
} finally { |
|
||||
// 关闭数据库连接
|
|
||||
await sequelize.close(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 运行查看
|
|
||||
viewUserManagementsTableStructure(); |
|
||||
Loading…
Reference in new issue