verify-notifications.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. const WebSocket = require('ws')
  2. const http = require('http')
  3. const BASE_URL = 'http://localhost:8080/api'
  4. const WS_URL = 'ws://localhost:8080/api/ws/notify'
  5. const TOKENS = {
  6. sales: 'mock-token-mp-21',
  7. dispatch: 'mock-token-mp-13',
  8. construction: 'mock-token-mp-15',
  9. }
  10. const ROLES = {
  11. sales: { userId: 21, name: '徐云辉' },
  12. dispatch: { userId: 13, name: '张智城' },
  13. construction: { userId: 15, name: '测试实施1' },
  14. }
  15. function request(method, path, data, token) {
  16. return new Promise((resolve, reject) => {
  17. const options = {
  18. hostname: 'localhost',
  19. port: 8080,
  20. path: '/api' + path,
  21. method,
  22. headers: {
  23. 'Content-Type': 'application/json',
  24. 'Authorization': `Bearer ${token}`,
  25. },
  26. }
  27. const req = http.request(options, (res) => {
  28. let body = ''
  29. res.on('data', (chunk) => (body += chunk))
  30. res.on('end', () => {
  31. try {
  32. resolve(JSON.parse(body))
  33. } catch (e) {
  34. resolve(body)
  35. }
  36. })
  37. })
  38. req.on('error', reject)
  39. if (data) req.write(JSON.stringify(data))
  40. req.end()
  41. })
  42. }
  43. function connectWebSocket(role) {
  44. return new Promise((resolve, reject) => {
  45. const ws = new WebSocket(`${WS_URL}?token=${encodeURIComponent(TOKENS[role])}`)
  46. const messages = []
  47. ws.on('open', () => {
  48. console.log(`[${role}] WebSocket connected`)
  49. resolve({ ws, messages })
  50. })
  51. ws.on('message', (data) => {
  52. const msg = JSON.parse(data.toString())
  53. console.log(`[${role}] received raw:`, msg.type, msg.title || '', msg.content || '')
  54. messages.push(msg)
  55. })
  56. ws.on('error', (err) => {
  57. console.error(`[${role}] WebSocket error:`, err.message)
  58. reject(err)
  59. })
  60. ws.on('close', () => {
  61. console.log(`[${role}] WebSocket closed`)
  62. })
  63. })
  64. }
  65. function wait(ms) {
  66. return new Promise((resolve) => setTimeout(resolve, ms))
  67. }
  68. async function main() {
  69. console.log('Connecting WebSockets...')
  70. const sales = await connectWebSocket('sales')
  71. const dispatch = await connectWebSocket('dispatch')
  72. const construction = await connectWebSocket('construction')
  73. await wait(1000)
  74. // Step 1: Sales creates a task
  75. console.log('\n--- Step 1: Sales creates task ---')
  76. const taskNo = 'TK-TEST-' + Date.now()
  77. const createRes = await request('POST', '/task', {
  78. taskNo,
  79. projectId: 33,
  80. taskType: 'dredge',
  81. planDate: '2026-07-26',
  82. address: '测试地址',
  83. taskName: '测试任务-' + Date.now(),
  84. }, TOKENS.sales)
  85. console.log('Create task response:', createRes.code, createRes.msg)
  86. if (createRes.code !== 200) {
  87. console.error('Failed to create task:', createRes)
  88. process.exit(1)
  89. }
  90. const taskId = createRes.data
  91. await wait(2000)
  92. console.log('\n--- Messages after create ---')
  93. 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 })))
  94. 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 })))
  95. 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 })))
  96. // Step 2: Dispatch approves task
  97. console.log('\n--- Step 2: Dispatch approves task ---')
  98. const approveRes = await request('POST', `/task/audit/${taskId}/approve`, {
  99. auditUserId: ROLES.dispatch.userId,
  100. auditUserName: ROLES.dispatch.name,
  101. }, TOKENS.dispatch)
  102. console.log('Approve task response:', approveRes.code, approveRes.msg)
  103. await wait(2000)
  104. console.log('\n--- Messages after approve ---')
  105. 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 })))
  106. 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 })))
  107. // Step 3: Dispatch dispatches task to construction team 90
  108. console.log('\n--- Step 3: Dispatch dispatches task to team 90 ---')
  109. // Need a vehicle. Let's query vehicles first.
  110. const vehicleRes = await request('GET', '/vehicle/list?pageNum=1&pageSize=1', null, TOKENS.dispatch)
  111. const vehicleId = vehicleRes.data?.rows?.[0]?.vehicleId || 1
  112. const dispatchRes = await request('POST', `/task/audit/${taskId}/dispatch`, {
  113. teamId: 90,
  114. vehicleId,
  115. auditUserId: ROLES.dispatch.userId,
  116. auditUserName: ROLES.dispatch.name,
  117. }, TOKENS.dispatch)
  118. console.log('Dispatch task response:', dispatchRes.code, dispatchRes.msg)
  119. await wait(2000)
  120. console.log('\n--- Messages after dispatch ---')
  121. 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 })))
  122. 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 })))
  123. 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 })))
  124. // Step 4: Construction confirms task
  125. console.log('\n--- Step 4: Construction confirms task ---')
  126. const confirmRes = await request('POST', '/sop/execute-step', {
  127. taskId,
  128. stepCode: 'confirm',
  129. action: 'confirm',
  130. operatorId: ROLES.construction.userId,
  131. operatorName: ROLES.construction.name,
  132. }, TOKENS.construction)
  133. console.log('Confirm task response:', confirmRes.code, confirmRes.msg)
  134. await wait(2000)
  135. console.log('\n--- Messages after confirm ---')
  136. 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 })))
  137. 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 })))
  138. // Step 5: Construction completes task (SOP finish step)
  139. console.log('\n--- Step 5: Construction completes task ---')
  140. const completeRes = await request('POST', '/sop/execute-step', {
  141. taskId,
  142. stepCode: 'finish',
  143. action: 'finish',
  144. operatorId: ROLES.construction.userId,
  145. operatorName: ROLES.construction.name,
  146. }, TOKENS.construction)
  147. console.log('Complete task response:', completeRes.code, completeRes.msg)
  148. await wait(2000)
  149. console.log('\n--- Messages after complete ---')
  150. 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 })))
  151. 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 })))
  152. // Check persisted messages
  153. console.log('\n--- Persisted messages for sales ---')
  154. const salesMsgRes = await request('GET', '/message/list?pageNum=1&pageSize=50', null, TOKENS.sales)
  155. 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 })))
  156. console.log('\n--- Persisted messages for dispatch ---')
  157. const dispatchMsgRes = await request('GET', '/message/list?pageNum=1&pageSize=50', null, TOKENS.dispatch)
  158. 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 })))
  159. console.log('\n--- Persisted messages for construction ---')
  160. const constructionMsgRes = await request('GET', '/message/list?pageNum=1&pageSize=50', null, TOKENS.construction)
  161. 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 })))
  162. sales.ws.close()
  163. dispatch.ws.close()
  164. construction.ws.close()
  165. }
  166. main().catch((err) => {
  167. console.error('Test failed:', err)
  168. process.exit(1)
  169. })