init: 迁移本地前端代码(Gitea 仓库重建后重新初始化)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import { createProdMockServer } from "vite-plugin-mock/es/createProdMockServer";
|
||||
import NoticeMock from "./noticeapi";
|
||||
|
||||
export function setupProdMockServer() {
|
||||
createProdMockServer([...NoticeMock]);
|
||||
}
|
||||
@@ -0,0 +1,724 @@
|
||||
/**
|
||||
* 通知公告本地 Mock 数据(vite-plugin-mock,dev 下 VITE_IS_MOCK=true 生效)。
|
||||
*
|
||||
* 背景:本地无法访问 sso.yunhaixingtong.com / base.yunhaixingtong.com,
|
||||
* 后端 CAS 过滤器会拦截 /api/* 请求,导致前端无法联调。
|
||||
* 该文件按后端 NoticeApiController / DictController / ContactsController /
|
||||
* FileController 的真实响应契约({code, msg, data})提供内存数据,
|
||||
* 仅用于前端页面调试,字段结构与线上后端保持一致。
|
||||
*/
|
||||
|
||||
/* ============================ 基础数据 ============================ */
|
||||
|
||||
const deptDict = [
|
||||
{ SerID: 101, CodeID: "D001", Name: "校长室", Enable: 1 },
|
||||
{ SerID: 102, CodeID: "D002", Name: "办公室", Enable: 1 },
|
||||
{ SerID: 103, CodeID: "D003", Name: "教务处", Enable: 1 },
|
||||
{ SerID: 104, CodeID: "D004", Name: "政教处", Enable: 1 },
|
||||
{ SerID: 105, CodeID: "D005", Name: "总务处", Enable: 1 },
|
||||
{ SerID: 106, CodeID: "D006", Name: "电教组", Enable: 1 },
|
||||
{ SerID: 107, CodeID: "D007", Name: "英语组", Enable: 0 },
|
||||
{ SerID: 108, CodeID: "D008", Name: "语文组", Enable: 1 },
|
||||
];
|
||||
|
||||
let deptSeq = 109;
|
||||
let nextFileId = 9001;
|
||||
|
||||
/** 通知存储(Create/EditNotice 会写入这里,刷新页面即还原) */
|
||||
const notices = [
|
||||
{
|
||||
serid: 1,
|
||||
title: "关于开展2026年秋季学期教学检查的通知",
|
||||
DeptID: "D001",
|
||||
DeptName: "校长室",
|
||||
TeaName: "刘文娟",
|
||||
TeaAccount: "lwj",
|
||||
EditDate: "2026-08-20 10:35:00",
|
||||
createTime: "2026-08-20 10:35:00",
|
||||
Contents: "<p>各位老师:</p><p>定于下周开展秋季学期教学检查,请各教研组提前准备教案、听课记录等材料。</p><p>具体安排另行通知。</p>",
|
||||
ReceiveList: "ALL",
|
||||
allowcount: 33,
|
||||
readcount: 12,
|
||||
UpFile: "9001,9002",
|
||||
isDsfs: false,
|
||||
DsfsTime: null,
|
||||
readUsers: [
|
||||
{ account: "zhd", name: "朱皓东", read: true },
|
||||
{ account: "lwm", name: "刘文娟", read: true },
|
||||
{ account: "cy", name: "陈垠", read: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
serid: 2,
|
||||
title: "校园网络安全培训通知",
|
||||
DeptID: "D006",
|
||||
DeptName: "电教组",
|
||||
TeaName: "黄瑶",
|
||||
TeaAccount: "hy",
|
||||
EditDate: "2026-08-22 14:22:00",
|
||||
createTime: "2026-08-22 14:22:00",
|
||||
Contents: "<p>定于本周五下午 15:00 在报告厅开展校园网络安全培训,请全体教职工准时参加。</p>",
|
||||
ReceiveList: "ALL",
|
||||
allowcount: 33,
|
||||
readcount: 5,
|
||||
UpFile: null,
|
||||
isDsfs: false,
|
||||
DsfsTime: null,
|
||||
readUsers: [
|
||||
{ account: "zhd", name: "朱皓东", read: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
serid: 3,
|
||||
title: "关于2026年教师节活动安排的通知",
|
||||
DeptID: "D002",
|
||||
DeptName: "办公室",
|
||||
TeaName: "刘文娟",
|
||||
TeaAccount: "lwj",
|
||||
EditDate: "2026-08-25 09:00:00",
|
||||
createTime: "2026-08-25 09:00:00",
|
||||
Contents: "<p>今年教师节主题活动定于 9 月 10 日下午举行,节目报名请于 9 月 5 日前报至办公室。</p>",
|
||||
ReceiveList: '["zhd","cy","hj"]',
|
||||
allowcount: 3,
|
||||
readcount: 1,
|
||||
UpFile: null,
|
||||
isDsfs: false,
|
||||
DsfsTime: null,
|
||||
readUsers: [
|
||||
{ account: "zhd", name: "朱皓东", read: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
serid: 4,
|
||||
title: "学期末固定资产清点通知",
|
||||
DeptID: "D005",
|
||||
DeptName: "总务处",
|
||||
TeaName: "测试教师4(资产保管员)4",
|
||||
TeaAccount: "zcby",
|
||||
EditDate: "2026-08-27 16:40:00",
|
||||
createTime: "2026-08-27 16:40:00",
|
||||
Contents: "<p>请各科室在放假前完成固定资产清点,并填写清点表交至总务处。</p>",
|
||||
ReceiveList: "ALL",
|
||||
allowcount: 33,
|
||||
readcount: 0,
|
||||
UpFile: null,
|
||||
isDsfs: true,
|
||||
DsfsTime: "2026-09-01 08:00:00",
|
||||
readUsers: [],
|
||||
},
|
||||
{
|
||||
serid: 5,
|
||||
title: "教学质量月活动方案(讨论稿)",
|
||||
DeptID: "D003",
|
||||
DeptName: "教务处",
|
||||
TeaName: "刘文娟",
|
||||
TeaAccount: "lwj",
|
||||
EditDate: "2026-08-28 11:05:00",
|
||||
createTime: "2026-08-28 11:05:00",
|
||||
Contents: "<p>附件为教学质量月活动方案讨论稿,请各位老师审阅并反馈意见。</p>",
|
||||
ReceiveList: "ALL",
|
||||
allowcount: 33,
|
||||
readcount: 2,
|
||||
UpFile: "9003",
|
||||
isDsfs: false,
|
||||
DsfsTime: null,
|
||||
readUsers: [
|
||||
{ account: "cy", name: "陈垠", read: true },
|
||||
{ account: "hj", name: "何明明", read: true },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const filesStore = {
|
||||
9001: { id: 9001, filename: "教学检查安排表.xlsx", fileTrueName: "教学检查安排表.xlsx", size: "56KB" },
|
||||
9002: { id: 9002, filename: "检查评分标准.docx", fileTrueName: "检查评分标准.docx", size: "120KB" },
|
||||
9003: { id: 9003, filename: "教学质量月活动方案.pdf", fileTrueName: "教学质量月活动方案.pdf", size: "800KB" },
|
||||
};
|
||||
|
||||
/** 联系组存储(成员为用户 id,与后端 SetContactsTea 存 userId 一致) */
|
||||
const groups = [
|
||||
{ serid: 1, GroupName: "英语组", members: [2, 8, 9] },
|
||||
{ serid: 2, GroupName: "电教组", members: [10, 11] },
|
||||
{ serid: 3, GroupName: "测试组", members: [1, 4, 6] },
|
||||
];
|
||||
let groupSeq = 4;
|
||||
|
||||
/** 用户 id → 姓名(组织树叶子 / 联系组成员共用,与 schoolTree 叶子 id 对应) */
|
||||
const idNames: Record<number, string> = {
|
||||
1: "朱皓东",
|
||||
2: "刘文娟",
|
||||
3: "陈垠",
|
||||
4: "测试教师5",
|
||||
5: "测试教师14",
|
||||
6: "何明明",
|
||||
7: "测试教师1(资金确认人)",
|
||||
8: "测试教师5",
|
||||
9: "测试教师17",
|
||||
10: "纯教2",
|
||||
11: "黄瑶",
|
||||
};
|
||||
|
||||
/** 教师账号表(组织树叶子 / 联系组成员共用) */
|
||||
const teacherNames = {
|
||||
zhd: "朱皓东",
|
||||
lwm: "刘文娟",
|
||||
cy: "陈垠",
|
||||
hy: "黄瑶",
|
||||
hj: "何明明",
|
||||
zwj: "洛文君",
|
||||
ls001: "测试教师001",
|
||||
js1: "测试教师1",
|
||||
js2: "测试教师2",
|
||||
js5: "测试教师5",
|
||||
js17: "测试教师17",
|
||||
zjzr: "测试教师1(资金确认人)",
|
||||
zcby: "测试教师4(资产保管员)4",
|
||||
};
|
||||
|
||||
/** 基础平台组织树(选择用户 - 基础平台 tab),叶子为教师;isParent 区分组/用户 */
|
||||
const schoolTree = [
|
||||
{
|
||||
id: 301,
|
||||
name: "校长室",
|
||||
isParent: true,
|
||||
children: [
|
||||
{ id: 1, name: "朱皓东", isParent: false },
|
||||
{ id: 2, name: "刘文娟", isParent: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 302,
|
||||
name: "副校长室",
|
||||
isParent: true,
|
||||
children: [{ id: 3, name: "陈垠", isParent: false }],
|
||||
},
|
||||
{
|
||||
id: 303,
|
||||
name: "教务处",
|
||||
isParent: true,
|
||||
children: [
|
||||
{ id: 4, name: "测试教师5", isParent: false },
|
||||
{ id: 5, name: "测试教师14", isParent: false },
|
||||
{ id: 6, name: "何明明", isParent: false },
|
||||
{ id: 7, name: "测试教师1(资金确认人)", isParent: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 304,
|
||||
name: "英语组",
|
||||
isParent: true,
|
||||
children: [
|
||||
{ id: 8, name: "测试教师5", isParent: false },
|
||||
{ id: 9, name: "测试教师17", isParent: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 305,
|
||||
name: "电教组",
|
||||
isParent: true,
|
||||
children: [
|
||||
{ id: 10, name: "纯教2", isParent: false },
|
||||
{ id: 11, name: "黄瑶", isParent: false },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
/* ============================ 工具 ============================ */
|
||||
|
||||
function ok(data: any) {
|
||||
return { code: 0, msg: "操作成功", data };
|
||||
}
|
||||
|
||||
function paginate(list: any[], pageIndex: number, pageSize: number) {
|
||||
const start = (pageIndex - 1) * pageSize;
|
||||
return { list: list.slice(start, start + pageSize), total: list.length };
|
||||
}
|
||||
|
||||
function resolveReceiveAccounts(receiveList: string) {
|
||||
if (!receiveList || /^all$/i.test(receiveList.trim())) return [];
|
||||
if (receiveList.trim().startsWith("[")) {
|
||||
try {
|
||||
return JSON.parse(receiveList);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return receiveList.split(",").filter(Boolean);
|
||||
}
|
||||
|
||||
function fileUrl(id: number) {
|
||||
return `/api/base/FileDown?id=${id}`;
|
||||
}
|
||||
|
||||
/* ============================ Mock 定义 ============================ */
|
||||
|
||||
export default [
|
||||
/* ---------- 布局 / 用户 ---------- */
|
||||
{
|
||||
url: "/api/base/GetUserInfo",
|
||||
method: "get",
|
||||
response: () =>
|
||||
ok({
|
||||
id: 186532,
|
||||
account: "zhd",
|
||||
name: "朱皓东",
|
||||
profilePicture: "",
|
||||
school: { id: 3260, name: "上海鸿育初级中学" },
|
||||
}),
|
||||
},
|
||||
{
|
||||
url: "/api/base/GetUserMod",
|
||||
method: "get",
|
||||
response: () =>
|
||||
ok([
|
||||
{ id: 1, modId: 1, name: "已收到", parentId: 0, page: "/", orderNumber: 1, usable: true, children: [] },
|
||||
{ id: 2, modId: 2, name: "已发送", parentId: 0, page: "/list", orderNumber: 2, usable: true, children: [] },
|
||||
{ id: 3, modId: 3, name: "全部通知", parentId: 0, page: "/noticelist", orderNumber: 3, usable: true, children: [] },
|
||||
{ id: 4, modId: 4, name: "通知统计", parentId: 0, page: "/stats", orderNumber: 4, usable: true, children: [] },
|
||||
{ id: 21, modId: 21, name: "应用设置", parentId: 0, page: "/setting", orderNumber: 5, usable: true, children: [] },
|
||||
]),
|
||||
},
|
||||
{
|
||||
url: "/api/base/GetLayout",
|
||||
method: "get",
|
||||
response: () =>
|
||||
ok({
|
||||
ssoUrl: "",
|
||||
username: "朱皓东",
|
||||
pathList: [],
|
||||
topName: "通知公告",
|
||||
pageUrl: "",
|
||||
logoUrl: "",
|
||||
initUrl: "",
|
||||
id: 0,
|
||||
avatar: "",
|
||||
}),
|
||||
},
|
||||
|
||||
/* ---------- 发文部门字典 ---------- */
|
||||
{
|
||||
url: "/api/base/GetSysDic",
|
||||
method: "get",
|
||||
response: ({ query }: any) =>
|
||||
ok(
|
||||
deptDict
|
||||
.filter((d) => d.Enable === 1 || query.type !== "1")
|
||||
.map((d) => ({ k: d.CodeID, v: d.Name }))
|
||||
),
|
||||
},
|
||||
{
|
||||
url: "/api/base/GetDictMangeList",
|
||||
method: "get",
|
||||
response: () => ok(deptDict.map((d) => ({ ...d }))),
|
||||
},
|
||||
{
|
||||
url: "/api/base/AddDeptDic",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const name = new URLSearchParams(body).get("name") || "未命名";
|
||||
deptDict.push({ SerID: deptSeq++, CodeID: "D" + String(deptSeq).padStart(3, "0"), Name: name, Enable: 1 });
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/base/UpdateDeptDic",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const sp = new URLSearchParams(body);
|
||||
const serid = Number(sp.get("SerID"));
|
||||
const item = deptDict.find((d) => d.SerID === serid);
|
||||
if (item) {
|
||||
if (sp.get("Name")) item.Name = sp.get("Name") as string;
|
||||
if (sp.get("Enable") !== null) item.Enable = Number(sp.get("Enable"));
|
||||
}
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/base/DelDept",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const i = deptDict.findIndex((d) => d.SerID === Number(query.serid));
|
||||
if (i > -1) deptDict.splice(i, 1);
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/base/OrdbyDicIds",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const ids = String(query.ids || "").split(",").map(Number);
|
||||
const sorted = ids.map((id) => deptDict.find((d) => d.SerID === id)).filter(Boolean);
|
||||
if (sorted.length === deptDict.length) deptDict.splice(0, deptDict.length, ...(sorted as any));
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/base/GetDeptSync",
|
||||
method: "get",
|
||||
response: () => ok(null),
|
||||
},
|
||||
{
|
||||
url: "/api/base/GetSchModuleIsSms",
|
||||
method: "get",
|
||||
response: () => ok(true),
|
||||
},
|
||||
{
|
||||
url: "/api/base/GetSchoolAll",
|
||||
method: "get",
|
||||
response: () => ok(schoolTree),
|
||||
},
|
||||
|
||||
/* ---------- 附件 ---------- */
|
||||
{
|
||||
url: "/api/base/FileUpload",
|
||||
method: "post",
|
||||
response: () => {
|
||||
const id = nextFileId++;
|
||||
filesStore[id] = { id, filename: `mock附件${id}.png`, fileTrueName: `mock附件${id}.png`, size: "12KB" };
|
||||
return ok({ fileid: id, name: filesStore[id].filename, host: "", fileurl: fileUrl(id) });
|
||||
},
|
||||
},
|
||||
{
|
||||
// 富文本编辑器图片上传(wangeditor customUpload)
|
||||
url: "/api/base/FileUploadImage",
|
||||
method: "post",
|
||||
response: () => {
|
||||
const svg =
|
||||
"<svg xmlns='http://www.w3.org/2000/svg' width='240' height='120'><rect width='100%' height='100%' fill='#e8f1ff'/><text x='50%' y='50%' font-size='16' fill='#5c9edc' text-anchor='middle' dominant-baseline='middle'>Mock 图片</text></svg>";
|
||||
const url = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svg)));
|
||||
return ok([{ host: "", fileurl: url, name: "mock图片.png" }]);
|
||||
},
|
||||
},
|
||||
|
||||
/* ---------- 通知列表 ---------- */
|
||||
{
|
||||
url: "/api/notice/Notice_list/List",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const pageIndex = Number(query.PageIndex || 1);
|
||||
const pageSize = Number(query.PageSize || 10);
|
||||
let list = notices.filter((n) => n.DsfsTime === null || n.isDsfs === false || n.EditDate <= "2026-09-09");
|
||||
if (query.Name) list = list.filter((n) => n.title.includes(query.Name) || n.TeaName.includes(query.Name));
|
||||
if (query.Depttype) list = list.filter((n) => n.DeptID === query.Depttype);
|
||||
const me = "zhd";
|
||||
const mapped = list.map((n) => ({
|
||||
serid: n.serid,
|
||||
title: n.title,
|
||||
DeptID: n.DeptID,
|
||||
DeptName: n.DeptName,
|
||||
TeaName: n.TeaName,
|
||||
EditDate: n.EditDate,
|
||||
status: n.readUsers.some((u) => u.account === me) ? 2 : 1,
|
||||
UpFile: n.UpFile,
|
||||
}));
|
||||
const page = paginate(mapped, pageIndex, pageSize);
|
||||
const unreadCount = list.filter((n) => !n.readUsers.some((u) => u.account === me)).length;
|
||||
return ok({ ...page, unreadCount, pageIndex, pageSize });
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/SendList",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const pageIndex = Number(query.PageIndex || 1);
|
||||
const pageSize = Number(query.PageSize || 10);
|
||||
let list = [...notices].sort((a, b) => (a.createTime < b.createTime ? 1 : -1));
|
||||
if (query.Name) list = list.filter((n) => n.title.includes(query.Name) || n.TeaName.includes(query.Name));
|
||||
if (query.Depttype) list = list.filter((n) => n.DeptID === query.Depttype);
|
||||
if (query.type === "user") list = list.filter((n) => n.TeaAccount === "zhd" || n.TeaName === "刘文娟");
|
||||
if (query.starttime) list = list.filter((n) => n.createTime.slice(0, 10) >= query.starttime);
|
||||
if (query.endtime) list = list.filter((n) => n.createTime.slice(0, 10) <= query.endtime);
|
||||
const mapped = list.map((n) => ({
|
||||
serid: n.serid,
|
||||
title: n.title,
|
||||
DeptID: n.DeptID,
|
||||
DeptName: n.DeptName,
|
||||
TeaName: n.TeaName,
|
||||
EditDate: n.EditDate,
|
||||
readcount: n.readcount,
|
||||
allowcount: n.allowcount,
|
||||
UpFile: n.UpFile,
|
||||
}));
|
||||
return ok({ ...paginate(mapped, pageIndex, pageSize), pageIndex, pageSize });
|
||||
},
|
||||
},
|
||||
|
||||
/* ---------- 通知详情 ---------- */
|
||||
{
|
||||
url: "/api/notice/Notice_list/Modify",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const n = notices.find((x) => x.serid === Number(query.serid));
|
||||
if (!n) return { code: 4, msg: "通知不存在", data: null };
|
||||
if (String(query.type) !== "0" && !n.readUsers.some((u) => u.account === "zhd")) {
|
||||
n.readUsers.push({ account: "zhd", name: "朱皓东", read: true });
|
||||
n.readcount += 1;
|
||||
}
|
||||
return ok({
|
||||
title: n.title,
|
||||
Contents: n.Contents,
|
||||
DeptName: n.DeptName,
|
||||
DeptID: n.DeptID,
|
||||
TeaName: n.TeaName,
|
||||
EditDate: n.EditDate,
|
||||
numcount: n.allowcount,
|
||||
readnumcount: n.readcount,
|
||||
ReceiveList: n.ReceiveList,
|
||||
DsfsTime: n.DsfsTime,
|
||||
isDsfs: n.isDsfs,
|
||||
ChaoSend: (n.UpFile ? n.UpFile.split(",") : []).map((id) => {
|
||||
const f = filesStore[Number(id)];
|
||||
return f
|
||||
? { id: f.id, name: f.fileTrueName, size: f.size, fileid: f.id, filename: f.filename }
|
||||
: { id: Number(id), name: "附件", fileid: Number(id), filename: "附件" };
|
||||
}),
|
||||
tlist: /^all$/i.test(n.ReceiveList.trim()) ? "all" : resolveReceiveAccounts(n.ReceiveList),
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/GetNoticeDetails",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const n = notices.find((x) => x.serid === Number(query.serid));
|
||||
if (!n) return { code: 4, msg: "通知不存在", data: null };
|
||||
return ok({
|
||||
title: n.title,
|
||||
Contents: n.Contents,
|
||||
DeptID: n.DeptID,
|
||||
DeptName: n.DeptName,
|
||||
EditDate: n.EditDate,
|
||||
DsfsTime: n.DsfsTime,
|
||||
isDsfs: n.isDsfs,
|
||||
ChaoSend: (n.UpFile ? n.UpFile.split(",") : []).map((id) => {
|
||||
const f = filesStore[Number(id)];
|
||||
return { id: Number(id), name: f ? f.fileTrueName : "附件", size: f ? f.size : "", fileid: Number(id), filename: f ? f.filename : "附件" };
|
||||
}),
|
||||
tlist: /^all$/i.test(n.ReceiveList.trim()) ? "all" : resolveReceiveAccounts(n.ReceiveList),
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
// 阅读情况:按学校组分组(对齐真实后端 ReadDetail:组名+组内用户,绿已读/红未读)
|
||||
url: "/api/notice/ReadDetail",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const n = notices.find((x) => x.serid === Number(query.serid));
|
||||
if (!n) return { code: 4, msg: "通知不存在", data: null };
|
||||
const readAccounts = n.readUsers.map((u) => u.account);
|
||||
const receivers = resolveReceiveAccounts(n.ReceiveList);
|
||||
// 已读者不在接收明细中时补充,保证已读情况完整
|
||||
const accounts = [...receivers, ...readAccounts.filter((a: string) => !receivers.includes(a))];
|
||||
// 姓名 → 所在组(组织树反查),查不到归「其他」
|
||||
const nameGroup: Record<string, string> = {};
|
||||
schoolTree.forEach((dept) => dept.children.forEach((c: any) => (nameGroup[c.name] = dept.name)));
|
||||
const groupUsers: Record<string, any[]> = {};
|
||||
accounts.forEach((account: string) => {
|
||||
const teaname = teacherNames[account] || account;
|
||||
const groupName = nameGroup[teaname] || "其他";
|
||||
(groupUsers[groupName] = groupUsers[groupName] || []).push({
|
||||
account,
|
||||
teaname,
|
||||
states: readAccounts.includes(account) ? "read" : "unread",
|
||||
});
|
||||
});
|
||||
return ok(
|
||||
Object.keys(groupUsers).map((name) => ({ GroupName: name, teaslist: groupUsers[name] }))
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/GetNextPrevNotice",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const ids = notices.map((n) => n.serid);
|
||||
const i = ids.indexOf(Number(query.serid));
|
||||
return ok({
|
||||
prevId: i > 0 ? ids[i - 1] : 0,
|
||||
nextId: i > -1 && i < ids.length - 1 ? ids[i + 1] : 0,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/* ---------- 通知写入操作 ---------- */
|
||||
{
|
||||
url: "/api/notice/Notice_list/Create",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const sp = new URLSearchParams(body);
|
||||
const now = new Date();
|
||||
const pad = (n: number) => String(n).padStart(2, "0");
|
||||
const time = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
|
||||
const deptId = sp.get("DeptID") || "";
|
||||
const dept = deptDict.find((d) => d.CodeID === deptId);
|
||||
const receive = sp.get("ReceiveList") || "all";
|
||||
const isAll = /^all$/i.test(receive.trim());
|
||||
const receivers = isAll ? [] : receive.split(/[,,\s]+/).filter(Boolean);
|
||||
const serid = Math.max(...notices.map((n) => n.serid)) + 1;
|
||||
notices.unshift({
|
||||
serid,
|
||||
title: sp.get("title") || "未命名通知",
|
||||
DeptID: deptId,
|
||||
DeptName: dept ? dept.Name : "",
|
||||
TeaName: "朱皓东",
|
||||
TeaAccount: "zhd",
|
||||
EditDate: time,
|
||||
createTime: time,
|
||||
Contents: sp.get("Contents") || "",
|
||||
ReceiveList: isAll ? "ALL" : JSON.stringify(receivers),
|
||||
allowcount: isAll ? 33 : receivers.length,
|
||||
readcount: 0,
|
||||
UpFile: sp.get("ChaoSend") || null,
|
||||
isDsfs: !!sp.get("DsfsTime"),
|
||||
DsfsTime: sp.get("DsfsTime") || null,
|
||||
readUsers: [],
|
||||
});
|
||||
return ok(serid);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/EditNotice",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const sp = new URLSearchParams(body);
|
||||
const n = notices.find((x) => x.serid === Number(sp.get("serid")));
|
||||
if (!n) return { code: 4, msg: "通知不存在", data: null };
|
||||
const dept = deptDict.find((d) => d.CodeID === sp.get("DeptID"));
|
||||
n.title = sp.get("title") || n.title;
|
||||
n.Contents = sp.get("Contents") || "";
|
||||
n.DeptID = sp.get("DeptID") || n.DeptID;
|
||||
n.DeptName = dept ? dept.Name : n.DeptName;
|
||||
const receive = sp.get("ReceiveList") || "all";
|
||||
const isAll = /^all$/i.test(receive.trim());
|
||||
n.ReceiveList = isAll ? "ALL" : JSON.stringify(receive.split(/[,,\s]+/).filter(Boolean));
|
||||
n.UpFile = sp.get("ChaoSend") || null;
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/DeleteNotice",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const ids = (new URLSearchParams(body).get("ids") || "").split(",").map(Number);
|
||||
for (const id of ids) {
|
||||
const i = notices.findIndex((n) => n.serid === id);
|
||||
if (i > -1) notices.splice(i, 1);
|
||||
}
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/InitializeRed",
|
||||
method: "get",
|
||||
response: () => {
|
||||
notices.forEach((n) => {
|
||||
if (!n.readUsers.some((u) => u.account === "zhd")) {
|
||||
n.readUsers.push({ account: "zhd", name: "朱皓东", read: true });
|
||||
n.readcount += 1;
|
||||
}
|
||||
});
|
||||
return ok({ count: notices.length });
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/UserPull",
|
||||
method: "post",
|
||||
response: () => ok(null),
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/SetTopmost",
|
||||
method: "post",
|
||||
response: () => ok(null),
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/Expedite",
|
||||
method: "post",
|
||||
response: () => ok(null),
|
||||
},
|
||||
{
|
||||
url: "/api/notice/Notice_list/ReceiveUsers",
|
||||
method: "post",
|
||||
response: () => ok(null),
|
||||
},
|
||||
|
||||
/* ---------- 联系组(自定义组) ---------- */
|
||||
{
|
||||
url: "/api/contacts/GetGroup",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const pageIndex = Number(query.page || 1);
|
||||
const pageSize = Number(query.count || 10);
|
||||
const mapped = groups.map((g) => ({ serid: g.serid, GroupName: g.GroupName }));
|
||||
return ok({ ...paginate(mapped, pageIndex, pageSize) });
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/contacts/AddGroup",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const name = new URLSearchParams(body).get("name") || "未命名组";
|
||||
groups.push({ serid: groupSeq++, GroupName: name, members: [] });
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/contacts/EditGroup",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const sp = new URLSearchParams(body);
|
||||
const g = groups.find((x) => x.serid === Number(sp.get("id")));
|
||||
if (g) g.GroupName = sp.get("name") || g.GroupName;
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/contacts/DelGroup",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const ids = (new URLSearchParams(body).get("ids") || "").split(",").map(Number);
|
||||
for (const id of ids) {
|
||||
const i = groups.findIndex((g) => g.serid === id);
|
||||
if (i > -1) groups.splice(i, 1);
|
||||
}
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/contacts/GetContactsTea",
|
||||
method: "get",
|
||||
response: ({ query }: any) => {
|
||||
const g = groups.find((x) => x.serid === Number(query.gid));
|
||||
const members = g ? g.members : [];
|
||||
const mapped = members.map((id) => ({ account: "user" + id, userId: id, name: idNames[id] || String(id) }));
|
||||
// page/count 不传或为 0 时返回全量(与后端语义一致)
|
||||
const pageIndex = Number(query.page || 0);
|
||||
const pageSize = Number(query.count || 0);
|
||||
if (!pageIndex || !pageSize) return ok({ list: mapped, total: mapped.length });
|
||||
return ok({ ...paginate(mapped, pageIndex, pageSize) });
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/contacts/SetContactsTea",
|
||||
method: "post",
|
||||
response: ({ body }: any) => {
|
||||
const sp = new URLSearchParams(body);
|
||||
const g = groups.find((x) => x.serid === Number(sp.get("gid")));
|
||||
if (g) g.members = (sp.get("ids") || "").split(",").filter(Boolean);
|
||||
return ok(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "/api/contacts/GetGroupTree",
|
||||
method: "get",
|
||||
response: () =>
|
||||
ok(
|
||||
groups.map((g) => ({
|
||||
id: 1000 + g.serid,
|
||||
name: g.GroupName,
|
||||
isParent: true,
|
||||
children: g.members.map((id) => ({ id, name: idNames[id] || String(id), isParent: false })),
|
||||
}))
|
||||
),
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user