mirror of
https://github.com/Dichgrem/Vue.git
synced 2026-02-05 07:51:56 -05:00
313 lines
11 KiB
JavaScript
313 lines
11 KiB
JavaScript
import { defineConfig } from "vite";
|
||
import vue from "@vitejs/plugin-vue";
|
||
import VueDevTools from "vite-plugin-vue-devtools";
|
||
import fs from "fs";
|
||
import path from "path";
|
||
|
||
function mockPlugin() {
|
||
const mockDir = path.resolve(process.cwd(), "mock");
|
||
|
||
const filePath = (file) => path.resolve(mockDir, file);
|
||
|
||
const send = (res, obj, code = 200) => {
|
||
res.statusCode = code;
|
||
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
||
res.end(JSON.stringify(obj));
|
||
};
|
||
|
||
const readJson = (file, fallback) => {
|
||
const p = filePath(file);
|
||
if (!fs.existsSync(p)) return fallback;
|
||
try {
|
||
return JSON.parse(fs.readFileSync(p, "utf-8") || "null") ?? fallback;
|
||
} catch {
|
||
return fallback;
|
||
}
|
||
};
|
||
|
||
const writeJson = (file, data) => {
|
||
const p = filePath(file);
|
||
fs.writeFileSync(p, JSON.stringify(data, null, 2), "utf-8");
|
||
};
|
||
|
||
const readBodyJson = (req) =>
|
||
new Promise((resolve, reject) => {
|
||
let body = "";
|
||
req.on("data", (c) => (body += c));
|
||
req.on("end", () => {
|
||
try {
|
||
resolve(JSON.parse(body || "{}"));
|
||
} catch (e) {
|
||
reject(e);
|
||
}
|
||
});
|
||
});
|
||
|
||
const getPathname = (req) => {
|
||
try {
|
||
return new URL(req.url, "http://localhost").pathname;
|
||
} catch {
|
||
return req.url;
|
||
}
|
||
};
|
||
|
||
// 统一 success
|
||
const ok = (res) => send(res, { error: 0, msg: "success" });
|
||
|
||
// ===== 业务联动:积分更新规则 =====
|
||
// yearScore: score=duration*2,看起来是 1小时=2分
|
||
const POINTS_PER_HOUR = 2;
|
||
|
||
const addScore = (deltaHour) => {
|
||
const deltaScore = (Number(deltaHour) || 0) * POINTS_PER_HOUR;
|
||
|
||
// userInfo.json
|
||
const ui = readJson("userInfo.json", { error: 0, data: {} });
|
||
ui.data = ui.data || {};
|
||
ui.data.totalScore = (Number(ui.data.totalScore) || 0) + deltaScore;
|
||
writeJson("userInfo.json", ui);
|
||
|
||
// userScore.json
|
||
const us = readJson("userScore.json", { error: 0, data: {} });
|
||
us.data = us.data || {};
|
||
us.data.totalScore = (Number(us.data.totalScore) || 0) + deltaScore;
|
||
writeJson("userScore.json", us);
|
||
|
||
// scoreOverview.json
|
||
const ov = readJson("scoreOverview.json", { error: 0, data: {} });
|
||
ov.data = ov.data || {};
|
||
ov.data.totalScore = (Number(ov.data.totalScore) || 0) + deltaScore;
|
||
writeJson("scoreOverview.json", ov);
|
||
|
||
// yearScore.json
|
||
const ys = readJson("yearScore.json", { error: 0, data: {} });
|
||
ys.data = ys.data || {};
|
||
ys.data.times = (Number(ys.data.times) || 0) + 1;
|
||
ys.data.duration =
|
||
(Number(ys.data.duration) || 0) + (Number(deltaHour) || 0);
|
||
ys.data.score = (Number(ys.data.score) || 0) + deltaScore;
|
||
writeJson("yearScore.json", ys);
|
||
};
|
||
|
||
return {
|
||
name: "simple-mock-plugin",
|
||
configureServer(server) {
|
||
server.middlewares.use(async (req, res, next) => {
|
||
const pathname = getPathname(req);
|
||
|
||
// ========== GET:仍然走你原来的静态文件 ==========
|
||
const sendJSON = (file) => {
|
||
const p = filePath(file);
|
||
if (!fs.existsSync(p)) {
|
||
return send(res, { error: `Mock file not found: ${file}` }, 404);
|
||
}
|
||
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
||
res.end(fs.readFileSync(p, "utf-8"));
|
||
};
|
||
|
||
if (pathname === "/api/userInfo" && req.method === "GET")
|
||
return sendJSON("userInfo.json");
|
||
if (pathname.startsWith("/api/actList") && req.method === "GET")
|
||
return sendJSON("actList.json");
|
||
if (
|
||
pathname.startsWith("/api/report/myOverview") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("scoreOverview.json");
|
||
if (pathname.startsWith("/api/report/rankList") && req.method === "GET")
|
||
return sendJSON("rank.json");
|
||
if (
|
||
pathname.startsWith("/api/actDetails/details") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("actDetails.json");
|
||
if (pathname.startsWith("/api/myApplyList") && req.method === "GET")
|
||
return sendJSON("myApplyList.json");
|
||
if (
|
||
pathname.startsWith("/api/act/publisherList") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("publishers.json");
|
||
if (
|
||
pathname.startsWith("/api/act/durationsList") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("durationList.json");
|
||
if (
|
||
pathname.startsWith("/api/service/userScore") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("userScore.json");
|
||
if (
|
||
pathname.startsWith("/api/service/yearList") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("yearList.json");
|
||
if (
|
||
pathname.startsWith("/api/service/yearScore") &&
|
||
req.method === "GET"
|
||
)
|
||
return sendJSON("yearScore.json");
|
||
if (pathname.startsWith("/api/service/list") && req.method === "GET")
|
||
return sendJSON("serviceList.json");
|
||
if (pathname.startsWith("/api/service/details") && req.method === "GET")
|
||
return sendJSON("recordDetails.json");
|
||
|
||
// ========== POST:全部改成“落盘” ==========
|
||
// 1) 用户信息保存
|
||
if (pathname === "/api/userInfo/submit" && req.method === "POST") {
|
||
try {
|
||
const incoming = await readBodyJson(req); // {name,code,gender,phoneNum,school,profession,userType...}
|
||
const old = readJson("userInfo.json", { error: 0, data: {} });
|
||
const next = {
|
||
error: 0,
|
||
data: { ...(old.data || {}), ...incoming },
|
||
};
|
||
writeJson("userInfo.json", next);
|
||
return ok(res);
|
||
} catch {
|
||
return send(res, { error: 1, msg: "Invalid JSON body" }, 400);
|
||
}
|
||
}
|
||
|
||
// 2) 申请/撤销活动:更新 myApplyList + actDetails(可选 actList)
|
||
if (
|
||
pathname.startsWith("/api/actDetails/apply") &&
|
||
req.method === "POST"
|
||
) {
|
||
try {
|
||
const incoming = await readBodyJson(req);
|
||
// 约定:至少要有 id;可选传 action: "apply" | "cancel"
|
||
const id = Number(incoming.id ?? incoming.actId);
|
||
const action = incoming.action || "apply";
|
||
if (!id) return send(res, { error: 1, msg: "missing id" }, 400);
|
||
|
||
// 读活动列表,用来补齐标题/时间/地点等字段
|
||
const actList = readJson("actList.json", {
|
||
error: 0,
|
||
data: { list: [] },
|
||
});
|
||
const act = (actList.data?.list || []).find(
|
||
(x) => Number(x.id) === id,
|
||
);
|
||
|
||
// myApplyList.json
|
||
const applyJson = readJson("myApplyList.json", {
|
||
error: 0,
|
||
data: { current: 1, pageSize: 10, pageCount: 1, list: [] },
|
||
});
|
||
const list = applyJson.data?.list || [];
|
||
const existsIdx = list.findIndex((x) => Number(x.id) === id);
|
||
|
||
if (action === "cancel") {
|
||
if (existsIdx >= 0) list.splice(existsIdx, 1);
|
||
} else {
|
||
// apply
|
||
if (existsIdx < 0) {
|
||
// 申请状态:你的 mock 里 1/2 出现过。这里用 1 表示已申请
|
||
list.unshift({ ...(act || { id }), applyStatus: 1 });
|
||
} else {
|
||
list[existsIdx].applyStatus = 1;
|
||
}
|
||
}
|
||
|
||
applyJson.data = applyJson.data || {};
|
||
applyJson.data.list = list;
|
||
applyJson.data.pageCount = 1;
|
||
writeJson("myApplyList.json", applyJson);
|
||
|
||
// actDetails.json:让详情页刷新后看到申请状态变化
|
||
const detailsJson = readJson("actDetails.json", {
|
||
error: 0,
|
||
data: { details: {} },
|
||
});
|
||
if (
|
||
detailsJson.data?.details &&
|
||
Number(detailsJson.data.details.id) === id
|
||
) {
|
||
if (action === "cancel") {
|
||
detailsJson.data.details.applyStatus = 0;
|
||
detailsJson.data.details.canApply = true;
|
||
} else {
|
||
detailsJson.data.details.applyStatus = 1;
|
||
detailsJson.data.details.canApply = false;
|
||
}
|
||
writeJson("actDetails.json", detailsJson);
|
||
}
|
||
|
||
// actList.json(可选):列表 canApply 同步变化
|
||
if (act) {
|
||
const idx = (actList.data?.list || []).findIndex(
|
||
(x) => Number(x.id) === id,
|
||
);
|
||
if (idx >= 0) {
|
||
actList.data.list[idx].canApply = action === "cancel";
|
||
writeJson("actList.json", actList);
|
||
}
|
||
}
|
||
|
||
return ok(res);
|
||
} catch {
|
||
return send(res, { error: 1, msg: "Invalid JSON body" }, 400);
|
||
}
|
||
}
|
||
|
||
// 3) 上传服务记录:写 serviceList + 联动积分文件
|
||
if (
|
||
pathname.startsWith("/api/act/uploadService") &&
|
||
req.method === "POST"
|
||
) {
|
||
try {
|
||
const incoming = await readBodyJson(req);
|
||
// 约定:时长字段可能叫 hour / duration / value
|
||
const hour =
|
||
Number(
|
||
incoming.hour ?? incoming.duration ?? incoming.value ?? 0,
|
||
) || 0;
|
||
|
||
// serviceList.json 结构:{data:{list:[{id,pic,content,publisher,time,status}]}}
|
||
const sl = readJson("serviceList.json", {
|
||
error: 0,
|
||
data: { current: 1, pageSize: 10, pageCount: 1, list: [] },
|
||
});
|
||
const list = sl.data?.list || [];
|
||
|
||
const nextId =
|
||
list.reduce((m, x) => Math.max(m, Number(x.id) || 0), 0) + 1;
|
||
|
||
list.unshift({
|
||
id: nextId,
|
||
pic: incoming.pic || "./imgs/actImg.jpeg",
|
||
content: incoming.content || "新增服务记录",
|
||
publisher: incoming.publisher || "未知来源",
|
||
time: incoming.time || Date.now(),
|
||
status: 1, // 1=通过?你 recordDetails.status=1,看起来是已审核/有效
|
||
// 额外字段可保留(不影响页面)
|
||
hour,
|
||
});
|
||
|
||
sl.data = sl.data || {};
|
||
sl.data.list = list;
|
||
sl.data.pageCount = 1;
|
||
writeJson("serviceList.json", sl);
|
||
|
||
// 同步更新积分(按 1小时=2分)
|
||
if (hour > 0) addScore(hour);
|
||
|
||
return ok(res);
|
||
} catch {
|
||
return send(res, { error: 1, msg: "Invalid JSON body" }, 400);
|
||
}
|
||
}
|
||
|
||
next();
|
||
});
|
||
},
|
||
};
|
||
}
|
||
|
||
export default defineConfig({
|
||
base: "./",
|
||
plugins: [vue(), mockPlugin(), VueDevTools()],
|
||
});
|