Files
yunhai-agent-service/src/main/java/com/yunhai/agent/tool/defs/CampusNoticeTools.java
T
lijing 322d589b3e
build / build-push (push) Successful in 54s
feat(form): 发布表单字段与各模块「新建发布」页完全对齐
原来助手表单只渲染"缺失的必填项",且控件只有文本/单选/时间 —— 与各模块
自己的发布页相比缺了接收对象多选、附件、定时发送、置顶、紧急程度、回执单据、
发布方式等字段,用户没法"填得一样"。

补齐一层共享的表单能力,再把三个发布工具按模块页逐字段重写:

共享能力
- ToolParam: 新增 join(分隔符)/multiple/allOption(哨兵)/scopes(推送范围),
  array 类型有选项来源时自动用多选控件;数组 schema 补 items
- ToolDef: 新增 fullForm() —— 表单渲染全部字段(不再只渲染缺失必填)
- ToolExecutor: POST_JSON 前按 joinSeparator 把数组拼成模块要的逗号串;
  allToken 与具体项互斥(只选具体项→拼串,否则发哨兵)
- AgentOrchestrator: file 控件补 uploadPath(/<模块>/api/base/FileUpload)
- 模板/参数文件同步下发 joinSeparator/uploadPath/multiple/allToken/scopeType

三个发布工具
- notice.publish: 补重要程度/接收班级(pushScopes 对象数组)/置顶/短信/阅读回执/
  附件/定时发送/发布方式;新增 notice.stuTree(组织树)
- dorm.publish: 补紧急程度/生效时间/回执截止/回执单据/接收宿舍(多选,ALL)/
  宿管配合/置顶/短信/附件/定时发送/存草稿
- activity.publish: 补报名截止/回执方式三档/名额上限/家长随行/活动费用/
  接收班级(多选,ALL)/短信/附件/定时发送/存草稿
- leave.submit/register: 连续请假改为可填参数,补连续天数与佐证材料附件

测试:发布工具契约 + 表单字段与模块页一致性断言;90 tests 全绿
2026-10-12 22:05:09 +08:00

