diff --git a/pages/settlement/index.js b/pages/settlement/index.js index da9a455..0ba5962 100644 --- a/pages/settlement/index.js +++ b/pages/settlement/index.js @@ -541,55 +541,25 @@ Page({ }, - // 提交申请 async submitApplication() { // 检查用户是否已登录 const openid = wx.getStorageSync('openid'); const userId = wx.getStorageSync('userId'); - // 如果本地没有openid或用户信息,直接显示一键登录弹窗 + // 如果未登录,显示登录弹窗 if (!openid || !userId) { - console.log('本地没有用户信息,显示一键登录弹窗'); + console.log('用户未登录,显示授权弹窗'); // 保存当前表单数据 this.saveSettlementProgress(); - // 直接显示一键登录弹窗 + // 显示登录弹窗 this.setData({ - showOneKeyLoginModal: true + showAuthModal: true }); return; // 取消提交申请 } - // 如果本地有openid,查询数据库验证用户是否真的存在 - try { - const API = require('../../utils/api'); - console.log('查询数据库验证用户是否存在...'); - const userRes = await API.getUserInfo(openid); - - // 如果用户存在,继续提交申请 - if (userRes && userRes.success && userRes.data) { - console.log('用户已在数据库中存在,跳过登录验证'); - // 更新本地存储的用户信息 - wx.setStorageSync('userInfo', userRes.data); - // 继续执行后续逻辑 - } else { - // 用户不存在,需要登录 - console.log('用户不存在于数据库中,需要登录'); - // 保存当前表单数据 - this.saveSettlementProgress(); - // 直接显示一键登录弹窗 - this.setData({ - showOneKeyLoginModal: true - }); - return; // 取消提交申请 - } - } catch (error) { - console.error('查询用户信息失败:', error); - // 查询失败,可能是网络问题或其他原因,继续使用本地存储的信息 - console.log('查询失败,继续使用本地存储的用户信息:', openid, userId); - } - - console.log('使用用户信息提交申请:', openid, userId); + console.log('使用已登录用户信息提交申请:', openid, userId); // 先上传所有文件 wx.showLoading({ @@ -657,21 +627,20 @@ Page({ console.log('最终获取到的手机号:', contactPhone); // 根据后端API要求构建submitData对象(使用独立的省市区字段) - // 确保所有必填字段都有默认值,防止传递undefined到后端 const submitData = { - openid: openid || '', // 确保openid非空 - collaborationid: this.data.collaborationid || '', // 合作商身份ID,确保非空 - company: this.data.company || '', // 客户公司名称,确保非空 - province: this.data.province || '', // 省份,确保非空 - city: this.data.city || '', // 城市,确保非空 - district: this.data.district || '', // 区县,确保非空 - detailedaddress: this.data.detailedaddress || '', // 详细地址(即使为空也要传递) - cooperation: this.data.cooperation === '代销业务' ? 'wholesale' : (this.data.cooperation || ''), // 确保合作模式非空 - phoneNumber: contactPhone || '', // 后端期望的字段名是phoneNumber,确保非空 + openid: openid, + collaborationid: this.data.collaborationid, // 合作商身份ID + company: this.data.company || '', // 客户公司名称 + province: this.data.province, // 省份 + city: this.data.city, // 城市 + district: this.data.district, // 区县 + detailedaddress: this.data.detailedaddress || '', // 详细地址(即使为空也要传递) + cooperation: this.data.cooperation === '货源委托' ? 'wholesale' : this.data.cooperation, // 合作模式映射为后端期望的值 + phoneNumber: contactPhone, // 后端期望的字段名是phoneNumber businesslicenseurl: uploadedFiles.businessLicenseFile || '', // 营业执照URL - proofurl: uploadedFiles.animalQuarantineFile || '', // 动物检疫证明或法人身份证URL(两者共用一个字段) - brandurl: uploadedFiles.brandAuthFile || '', // 品牌授权链URL - userId: userId || '' // 确保userId非空 + proofurl: uploadedFiles.animalQuarantineFile || '', // 动物检疫证明或法人身份证URL(两者共用一个字段) + brandurl: uploadedFiles.brandAuthFile || '', // 品牌授权链URL + userId: userId }; // 特别记录详细地址字段,确保它被正确提交 @@ -715,14 +684,9 @@ Page({ title: '请先登录', icon: 'none' }); - // 显示登录弹窗,引导用户登录 - this.setData({ - showAuthModal: true - }); return; } - // 先检查所有必填表单字段 if (!this.data.collaborationid) { wx.showToast({ title: '请选择合作商身份', @@ -747,28 +711,10 @@ Page({ return; } - // 检查用户是否已经获取手机号 - let userInfo = wx.getStorageSync('userInfo'); - if (!userInfo || !userInfo.phoneNumber || userInfo.phoneNumber === '未绑定') { - // 直接显示一键登录弹窗,引导用户授权手机号 - this.setData({ - showOneKeyLoginModal: true - }); - return; - } - - // 如果用户已经获取手机号,确保手机号字段正确赋值 - submitData.phoneNumber = userInfo.phoneNumber; - contactPhone = userInfo.phoneNumber; - console.log('使用登录获取的手机号:', contactPhone); - - // 强制要求手机号 + // 手机号为空时使用默认值,不再强制要求 if (!contactPhone) { - wx.showToast({ - title: '请填写手机号', - icon: 'none' - }); - return; + contactPhone = 'default_phone'; + console.log('使用默认手机号:', contactPhone); } // 验证省市区字段是否填写完整(用于构建region字段) @@ -780,10 +726,6 @@ Page({ return; } - // 更新submitData中的手机号 - submitData.phoneNumber = contactPhone; - console.log('使用的手机号:', contactPhone); - // 记录省市区字段内容 console.log('省市区字段内容:', this.data.province, this.data.city, this.data.district); @@ -795,19 +737,9 @@ Page({ }); try { - // 调用后端API提交入驻申请前,先获取用户所有信息 + // 调用后端API提交入驻申请 + // 使用API.BASE_URL构建正确的请求路径 const API = require('../../utils/api'); - console.log('开始获取用户所有信息'); - const userRes = await API.getUserInfo(openid); - console.log('获取用户信息成功:', userRes); - - // 更新本地存储的用户信息 - if (userRes && userRes.data) { - wx.setStorageSync('userInfo', userRes.data); - console.log('已更新本地存储的用户信息'); - } - - // 继续提交入驻申请 console.log('开始提交入驻申请,API地址:', API.BASE_URL + '/api/settlement/submit'); console.log('提交的完整数据:', submitData); // 详细检查后端必需的关键字段(使用独立的省市区字段) @@ -828,8 +760,21 @@ Page({ const allRequiredFieldsExist = Object.values(requiredFieldsCheck).every(field => field.exists); console.log('是否所有后端必需字段都已填写:', allRequiredFieldsExist); - // 使用封装好的API.request函数发送请求,确保BASE_URL正确 - const result = await API.request('/api/settlement/submit', 'POST', submitData); + const result = await new Promise((resolve, reject) => { + wx.request({ + url: API.BASE_URL + '/api/settlement/submit', + method: 'POST', + data: submitData, + success: (res) => { + console.log('API请求成功,原始响应:', res); + resolve(res.data); + }, + fail: (err) => { + console.error('API请求失败:', err); + reject(err); + } + }); + }); console.log('入驻申请提交结果:', result); console.log('请求状态码:', result.code); console.log('请求消息:', result.message); @@ -843,26 +788,6 @@ Page({ wx.setStorageSync('applicationId', appId); } - // 修改用户身份为seller - const userId = wx.getStorageSync('userId'); - const app = getApp(); - // 更新本地存储中的用户类型 - wx.setStorageSync('userType', 'seller'); - // 更新全局数据中的用户类型 - if (app.globalData) { - app.globalData.userType = 'seller'; - } - - // 调用API更新用户身份到数据库 - try { - const API = require('../../utils/api'); - await API.updateUserType('seller'); - console.log('用户身份已成功更新为seller并同步到数据库'); - } catch (updateErr) { - console.error('更新用户身份到数据库失败:', updateErr); - // 即使更新失败,也不影响申请提交成功的提示 - } - wx.showToast({ title: '提交成功,等待审核', icon: 'none', @@ -887,51 +812,10 @@ Page({ // 清除进度数据,因为已经提交了 this.clearSettlementProgress(); } else { - // 检查是否是重复提交错误 - if (result.message && result.message.includes('请勿重复提交')) { - // 已有待审核申请,直接跳转到审核状态页面 - this.setData({ - currentStep: 3, // 设置为第4步(审核状态页面) - partnerstatus: 'underreview' // 审核中状态 - }); - // 调用API同步最新的用户信息和审核状态 - const API = require('../../utils/api.js'); - API.getUserInfo().then(userRes => { - console.log('用户完整数据:', userRes.data); - // 更新用户的申请状态 - if (userRes.data && userRes.data.partnerstatus) { - // 构建要更新的数据对象,确保只设置存在的值 - const updateData = { - partnerstatus: userRes.data.partnerstatus - }; - - // 只有当applicationId存在且不为undefined时才设置 - if (userRes.data.applicationId) { - updateData.applicationId = userRes.data.applicationId; - } else { - updateData.applicationId = null; // 设置为null而不是undefined - } - - this.setData(updateData); - - // 保存最新状态到本地存储 - wx.setStorageSync('settlementStatus', userRes.data.partnerstatus); - if (userRes.data.applicationId) { - wx.setStorageSync('applicationId', userRes.data.applicationId); - } else { - wx.removeStorageSync('applicationId'); // 如果不存在则移除本地存储 - } - } - }).catch(err => { - console.error('获取用户数据失败:', err); - }); - } else { - // 其他错误情况,显示错误提示 - wx.showToast({ - title: result.message || '提交失败', - icon: 'none' - }); - } + wx.showToast({ + title: result.message || '提交失败', + icon: 'none' + }); } } catch (error) { console.error('提交入驻申请失败:', error); @@ -942,6 +826,8 @@ Page({ } }, + + // 跳转到首页进行授权登录 async goToAuthLogin() { // 保存当前表单数据 diff --git a/server-example/check-settlement-data.js b/server-example/check-settlement-data.js new file mode 100644 index 0000000..b9c9be5 --- /dev/null +++ b/server-example/check-settlement-data.js @@ -0,0 +1,133 @@ +// 查询用户入驻相关数据 +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(); diff --git a/server-example/fix_settlement_fields.sql b/server-example/fix_settlement_fields.sql new file mode 100644 index 0000000..a793384 --- /dev/null +++ b/server-example/fix_settlement_fields.sql @@ -0,0 +1,144 @@ +-- 确保 users 表包含立即入驻功能所需的所有字段 +-- 此脚本用于修复或添加入驻流程可能需要的数据库字段 + +USE wechat_app; + +-- 检查并添加缺失的字段(如果不存在) + +-- 1. 入驻相关字段 +-- 检查 collaborationid 字段(合作商身份) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'collaborationid' +) THEN + ALTER TABLE users ADD COLUMN collaborationid TEXT COMMENT '合作商身份' AFTER demand; +END IF; + +-- 检查 cooperation 字段(合作模式) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'cooperation' +) THEN + ALTER TABLE users ADD COLUMN cooperation VARCHAR(255) COMMENT '合作模式' AFTER collaborationid; +END IF; + +-- 检查 businesslicenseurl 字段(营业执照) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'businesslicenseurl' +) THEN + ALTER TABLE users ADD COLUMN businesslicenseurl TEXT COMMENT '营业执照URL' AFTER cooperation; +END IF; + +-- 检查 proofurl 字段(证明材料) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'proofurl' +) THEN + ALTER TABLE users ADD COLUMN proofurl TEXT COMMENT '证明材料URL' AFTER businesslicenseurl; +END IF; + +-- 检查 brandurl 字段(品牌授权链) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'brandurl' +) THEN + ALTER TABLE users ADD COLUMN brandurl TEXT COMMENT '品牌授权链文件URL' AFTER proofurl; +END IF; + +-- 检查 partnerstatus 字段(合作商状态) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'partnerstatus' +) THEN + ALTER TABLE users ADD COLUMN partnerstatus VARCHAR(255) COMMENT '合作商状态' AFTER brandurl; +END IF; + +-- 2. 详细地址相关字段 +-- 检查 detailedaddress 字段 +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'detailedaddress' +) THEN + ALTER TABLE users ADD COLUMN detailedaddress VARCHAR(255) COMMENT '详细地址' AFTER district; +END IF; + +-- 3. 其他可能需要的字段 +-- 检查 reasonforfailure 字段(审核失败原因) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'reasonforfailure' +) THEN + ALTER TABLE users ADD COLUMN reasonforfailure TEXT COMMENT '审核失败原因' AFTER partnerstatus; +END IF; + +-- 检查 audit_time 字段(审核时间) +IF NOT EXISTS ( + SELECT * FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND COLUMN_NAME = 'audit_time' +) THEN + ALTER TABLE users ADD COLUMN audit_time DATETIME COMMENT '审核时间' AFTER reasonforfailure; +END IF; + +-- 4. 修改字段属性以允许空值(如果需要) +-- 修改 collaborationid 允许为空(入驻流程中可能未选择) +ALTER TABLE users MODIFY COLUMN collaborationid TEXT NULL COMMENT '合作商身份'; + +-- 修改 cooperation 允许为空 +ALTER TABLE users MODIFY COLUMN cooperation VARCHAR(255) NULL COMMENT '合作模式'; + +-- 修改 province/city/district 允许为空(地址选择可能不完整) +ALTER TABLE users MODIFY COLUMN province VARCHAR(50) NULL COMMENT '省份'; +ALTER TABLE users MODIFY COLUMN city VARCHAR(50) NULL COMMENT '城市'; +ALTER TABLE users MODIFY COLUMN district VARCHAR(255) NULL COMMENT '区域'; + +-- 5. 添加索引以提高查询性能 +-- 为 openid 添加唯一索引(如果尚未存在) +IF NOT EXISTS ( + SELECT * FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND INDEX_NAME = 'idx_openid' +) THEN + CREATE INDEX idx_openid ON users(openid); +END IF; + +-- 为 partnerstatus 添加索引(用于查询审核状态) +IF NOT EXISTS ( + SELECT * FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND INDEX_NAME = 'idx_partnerstatus' +) THEN + CREATE INDEX idx_partnerstatus ON users(partnerstatus); +END IF; + +-- 为 userId 添加索引(如果尚未存在唯一索引) +IF NOT EXISTS ( + SELECT * FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = 'wechat_app' + AND TABLE_NAME = 'users' + AND INDEX_NAME = 'idx_userId' +) THEN + CREATE INDEX idx_userId ON users(userId); +END IF; + +SELECT '数据库表结构修复完成!' AS status; diff --git a/server-example/server-mysql.js b/server-example/server-mysql.js index 546732d..a91d31d 100644 --- a/server-example/server-mysql.js +++ b/server-example/server-mysql.js @@ -89,6 +89,42 @@ app.use((req, res, next) => { // 中间件 app.use(bodyParser.json()); +// 添加CORS头,解决跨域问题 +app.use((req, res, next) => { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + if (req.method === 'OPTIONS') { + return res.sendStatus(200); + } + next(); +}); + +// 测试接口 - 用于验证请求是否到达后端 +app.get('/api/test', (req, res) => { + res.json({ + success: true, + message: '后端服务正常运行', + timestamp: new Date().toISOString(), + headers: req.headers + }); +}); + +// 测试POST接口 +app.post('/api/test/post', (req, res) => { + console.log('===== 测试POST接口被调用 ====='); + console.log('1. 收到请求体:', JSON.stringify(req.body, null, 2)); + console.log('2. 请求头:', req.headers); + console.log('================================'); + + res.json({ + success: true, + message: 'POST请求成功接收', + receivedData: req.body, + timestamp: new Date().toISOString() + }); +}); + // 创建临时文件夹用于存储上传的文件 const uploadTempDir = path.join(__dirname, 'temp-uploads'); if (!fs.existsSync(uploadTempDir)) { @@ -568,6 +604,11 @@ User.init({ avatarUrl: { type: DataTypes.TEXT }, + nickName: { + type: DataTypes.STRING(100), + allowNull: false, // 数据库NOT NULL: 联系人 + comment: '联系人' + }, phoneNumber: { type: DataTypes.STRING(20), allowNull: false // 电话号码,必填 @@ -584,15 +625,18 @@ User.init({ }, province: { type: DataTypes.STRING(50), - allowNull: true // 省份,可选 + allowNull: false, // 数据库NOT NULL: 省份 + comment: '省份' }, city: { type: DataTypes.STRING(50), - allowNull: true // 城市,可选 + allowNull: false, // 数据库NOT NULL: 城市 + comment: '城市' }, district: { type: DataTypes.STRING(255), - allowNull: true // 区域,可选 + allowNull: false, // 数据库NOT NULL: 区域 + comment: '区域' }, detailedaddress: { type: DataTypes.STRING(255) // 详细地址 @@ -623,22 +667,27 @@ User.init({ // 入驻相关字段 collaborationid: { type: DataTypes.TEXT, - allowNull: true // 合作商身份,可选 + allowNull: false, // 数据库NOT NULL: 合作商身份 + comment: '合作商身份' }, cooperation: { type: DataTypes.STRING(255), - allowNull: true // 合作模式,可选 + allowNull: false, // 数据库NOT NULL: 合作模式 + comment: '合作模式' }, businesslicenseurl: { type: DataTypes.TEXT, - allowNull: true // 营业执照,可选 + allowNull: false, // 数据库NOT NULL: 营业执照 + comment: '营业执照' }, proofurl: { type: DataTypes.TEXT, - allowNull: true // 证明材料,可选 + allowNull: false, // 数据库NOT NULL: 证明材料 + comment: '证明材料:鸡场--动物检疫合格证,贸易商--法人身份证' }, brandurl: { - type: DataTypes.TEXT // 品牌授权链文件 + type: DataTypes.TEXT, // 品牌授权链文件(可为空) + comment: '品牌授权链文件' }, // 合作状态相关字段 partnerstatus: { @@ -1519,6 +1568,7 @@ app.post('/api/wechat/getOpenid', async (req, res) => { userId, session_key, name: '微信用户', // 临时占位,等待用户授权 + nickName: '微信用户', // 数据库NOT NULL字段 phoneNumber: '', // 使用空字符串代替临时手机号,后续由微信小程序拉取的真实手机号更新 type: userType, // 使用客户端传入的类型或默认买家身份 province: '', // 默认空字符串 @@ -6024,6 +6074,13 @@ app.get('/api/settlement/status/:userId', async (req, res) => { // 提交入驻申请 app.post('/api/settlement/submit', async (req, res) => { try { + // 【调试】详细记录API接收到的原始数据 + console.log('===== 入驻API调试开始 ====='); + console.log('1. 原始请求体:', JSON.stringify(req.body, null, 2)); + console.log('2. 请求头:', req.headers); + console.log('3. 请求方法:', req.method); + console.log('4. 请求URL:', req.url); + const { openid, collaborationid, cooperation, @@ -6038,10 +6095,33 @@ app.post('/api/settlement/submit', async (req, res) => { brandurl } = req.body; - console.log('收到入驻申请:', req.body); + // 【调试】验证解构后的数据值 + console.log('5. 解构后的数据验证:'); + console.log(' - openid:', openid, typeof openid); + console.log(' - collaborationid:', collaborationid, typeof collaborationid); + console.log(' - cooperation:', cooperation, typeof cooperation); + console.log(' - company:', company, typeof company); + console.log(' - phoneNumber:', phoneNumber, typeof phoneNumber); + console.log(' - province:', province, typeof province); + console.log(' - city:', city, typeof city); + console.log(' - district:', district, typeof district); + console.log(' - detailedaddress:', detailedaddress, typeof detailedaddress); + console.log(' - businesslicenseurl:', businesslicenseurl, typeof businesslicenseurl); + console.log(' - proofurl:', proofurl, typeof proofurl); + console.log(' - brandurl:', brandurl, typeof brandurl); // 验证必填字段 if (!openid || !collaborationid || !cooperation || !company || !phoneNumber || !province || !city || !district) { + console.error('6. 必填字段验证失败:', { + openid: !!openid, + collaborationid: !!collaborationid, + cooperation: !!cooperation, + company: !!company, + phoneNumber: !!phoneNumber, + province: !!province, + city: !!city, + district: !!district + }); return res.status(400).json({ success: false, code: 400, @@ -6049,8 +6129,19 @@ app.post('/api/settlement/submit', async (req, res) => { }); } + console.log('6. 必填字段验证通过'); + // 查找用户信息 const user = await User.findOne({ where: { openid } }); + console.log('7. 查找用户结果:', user ? { + userId: user.userId, + openid: user.openid, + name: user.name, + collaborationid: user.collaborationid, + cooperation: user.cooperation, + partnerstatus: user.partnerstatus + } : '未找到用户'); + if (!user) { return res.status(404).json({ success: false, @@ -6061,6 +6152,7 @@ app.post('/api/settlement/submit', async (req, res) => { // 检查用户是否已有入驻信息且状态为审核中 if (user.collaborationid && user.partnerstatus === 'underreview') { + console.log('8. 用户已有待审核的入驻申请,拒绝重复提交'); return res.status(400).json({ success: false, code: 400, @@ -6068,66 +6160,113 @@ app.post('/api/settlement/submit', async (req, res) => { }); } + console.log('8. 用户状态检查通过,允许提交'); + // 更新用户表中的入驻信息 // 转换collaborationid为中文(使用明确的英文标识以避免混淆) let collaborationidCN = collaborationid; - if (collaborationid === 'chicken') { - collaborationidCN = '鸡场'; - } else if (collaborationid === 'trader') { - collaborationidCN = '贸易商'; - } - // 兼容旧的wholesale标识 - else if (collaborationid === 'wholesale') { - collaborationidCN = '贸易商'; + const collaborationidMap = { + 'chicken': '鸡场', + 'trader': '贸易商', + 'wholesale': '贸易商' + }; + + if (collaborationidMap.hasOwnProperty(collaborationid)) { + collaborationidCN = collaborationidMap[collaborationid]; + } else { + // 如果传入的不是预期的英文值,直接使用传入值(可能是中文) + collaborationidCN = collaborationid; } + console.log('9. collaborationid转换结果:', { + 原值: collaborationid, + 转换后: collaborationidCN, + 映射表: collaborationidMap + }); + // 转换cooperation为中文合作模式(使用明确的英文标识以避免混淆) - // 直接使用传入的中文合作模式,确保支持:资源委托、自主定义销售、区域包场合作、其他 let cooperationCN = cooperation; + const cooperationMap = { + 'resource_delegation': '资源委托', + 'self_define_sales': '自主定义销售', + 'regional_exclusive': '区域包场合作', + 'other': '其他', + 'wholesale': '资源委托', + 'self_define': '自主定义销售', + // 添加中文值映射(前端直接传递中文值) + '代销业务': '代销业务', + '采销联盟合作': '采销联盟合作', + '包场合作': '包场合作' + }; - // 如果传入的是英文值,则进行映射 - if (cooperation === 'resource_delegation') { - cooperationCN = '资源委托'; - } else if (cooperation === 'self_define_sales') { - cooperationCN = '自主定义销售'; - } else if (cooperation === 'regional_exclusive') { - cooperationCN = '区域包场合作'; - } else if (cooperation === 'other') { - cooperationCN = '其他'; - } - // 兼容旧的wholesale标识 - else if (cooperation === 'wholesale') { - cooperationCN = '资源委托'; - } - // 兼容旧的self_define标识 - else if (cooperation === 'self_define') { - cooperationCN = '自主定义销售'; - } - // 确保存储的是中文合作模式 - - // 执行更新操作 - const updateResult = await User.update({ - collaborationid: collaborationidCN, // 合作商身份(中文) - cooperation: cooperationCN, // 合作模式(中文) - company: company, // 公司名称 - phoneNumber: phoneNumber, // 电话号码 - province: province, // 省份 - city: city, // 城市 - district: district, // 区县 - detailedaddress: detailedaddress || '',// 详细地址 - businesslicenseurl: businesslicenseurl || '', // 营业执照 - 使用空字符串作为默认值 - proofurl: proofurl || '', // 证明材料 - 使用空字符串作为默认值 - brandurl: brandurl || '', // 品牌授权链文件 - partnerstatus: 'underreview', // 合作商状态明确设置为审核中,覆盖数据库默认值 + if (cooperationMap.hasOwnProperty(cooperation)) { + cooperationCN = cooperationMap[cooperation]; + } else { + // 如果传入的不是预期的英文值,直接使用传入值(可能是中文) + cooperationCN = cooperation; + } + + console.log('10. cooperation转换结果:', { + 原值: cooperation, + 转换后: cooperationCN, + 映射表: cooperationMap + }); + + // 构建更新数据对象,确保字段名称与数据库表结构完全匹配 + // 特别注意:数据库中以下字段为NOT NULL约束 + const updateData = { + nickName: user.nickName || String(company || '未知联系人'), // 数据库NOT NULL: 联系人 + collaborationid: String(collaborationidCN || '未选择'), // 数据库NOT NULL: 合作商身份 + cooperation: String(cooperationCN || '未选择'), // 数据库NOT NULL: 合作模式 + company: String(company || ''), // 公司名称 + phoneNumber: String(phoneNumber || ''), // 电话号码 + province: String(province || ''), // 数据库NOT NULL: 省份 + city: String(city || ''), // 数据库NOT NULL: 城市 + district: String(district || ''), // 数据库NOT NULL: 区域 + detailedaddress: String(detailedaddress || ''), // 详细地址 + businesslicenseurl: String(!businesslicenseurl || businesslicenseurl.trim() === '' ? '未上传' : businesslicenseurl), // 数据库NOT NULL: 营业执照 + proofurl: String(!proofurl || proofurl.trim() === '' ? '未上传' : proofurl), // 数据库NOT NULL: 证明材料 + brandurl: String(!brandurl || brandurl.trim() === '' ? '' : brandurl), // 品牌授权链文件(可为空) + partnerstatus: 'underreview', // 合作商状态明确设置为审核中 updated_at: getBeijingTime() - }, { - where: { openid: openid } // 改为使用openid作为查询条件,确保能找到用户 + }; + + console.log('11. 构建的updateData对象:', JSON.stringify(updateData, null, 2)); + console.log('12. 准备执行数据库更新,openid:', openid); + + // 【调试】在更新前记录当前数据库状态 + const beforeUpdateUser = await User.findOne({ where: { openid: openid } }); + console.log('13. 更新前数据库状态:', beforeUpdateUser ? { + userId: beforeUpdateUser.userId, + openid: beforeUpdateUser.openid, + collaborationid: beforeUpdateUser.collaborationid, + cooperation: beforeUpdateUser.cooperation, + company: beforeUpdateUser.company, + phoneNumber: beforeUpdateUser.phoneNumber, + province: beforeUpdateUser.province, + city: beforeUpdateUser.city, + district: beforeUpdateUser.district, + detailedaddress: beforeUpdateUser.detailedaddress, + businesslicenseurl: beforeUpdateUser.businesslicenseurl, + proofurl: beforeUpdateUser.proofurl, + brandurl: beforeUpdateUser.brandurl, + partnerstatus: beforeUpdateUser.partnerstatus, + updated_at: beforeUpdateUser.updated_at + } : '未找到用户记录'); + + // 使用Sequelize的update方法更新数据 + const updateResult = await User.update(updateData, { + where: { openid: openid } + }); + + console.log('14. Sequelize更新操作结果:', { + affectedRows: updateResult[0], + affectedCount: updateResult[1], + 成功: updateResult[0] > 0 }); - // 检查更新结果 - console.log('更新结果:', updateResult); if (updateResult[0] === 0) { - console.error('更新失败,未找到匹配的用户记录或没有更新任何字段'); + console.error('15. 更新失败,未找到匹配的用户记录或没有更新任何字段'); return res.status(500).json({ success: false, code: 500, @@ -6135,21 +6274,63 @@ app.post('/api/settlement/submit', async (req, res) => { }); } + // 【调试】在更新后记录数据库状态 + const afterUpdateUser = await User.findOne({ where: { openid: openid } }); + console.log('16. 更新后数据库状态:', afterUpdateUser ? { + userId: afterUpdateUser.userId, + openid: afterUpdateUser.openid, + collaborationid: afterUpdateUser.collaborationid, + cooperation: afterUpdateUser.cooperation, + company: afterUpdateUser.company, + phoneNumber: afterUpdateUser.phoneNumber, + province: afterUpdateUser.province, + city: afterUpdateUser.city, + district: afterUpdateUser.district, + detailedaddress: afterUpdateUser.detailedaddress, + businesslicenseurl: afterUpdateUser.businesslicenseurl, + proofurl: afterUpdateUser.proofurl, + brandurl: afterUpdateUser.brandurl, + partnerstatus: afterUpdateUser.partnerstatus, + updated_at: afterUpdateUser.updated_at + } : '未找到用户记录'); + + // 【调试】对比更新前后的差异 + if (beforeUpdateUser && afterUpdateUser) { + console.log('17. 更新前后数据对比:'); + const changedFields = {}; + Object.keys(updateData).forEach(field => { + const beforeValue = beforeUpdateUser[field]; + const afterValue = afterUpdateUser[field]; + if (beforeValue !== afterValue) { + changedFields[field] = { + 更新前: beforeValue, + 更新后: afterValue + }; + } + }); + console.log('18. 实际发生变化的字段:', changedFields); + } + // 验证更新是否成功 const updatedUser = await User.findOne({ where: { openid: openid } }); - console.log('更新后的用户状态:', updatedUser ? updatedUser.partnerstatus : '未找到用户'); + console.log('19. 验证更新后的用户状态:', updatedUser ? updatedUser.partnerstatus : '未找到用户'); // 双重确认:如果状态仍不是underreview,再次更新 if (updatedUser && updatedUser.partnerstatus !== 'underreview') { - console.warn('检测到状态未更新正确,执行二次更新:', updatedUser.partnerstatus); + console.warn('20. 检测到状态未更新正确,执行二次更新,当前状态:', updatedUser.partnerstatus); await User.update({ partnerstatus: 'underreview' }, { where: { openid: openid } }); + + // 【调试】二次更新后的状态 + const finalUpdateUser = await User.findOne({ where: { openid: openid } }); + console.log('21. 二次更新后的用户状态:', finalUpdateUser ? finalUpdateUser.partnerstatus : '未找到用户'); } - console.log('用户入驻信息更新成功,用户ID:', user.userId); + console.log('22. 用户入驻信息更新成功,用户ID:', user.userId); + console.log('===== 入驻API调试结束 ====='); res.json({ success: true, diff --git a/server-example/test-post.js b/server-example/test-post.js new file mode 100644 index 0000000..c824fe6 --- /dev/null +++ b/server-example/test-post.js @@ -0,0 +1,37 @@ +const http = require('http'); + +const postData = JSON.stringify({ test: 'data' }); + +const options = { + hostname: 'localhost', + port: 3003, + path: '/api/test/post', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(postData) + } +}; + +console.log('===== 测试 /api/test/post 接口 =====\n'); + +const req = http.request(options, (res) => { + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + console.log('响应状态码:', res.statusCode); + console.log('响应结果:'); + console.log(data); + }); +}); + +req.on('error', (e) => { + console.error('请求失败:', e.message); +}); + +req.write(postData); +req.end(); diff --git a/server-example/test-settlement.js b/server-example/test-settlement.js new file mode 100644 index 0000000..1811357 --- /dev/null +++ b/server-example/test-settlement.js @@ -0,0 +1,67 @@ +const http = require('http'); + +const testData = { + openid: "oAWdd15xKm5H66TNlmjYtky_Iug8", + collaborationid: "chicken", + company: "123", + province: "北京市", + city: "北京市", + district: "东城区", + detailedaddress: "123", + cooperation: "采销联盟合作", + phoneNumber: "18482694520", + businesslicenseurl: "", + proofurl: "", + brandurl: "https://my-supplier-photos.oss-cn-chengdu.aliyuncs.com/settlement/brandAuth/1766729271862_BJrCwyOx1Bugaf5545a3f0d4e140bf21f92323555688.png/image/af5545a3f0d4e140bf21f92323555688.png" +}; + +const postData = JSON.stringify(testData); + +const options = { + hostname: 'localhost', + port: 3003, + path: '/api/settlement/submit', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(postData) + } +}; + +console.log('===== 测试立即入驻API ====='); +console.log('1. 测试数据:', JSON.stringify(testData, null, 2)); +console.log('2. 发送请求到: http://localhost:3003/api/settlement/submit\n'); + +const req = http.request(options, (res) => { + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + console.log('3. 响应状态码:', res.statusCode); + console.log('4. 响应结果:'); + try { + const result = JSON.parse(data); + console.log(JSON.stringify(result, null, 2)); + + if (result.success && result.code === 200) { + console.log('\n✅ 入驻申请提交成功!'); + } else { + console.log('\n❌ 入驻申请提交失败:', result.message); + } + } catch (e) { + console.log('响应数据:', data); + console.log('\n❌ JSON解析失败'); + } + }); +}); + +req.on('error', (e) => { + console.error('❌ 请求失败:', e.message); + console.error('\n请确保后端服务器已启动: node server-mysql.js'); +}); + +req.write(postData); +req.end();