const CAPTURE_FILES = [ "/__mirror/captures/hc-pos-dashboard-apis.json", "/__mirror/captures/hc-pos-basicsInfo-apis.json" ]; let fixturesPromise = null; let storageSeedPromise = null; self.addEventListener("install", (event) => { self.skipWaiting(); event.waitUntil(loadFixtures()); }); self.addEventListener("activate", (event) => { event.waitUntil(self.clients.claim()); }); self.addEventListener("fetch", (event) => { const requestUrl = new URL(event.request.url); if (!requestUrl.hostname.includes("app-project-be.sqygj.cn")) { return; } event.respondWith(handleApiRequest(event.request)); }); async function loadFixtures() { if (fixturesPromise) { return fixturesPromise; } fixturesPromise = (async () => { const fixtureMap = new Map(); for (const file of CAPTURE_FILES) { const response = await fetch(file, { cache: "no-store" }); if (!response.ok) { continue; } const items = await response.json(); items .filter((item) => item.resource_type === "XHR") .forEach((item) => { fixtureMap.set(item.url, item); }); } return fixtureMap; })(); return fixturesPromise; } async function loadStorageSeed() { if (storageSeedPromise) { return storageSeedPromise; } storageSeedPromise = (async () => { const response = await fetch("./storage-seed.json", { cache: "no-store" }); if (!response.ok) { return {}; } return response.json(); })(); return storageSeedPromise; } async function handleApiRequest(request) { const fixtures = await loadFixtures(); if (request.method === "OPTIONS") { return new Response("", { status: 200, headers: corsHeaders("text/plain;charset=utf-8") }); } const fixture = fixtures.get(request.url); if (fixture) { return new Response(fixture.body || "", { status: fixture.status || 200, headers: corsHeaders(fixture.mime_type || "application/json;charset=utf-8") }); } const mockResponse = await buildMockResponse(request); return new Response(JSON.stringify(mockResponse), { status: 200, headers: corsHeaders("application/json;charset=utf-8") }); } function corsHeaders(contentType) { return { "Content-Type": contentType, "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,OPTIONS", "Access-Control-Allow-Headers": "*" }; } function ok(data) { return { data, code: 0, message: "mock success.", ok: true }; } function paged(records = []) { return ok({ rowsCount: records.length, pageNumber: 1, pageSize: 10, pageCount: records.length ? 1 : 0, records }); } function basicStats() { return ok({ total: 0, num: 0, count: 0, value: 0, amount: 0, ratio: 0, rate: 0 }); } async function buildMockResponse(request) { const url = new URL(request.url); const path = url.pathname; const seed = await loadStorageSeed(); const targetInfo = parseTargetInfo(seed); const currentProject = parseCurrentProject(seed); if (path.endsWith("/appproject/account/findProjectByRoleId")) { return ok(targetInfo.projectList || []); } if (path.endsWith("/appproject/account/findByAccount")) { return ok(targetInfo.accountProfile || {}); } if (path.endsWith("/appproject/project/findByCode")) { return ok(mockProjectDetail(currentProject)); } if (path.endsWith("/appproject/account/findByCompanyId")) { return ok((targetInfo.projectList || []).filter((item) => item.companyId === currentProject.companyId)); } if (path.endsWith("/appproject/data/project/serviceCount")) { return ok({ countryCount: null, provinceCount: 1, cityCount: 1, areaCount: 1, streetCount: 1, companyCount: 1, projectCount: 1, manageArea: 13848, contractArea: 41980.48, serviceArea: 78000, payArea: 3440.51, totalHouse: 38, totalHouseMember: 65, totalUser: 120, ownerUser: 25, status0Count: 0, status1Count: 0, status2Count: 0, status3Count: 1, status4Count: 10, status5Count: 0 }); } if (path.endsWith("/appproject/PlatformMessage/noticePageList")) { return paged([ { id: 1, title: "本地镜像通知", content: "这是本地 mock 数据,用于运行态镜像演示。", createTime: "2026-04-01 22:00:00" } ]); } if (path.endsWith("/appproject/OperationalGuidance/pageList")) { return paged([ { id: 1, title: "系统配置(项目平台)合集", tag: "项目平台" }, { id: 2, title: "满意度(公告+问卷+周检)", tag: "满意度" }, { id: 3, title: "工程管理—计划工单", tag: "工单" } ]); } if (path.endsWith("/appproject/AgentConfig/getAgentUrl")) { return ok("https://example.com/mock-agent"); } if (path.endsWith("/appproject/WorkOrder/findByProjectUuidAndAccountUuid")) { return ok([ { id: 1, status: 1, title: "巡检工单", createTime: "2026-04-01 10:00:00" }, { id: 2, status: 2, title: "报修工单", createTime: "2026-04-01 11:30:00" } ]); } if (/\/check[A-Z]/.test(path) || /\/check[a-zA-Z]/.test(path) || path.includes("/checkTips")) { return ok(false); } if (path.includes("/pageList")) { return paged([]); } if (path.includes("/treeList") || path.includes("/getList") || path.endsWith("/list")) { return ok([]); } if ( path.includes("/create") || path.includes("/update") || path.includes("/delete") || path.includes("/save") || path.includes("/edit") || path.includes("/bind") || path.includes("/sync") ) { return ok(true); } if ( path.includes("/total") || path.includes("/statistics") || path.includes("/report") || path.includes("/chart") || path.includes("/count") ) { return basicStats(); } if (path.includes("/findById") || path.includes("/detail") || path.includes("/findBy")) { return ok({}); } return ok({}); } function parseTargetInfo(seed) { try { const raw = JSON.parse(seed.C_userInfo || "{}"); const targetInfo = JSON.parse(raw.targetInfo || "{}"); return { accountProfile: targetInfo, projectList: targetInfo.projectList || [], menuTree: targetInfo.menuSelectAllResponseByProject || [] }; } catch (_error) { return {}; } } function parseCurrentProject(seed) { try { return JSON.parse(seed.store || "{}"); } catch (_error) { return {}; } } function mockProjectDetail(project) { return { id: project.id || 426, code: project.community_uuid || "mock-project-code", name: project.community_name || "循环花园一期", nickname: "箭楼下社区", developer: "腾龙开发商", floorage: 41980.48, greeningArea: 78000, manageArea: 13848, payArea: 3440.51, houseCount: 38, houseMemberCount: 65, province: "湖北省", city: "黄石市", area: "下陆区", street: "团城山街道", longitude: "119.919847", latitude: "31.016537", architectureType: "高层", deliverDate: "2010-07-01", architectureDate: "2008-07-01", layout: "一室一厅", address: "下陆区团城山街道龙湾一品小区", image: "https://sqy-oss-test.oss-cn-guangzhou.aliyuncs.com/20220320/1647777882795_f65e03a8.jpg", signature: "https://sqy-oss-test.oss-cn-guangzhou.aliyuncs.com/20230414/1681480367954_5c56e2c5.png", companyId: project.companyId || 421, companyUuid: project.companyUuid || "92115dc9-09a2-42da-b9bb-60352c900a53", codeNumber: project.codeNumber || "X39839", star: project.star || 5, payMethod: 2, manageType: 7 }; }