148 lines
9.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.yunhai.agent.tool.defs;
import com.yunhai.agent.tool.ToolDef;
import com.yunhai.agent.tool.ToolParam;
import java.util.ArrayList;
import java.util.List;
/**
* 校园公告(校园通知)模块工具 —— 后端 CampusAnnouncement / NoticeFront,前缀 /api/notice。
*/
public final class CampusNoticeTools {
public static final String MODULE = "campusnotice";
private CampusNoticeTools() {
}
public static List<ToolDef> defs() {
List<ToolDef> list = new ArrayList<>();
list.add(ToolDef.of("notice.received", MODULE, "我收到的公告",
"分页查询当前用户收到的校园公告。用户问“最近有什么通知”“有没有未读公告”时用它。",
"GET", "/api/notice/List")
.p(ToolParam.optional("pageIndex", "integer", "页码,从 1 开始").dft("1"),
ToolParam.optional("pageSize", "integer", "每页条数,默认 10").dft("10"),
ToolParam.optional("keyword", "string", "标题关键词"),
ToolParam.optional("type", "integer", "重要程度:1 普通 / 2 重要"),
ToolParam.optional("readType", "integer", "阅读状态:0 全部 / 1 未读 / 2 已读"))
.readAt("/")
.modId(null));
list.add(ToolDef.of("notice.readTabCount", MODULE, "公告未读统计",
"查询当前用户公告的已收总数 / 未读数 / 已读数(回答“我还有几条没看”)。",
"GET", "/api/notice/ReadTabCount")
.readAt("/"));
list.add(ToolDef.of("notice.sent", MODULE, "我发出的公告",
"分页查询我发布(或有权限查看)的公告,可按状态筛选(草稿/已发布/待审批/已驳回)。",
"GET", "/api/notice/SendList")
.p(ToolParam.optional("pageIndex", "integer", "页码").dft("1"),
ToolParam.optional("pageSize", "integer", "每页条数").dft("10"),
ToolParam.optional("scope", "string", "传 user 只查自己发布的"),
ToolParam.optional("status", "integer", "0 草稿 / 1 已发布 / 2 待审批 / 3 已驳回"),
ToolParam.optional("keyword", "string", "标题关键词"))
.readAt("/list")
.modId(null));
list.add(ToolDef.of("notice.detail", MODULE, "公告详情",
"查看一条公告的正文、附件与已读情况。",
"GET", "/api/notice/Detail")
.p(ToolParam.required("serid", "integer", "公告 id"),
ToolParam.optional("type", "integer", "1 查看并标记已读(默认) / 0 仅查看不标读").dft("1"))
.readAt("/"));
list.add(ToolDef.of("notice.deptDics", MODULE, "发文部门字典",
"查询本校本模块可选的发文部门(发布公告时填 deptId 用)。"
+ "仅在用户明确问「有哪些发文部门」时使用;"
+ "发布公告时**不要**先调它 —— 表单的「发文部门」下拉会自动带出可选值。",
"GET", "/api/dict/List")
.fix("type", "1")
.readAt("/list/new"));
list.add(ToolDef.of("notice.publish", MODULE, "发布校园公告",
"发布一条校园公告。字段与校园公告模块的「新建公告」页**完全一致**:"
+ "标题、重要程度、来源部门、接收班级、置顶、短信提醒、学员阅读回执、附件、正文、定时发送、发布方式。"
+ "调用前必须确认:标题 title、正文 content、发文部门 deptId;"
+ "缺失就直接调用本工具,系统会弹出**完整表单**让用户填写,不要用文字反复追问;"
+ "发文部门必须来自字典,不要编造。"
+ "接收班级 pushScopes 默认「全部班级」;要定向到具体班级时由表单多选。"
+ "发布方式 publishType:direct 直接发布(默认)/ draft 存为草稿。"
+ "timingSendTime 非空 = 定时发送。",
"POST_JSON", "/api/notice/Create")
.p(ToolParam.required("title", "string", "公告标题(200 字以内)")
.label("公告标题").eg("关于国庆假期安排的通知"),
ToolParam.required("content", "string", "公告正文(纯文本,对应模块页的富文本编辑器)")
.label("公告正文").as("textarea").eg("各位老师、同学:经学校研究决定……"),
ToolParam.optional("type", "integer", "重要程度:1 普通 / 2 重要")
.label("重要程度").dft("1")
.options(new String[]{"1", "2"}, new String[]{"普通", "重要"}),
ToolParam.required("deptId", "string", "发文部门 id,来自 notice.deptDics 的 k 字段")
.label("发文部门")
.optionsFrom("notice.deptDics").optionsKeys("k", "v"),
ToolParam.optional("pushScopes", "array", "接收班级:留空或含全部 = 全部班级;也可多选具体班级")
.label("接收班级")
.optionsFrom("notice.stuTree").optionsKeys("id", "name")
.scopes(4).allOption("ALL", "全部班级"),
ToolParam.optional("topmost", "integer", "是否置顶")
.label("置顶").dft("0")
.options(new String[]{"0", "1"}, new String[]{"否", "是"}),
ToolParam.optional("smsFlag", "integer", "是否同时发短信提醒")
.label("短信提醒").dft("0")
.options(new String[]{"0", "1"}, new String[]{"否", "是"}),
ToolParam.optional("receiptFlag", "integer", "是否需要学员阅读回执(要回执时收件人需点确认)")
.label("学员阅读回执").dft("0")
.options(new String[]{"0", "1"}, new String[]{"否", "是"}),
ToolParam.optional("fileIds", "array", "附件文件 id 列表(由表单的附件上传得到)")
.label("添加附件").as("file").multiple(true).join(","),
ToolParam.optional("timingSendTime", "string", "定时发送时间 yyyy-MM-dd HH:mm:ss(留空=立即发布)")
.label("定时发送").eg("2026-10-13 08:00:00"),
ToolParam.optional("publishType", "string", "发布方式:direct 直接发布 / draft 存为草稿")
.label("发布方式").dft("direct")
.options(new String[]{"direct", "draft"}, new String[]{"直接发布", "存为草稿"}))
.fullForm()
.write("/list/new")
.modId(null));
list.add(ToolDef.of("notice.stuTree", MODULE, "组织树(学员)",
"查询本校组织树(学部 / 年级 / 班级),用于发布公告时选择接收班级。"
+ "仅在用户明确要「按组织范围选人」时使用;"
+ "发布公告时**不要**先调它 —— 表单的「接收班级」多选会自动代取该树。",
"GET", "/api/base/getStuTree")
.fix("toUser", false)
.readAt("/list/new")
.modId(null));
list.add(ToolDef.of("notice.approvalList", MODULE, "待我审批的公告",
"查询待我审批的公告列表(公告审批中心)。",
"GET", "/api/notice/ApprovalList")
.readAt("/approval")
.p(ToolParam.optional("status", "string", "pending 待审批(默认) / approved 已通过 / rejected 已驳回 / all 全部").dft("pending"),
ToolParam.optional("pageIndex", "integer", "页码").dft("1"),
ToolParam.optional("pageSize", "integer", "每页条数").dft("10")));
list.add(ToolDef.of("notice.approve", MODULE, "通过公告审批",
"审批通过一条公告(末步通过即真实发布)。",
"POST_FORM", "/api/notice/Approve")
.p(ToolParam.required("serid", "integer", "公告 id")
.label("公告"),
ToolParam.optional("opinion", "string", "审批意见")
.label("审批意见").as("textarea").eg("内容符合要求,同意发布"))
.write("/approval")
.modId(null));
list.add(ToolDef.of("notice.reject", MODULE, "驳回公告审批",
"驳回一条公告审批(意见必填,会退回发布人)。",
"POST_FORM", "/api/notice/Reject")
.p(ToolParam.required("serid", "integer", "公告 id")
.label("公告"),
ToolParam.required("remark", "string", "驳回意见")
.label("驳回意见").as("textarea").eg("标题表述不清,请修改后重新提交"))
.write("/approval")
.modId(null));
return list;
}
}