309 lines
7.6 KiB
JavaScript
309 lines
7.6 KiB
JavaScript
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
|
|
};
|
|
}
|