diff --git a/.backup/20260914-v13-approval-tab-count/src/main/java/com/yunhai/campusnotice/controller/api/NoticeController.java b/.backup/20260914-v13-approval-tab-count/src/main/java/com/yunhai/campusnotice/controller/api/NoticeController.java
new file mode 100644
index 0000000..3d6ff9c
--- /dev/null
+++ b/.backup/20260914-v13-approval-tab-count/src/main/java/com/yunhai/campusnotice/controller/api/NoticeController.java
@@ -0,0 +1,385 @@
+package com.yunhai.campusnotice.controller.api;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.yunhai.campusnotice.config.Config;
+import com.yunhai.campusnotice.common.validation.ValidationGroups;
+import com.yunhai.campusnotice.model.BasePageResult;
+import com.yunhai.campusnotice.model.notice.*;
+import com.yunhai.campusnotice.service.INoticeService;
+import com.yunhai.campusnotice.utils.OtherUtil;
+import com.yunhai.campusnotice.utils.PageUtils;
+import com.yunhai.platform.apistd.BizException;
+import com.yunhai.platform.utils.exception.ErrorCode;
+import com.yunhai.platform.utils.model.BoaUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.web.SortDefault;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.print.attribute.standard.MediaSize;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 通知公告接口(合并 NoticeApiController + 旧 NoticeController)。
+ *
路径前缀:{@code Config.API_PATH + "/notice/"}(platform = api / manage / mobiapi)。
+ * 方法动词式 PascalCase(对齐 UserBase);写操作一律 POST。
+ * 返回裸对象,由 ApiResponseAdvice 自动包装为 {code, msg, data}。
+ */
+@RestController
+@RequestMapping(value = Config.API_PATH + "/notice/")
+public class NoticeController {
+
+ @Autowired
+ private INoticeService noticeService;
+ // ============================ 收件箱列表 ============================
+
+ /**
+ * 已收通知列表(用户端)。
+ */
+ @GetMapping("List")
+ public NoticePageResult list(NoticeQuery query,
+ @SortDefault(sort = {"topmost", "createTime"},
+ direction = Sort.Direction.DESC) Sort sort) {
+ return noticeService.userList(query, PageUtils.toPageable(query, sort));
+ }
+
+ // ============================ 已发/全部通知列表 ============================
+
+ /**
+ * 已发/全部通知列表(管理端)。type=user 只看自己。
+ */
+ @GetMapping("SendList")
+ public BasePageResult sendList(NoticeQuery query,
+ @SortDefault(sort = "createTime",
+ direction = Sort.Direction.DESC) Sort sort) {
+ return noticeService.adminList(query, PageUtils.toPageable(query, sort));
+ }
+
+ // ============================ 查看详情(标读) ============================
+
+ /**
+ * 查看通知详情(type=1 普通查看标记已读, type=0 编辑模式不标记已读)。
+ */
+ @GetMapping("Detail")
+ public NoticeDetailVo detail(@RequestParam("serid") Integer serid,
+ @RequestParam(value = "type", defaultValue = "1") Integer type) {
+ return noticeService.detailMap(serid, type);
+ }
+
+ // ============================ 编辑回显(不标读) ============================
+
+ /**
+ * 获取通知详情(编辑/转发用,不标记已读)。
+ */
+ @GetMapping("GetDetail")
+ public NoticeDetailVo getDetail(@RequestParam("serid") Integer serid) {
+ return noticeService.getDetailMap(serid);
+ }
+
+ // ============================ 新建 ============================
+
+ /**
+ * 新建通知(JSON body)。fileIds 为附件ID逗号串,smsFlag 为短信标记。
+ */
+ @PostMapping("Create")
+ public Integer create(@RequestBody @Validated(ValidationGroups.Create.class) NoticeRequest request) {
+ return noticeService.publish(request);
+ }
+
+ // ============================ 编辑 ============================
+
+ /**
+ * 编辑通知(JSON body,含 id)。
+ */
+ @PostMapping("Edit")
+ public void edit(@RequestBody @Validated(ValidationGroups.Update.class) NoticeRequest request) {
+ noticeService.edit(request.getSourceId() != null ? request.getSourceId() : 0, request);
+ }
+
+ // ============================ 批量删除 ============================
+
+ /**
+ * 批量删除通知(ids 数组)。
+ */
+ @PostMapping("Delete")
+ public void delete(@RequestBody List ids) {
+ noticeService.deleteBatch(ids);
+ }
+
+ // ============================ 撤回 ============================
+
+ /**
+ * 撤回通知。
+ */
+ @PostMapping("UserPull")
+ public void userPull(@RequestParam("serid") Integer serid) {
+ noticeService.pull(serid);
+ }
+
+ // ============================ 置顶 ============================
+
+ /**
+ * 置顶/取消置顶。
+ */
+ @PostMapping("SetTopmost")
+ public void setTopmost(@RequestParam("serid") Integer serid,
+ @RequestParam(value = "topmost", defaultValue = "1") Integer topmost) {
+ noticeService.setTopmost(serid, topmost);
+ }
+
+ // ============================ 追加接收人 ============================
+
+ /**
+ * 追加接收人。
+ */
+ @PostMapping("ReceiveUsers")
+ public void receiveUsers(@RequestParam("serid") Integer serid,
+ @RequestParam("users") String users) {
+ noticeService.receiveUsers(serid, users);
+ }
+
+ // ============================ 催收 ============================
+
+ /**
+ * 催收未读。
+ */
+ @PostMapping("Expedite")
+ public void expedite(@RequestParam("serid") Integer serid) {
+ noticeService.expedite(serid);
+ }
+
+ // ============================ 一键已读 ============================
+
+ /**
+ * 一键全部已读(POST 化,原为 GET 写操作)。
+ */
+ @PostMapping("InitializeRed")
+ public InitializeRedVo initializeRed() {
+ return noticeService.initializeRedResult();
+ }
+
+ // ============================ 阅读情况 ============================
+
+ /**
+ * 阅读情况(按已读/未读分组)。
+ */
+ @GetMapping("ReadDetail")
+ public List