build / build-push (push) Successful in 54s
原来助手表单只渲染"缺失的必填项",且控件只有文本/单选/时间 —— 与各模块 自己的发布页相比缺了接收对象多选、附件、定时发送、置顶、紧急程度、回执单据、 发布方式等字段,用户没法"填得一样"。 补齐一层共享的表单能力,再把三个发布工具按模块页逐字段重写: 共享能力 - 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 全绿
148 lines
9.8 KiB
Java
148 lines
9.8 KiB
Java
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;
|
||
}
|
||
}
|