const WebSocket = require('ws') const http = require('http') const BASE_URL = 'http://localhost:8080/api' const WS_URL = 'ws://localhost:8080/api/ws/notify' const TOKENS = { sales: 'mock-token-mp-21', dispatch: 'mock-token-mp-13', construction: 'mock-token-mp-15', } const ROLES = { sales: { userId: 21, name: '徐云辉' }, dispatch: { userId: 13, name: '张智城' }, construction: { userId: 15, name: '测试实施1' }, } function request(method, path, data, token) { return new Promise((resolve, reject) => { const options = { hostname: 'localhost', port: 8080, path: '/api' + path, method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, } const req = http.request(options, (res) => { let body = '' res.on('data', (chunk) => (body += chunk)) res.on('end', () => { try { resolve(JSON.parse(body)) } catch (e) { resolve(body) } }) }) req.on('error', reject) if (data) req.write(JSON.stringify(data)) req.end() }) } function connectWebSocket(role) { return new Promise((resolve, reject) => { const ws = new WebSocket(`${WS_URL}?token=${encodeURIComponent(TOKENS[role])}`) const messages = [] ws.on('open', () => { console.log(`[${role}] WebSocket connected`) resolve({ ws, messages }) }) ws.on('message', (data) => { const msg = JSON.parse(data.toString()) console.log(`[${role}] received raw:`, msg.type, msg.title || '', msg.content || '') messages.push(msg) }) ws.on('error', (err) => { console.error(`[${role}] WebSocket error:`, err.message) reject(err) }) ws.on('close', () => { console.log(`[${role}] WebSocket closed`) }) }) } function wait(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } async function main() { console.log('Connecting WebSockets...') const sales = await connectWebSocket('sales') const dispatch = await connectWebSocket('dispatch') const construction = await connectWebSocket('construction') await wait(1000) // Step 1: Sales creates a task console.log('\n--- Step 1: Sales creates task ---') const taskNo = 'TK-TEST-' + Date.now() const createRes = await request('POST', '/task', { taskNo, projectId: 33, taskType: 'dredge', planDate: '2026-07-26', address: '测试地址', taskName: '测试任务-' + Date.now(), }, TOKENS.sales) console.log('Create task response:', createRes.code, createRes.msg) if (createRes.code !== 200) { console.error('Failed to create task:', createRes) process.exit(1) } const taskId = createRes.data await wait(2000) console.log('\n--- Messages after create ---') console.log('Sales messages:', sales.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Dispatch messages:', dispatch.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Construction messages:', construction.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) // Step 2: Dispatch approves task console.log('\n--- Step 2: Dispatch approves task ---') const approveRes = await request('POST', `/task/audit/${taskId}/approve`, { auditUserId: ROLES.dispatch.userId, auditUserName: ROLES.dispatch.name, }, TOKENS.dispatch) console.log('Approve task response:', approveRes.code, approveRes.msg) await wait(2000) console.log('\n--- Messages after approve ---') console.log('Sales messages:', sales.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Dispatch messages:', dispatch.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) // Step 3: Dispatch dispatches task to construction team 90 console.log('\n--- Step 3: Dispatch dispatches task to team 90 ---') // Need a vehicle. Let's query vehicles first. const vehicleRes = await request('GET', '/vehicle/list?pageNum=1&pageSize=1', null, TOKENS.dispatch) const vehicleId = vehicleRes.data?.rows?.[0]?.vehicleId || 1 const dispatchRes = await request('POST', `/task/audit/${taskId}/dispatch`, { teamId: 90, vehicleId, auditUserId: ROLES.dispatch.userId, auditUserName: ROLES.dispatch.name, }, TOKENS.dispatch) console.log('Dispatch task response:', dispatchRes.code, dispatchRes.msg) await wait(2000) console.log('\n--- Messages after dispatch ---') console.log('Sales messages:', sales.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Dispatch messages:', dispatch.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Construction messages:', construction.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) // Step 4: Construction confirms task console.log('\n--- Step 4: Construction confirms task ---') const confirmRes = await request('POST', '/sop/execute-step', { taskId, stepCode: 'confirm', action: 'confirm', operatorId: ROLES.construction.userId, operatorName: ROLES.construction.name, }, TOKENS.construction) console.log('Confirm task response:', confirmRes.code, confirmRes.msg) await wait(2000) console.log('\n--- Messages after confirm ---') console.log('Sales messages:', sales.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Dispatch messages:', dispatch.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) // Step 5: Construction completes task (SOP finish step) console.log('\n--- Step 5: Construction completes task ---') const completeRes = await request('POST', '/sop/execute-step', { taskId, stepCode: 'finish', action: 'finish', operatorId: ROLES.construction.userId, operatorName: ROLES.construction.name, }, TOKENS.construction) console.log('Complete task response:', completeRes.code, completeRes.msg) await wait(2000) console.log('\n--- Messages after complete ---') console.log('Sales messages:', sales.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) console.log('Dispatch messages:', dispatch.messages.filter(m => m.type !== 'connected' && m.type !== 'pong').map(m => ({ type: m.type, title: m.title, content: m.content }))) // Check persisted messages console.log('\n--- Persisted messages for sales ---') const salesMsgRes = await request('GET', '/message/list?pageNum=1&pageSize=50', null, TOKENS.sales) console.log('Sales persisted messages:', salesMsgRes.data?.rows?.filter(m => m.extraData == taskId || m.content?.includes(taskNo)).map(m => ({ type: m.messageType, title: m.title, content: m.content, isRead: m.isRead }))) console.log('\n--- Persisted messages for dispatch ---') const dispatchMsgRes = await request('GET', '/message/list?pageNum=1&pageSize=50', null, TOKENS.dispatch) console.log('Dispatch persisted messages:', dispatchMsgRes.data?.rows?.filter(m => m.extraData == taskId || m.content?.includes(taskNo)).map(m => ({ type: m.messageType, title: m.title, content: m.content, isRead: m.isRead }))) console.log('\n--- Persisted messages for construction ---') const constructionMsgRes = await request('GET', '/message/list?pageNum=1&pageSize=50', null, TOKENS.construction) console.log('Construction persisted messages:', constructionMsgRes.data?.rows?.filter(m => m.extraData == taskId || m.content?.includes(taskNo)).map(m => ({ type: m.messageType, title: m.title, content: m.content, isRead: m.isRead }))) sales.ws.close() dispatch.ws.close() construction.ws.close() } main().catch((err) => { console.error('Test failed:', err) process.exit(1) })