import { test, expect } from '@playwright/test' const API_BASE = process.env.API_BASE || 'http://localhost:18080' test.describe('全流程 E2E:申请→评估→方案→派单→执行→验收→结算', () => { test('完整业务闭环', async ({ page }) => { // ===== 1. 登录 ===== await page.goto('/platform/login') await page.waitForSelector('input[placeholder="11位手机号"]') await page.getByPlaceholder('11位手机号').fill('13900000001') await page.getByPlaceholder('输入密码').fill('test123456') await page.locator('button.bg-primary').click() await page.waitForTimeout(2500) // Should redirect to /platform expect(page.url()).toMatch(/\/platform/) // ===== 2. 创建申请 ===== await page.goto('/platform/applications') await page.waitForTimeout(2000) await page.getByText('新建申请').click() await page.getByPlaceholder('如 2001').fill('2001') await page.getByPlaceholder('姓名').fill('张爷爷') await page.getByPlaceholder('手机号').fill('13800000001') await page.getByPlaceholder('详细地址').fill('梅江区金山街道') await page.getByText('提交申请').click() await page.waitForTimeout(2000) // ===== 3. 验证工作台 ===== await page.goto('/platform') await page.waitForTimeout(2000) await expect(page.getByText('工作台')).toBeVisible() }) test('API 直连全流程(后端验证)', async ({ request }) => { const H = { 'Content-Type': 'application/json', 'X-Tenant-Id': '1', 'X-Org-Id': '1', 'X-User-Role': 'ADMIN', 'X-User-Id': '1' } const genKey = () => 'e2e-pw-' + Date.now() + '-' + Math.random().toString(36).slice(2,6) // Create application let r = await request.post(`${API_BASE}/api/hss/applications`, { headers: { ...H, 'Idempotency-Key': genKey() }, data: { patientId:'2001', serviceType:'HOME_CARE', channel:'WECHAT', contactName:'PW', contactPhone:'13800000001', address:'梅江区', regionCode:'441402001' } }) expect(r.status()).toBe(200) const j1 = await r.json() expect(j1.code).toBe(200) const appId = j1.data.id // Submit r = await request.post(`${API_BASE}/api/hss/applications/${appId}/submit`, { headers: { ...H, 'Idempotency-Key': genKey() } }) expect(r.status()).toBe(200) // Accept r = await request.post(`${API_BASE}/api/hss/applications/${appId}/accept`, { headers: { ...H, 'Idempotency-Key': genKey() } }) expect(r.status()).toBe(200) // Assign assessment r = await request.post(`${API_BASE}/api/hss/assessments/${appId}/assign`, { headers: { ...H, 'Idempotency-Key': genKey() }, data: { assessorId: 1 } }) expect(r.status()).toBe(200) const j2 = await r.json() const asmId = j2.data?.id || 1 // Submit assessment r = await request.post(`${API_BASE}/api/hss/assessments/${asmId}/submit`, { headers: { ...H, 'Idempotency-Key': genKey() }, data: { careLevel:'LEVEL_3', riskLevel:'MEDIUM', reportContent:'{"mobility":"limited"}' } }) expect(r.status()).toBe(200) // Create plan r = await request.post(`${API_BASE}/api/hss/service-plans`, { headers: { ...H, 'Idempotency-Key': genKey() }, data: { applicationId: appId, assessmentTaskId: asmId, items: [{ serviceItemId:1, itemName:'助洁', unitPrice:50, frequency:3, standardDuration:60, evidenceRequired:false }] } }) expect(r.status()).toBe(200) const j3 = await r.json() const planId = j3.data?.id || 1 // Submit sign r = await request.post(`${API_BASE}/api/hss/service-plans/${planId}/submit-sign`, { headers: { ...H, 'Idempotency-Key': genKey() } }) expect(r.status()).toBe(200) console.log(`✅ E2E API pipeline: app#${appId} → asm#${asmId} → plan#${planId}`) }) test('非法状态转换被拦截', async ({ request }) => { const H = { 'Content-Type': 'application/json', 'X-Tenant-Id': '1', 'X-Org-Id': '1', 'X-User-Role': 'ADMIN', 'X-User-Id': '1' } const r = await request.post(`${API_BASE}/api/hss/applications/99999/accept`, { headers: H }) expect(r.status()).toBe(422) }) test('幂等去重验证', async ({ request }) => { const H = { 'Content-Type': 'application/json', 'X-Tenant-Id': '1', 'X-Org-Id': '1', 'X-User-Role': 'ADMIN', 'X-User-Id': '1' } const key = 'pw-idem-' + Date.now() const data = { type: 'demo', name: '幂等', orgName: '测试', phone: '13900000000', source: 'pw' } const r1 = await request.post(`${API_BASE}/api/hss/leads`, { headers: { ...H, 'Idempotency-Key': key }, data }) const r2 = await request.post(`${API_BASE}/api/hss/leads`, { headers: { ...H, 'Idempotency-Key': key }, data }) expect(r1.status()).toBe(200) expect(r2.status()).toBe(200) const j1 = await r1.json(); const j2 = await r2.json() expect(j1.data?.id || j1.data?.status).toBe(j2.data?.id || j2.data?.status) }) })