ef03130980
ci/woodpecker/tag/build Pipeline was successful
问题:上一版只在 GetLeaveTypes 加了 xsgz/xsfw 分支,其余请假入口仍走辅导猫 旧链路。用户点销假按钮(走 /leave/pending-list)时仍拿到辅导猫的 HTTP 420 「产品已到期」,提示误导且无法自助解决。 改动:新增 rejectExternalLeaveSystem 统一守卫,接入全部 7 个请假相关入口: - GetLeaveTypes / GetLeaveApplyApprovers / ExecuteLeaveApply(请假侧) - GetPendingLeaves / GetLeaveApprovers / ExecuteLeave(销假侧) - GetLeaveExtendPrefill(续假) 命中 xsgz/xsfw 时短路返回明确文案「XX大学 的请假由学校「学工系统」独立提供, 不支持在今日校园内提交,请前往学校学工系统办理」,不再让用户看到 420。 新增单测验证分流判定与文案(纯静态映射,不触发网络)。
103 lines
3.5 KiB
Go
103 lines
3.5 KiB
Go
package handler
|
||
|
||
import (
|
||
"log/slog"
|
||
"strings"
|
||
|
||
cpd "cpdaily-new/internal/service/cpdaily"
|
||
"cpdaily-new/internal/utils"
|
||
|
||
"github.com/gofiber/fiber/v2"
|
||
)
|
||
|
||
// 续假(仅新套 wec-counselor-leave-new-apps)。
|
||
// 续假复用请假提交接口 /stu/leave/apply(body 带 reApply/isExtend/leaveId/extendId);
|
||
// 执行逻辑并入 ExecuteLeaveApply(见 leaveNewExecuteApply 的续假分支),本文件仅提供「续假预填」查询。
|
||
|
||
// GetLeaveExtendPrefill 续假预填:返回原假单的类型、原结束时间(续假开始时间)、原因、是否离校等。
|
||
// 前端据此预填续假表单(开始时间锁定为原结束时间,用户只改新的结束时间)。
|
||
func GetLeaveExtendPrefill(c *fiber.Ctx) error {
|
||
user, err := loadLeaveUser(c)
|
||
if err != nil {
|
||
return utils.FailAuth(c, err.Error())
|
||
}
|
||
|
||
var req struct {
|
||
LeaveID string `json:"leaveId"`
|
||
}
|
||
if err := c.BodyParser(&req); err != nil {
|
||
return utils.FailParam(c, "请求参数错误")
|
||
}
|
||
req.LeaveID = strings.TrimSpace(req.LeaveID)
|
||
if req.LeaveID == "" {
|
||
return utils.FailParam(c, "缺少请假单 ID")
|
||
}
|
||
|
||
cookieMap := cpd.ParseCookieJSON(user.Cookie)
|
||
host := getSchoolHost(user.SchoolID)
|
||
|
||
// 学校独立学工系统:续假也不经辅导猫
|
||
if rejectExternalLeaveSystem(c, user, cookieMap) {
|
||
return nil
|
||
}
|
||
|
||
// 旧套:续假预填取自请假详情(类型 code + 原结束时间作为续假开始时间)
|
||
if schoolLeaveFlavor(user, cookieMap) != cpd.LeaveFlavorNew {
|
||
d, err := cpd.FetchLeaveDetail(cookieMap, host, req.LeaveID)
|
||
if err != nil && isCookieExpired(err) {
|
||
if refreshErr := refreshCpdailyCookie(user); refreshErr == nil {
|
||
cookieMap = cpd.ParseCookieJSON(user.Cookie)
|
||
d, err = cpd.FetchLeaveDetail(cookieMap, host, req.LeaveID)
|
||
} else {
|
||
err = wrapNeedReLogin(refreshErr)
|
||
}
|
||
}
|
||
if err != nil {
|
||
slog.Error("获取续假预填失败(旧套)", "userId", user.ID, "leaveId", req.LeaveID, "error", err)
|
||
if needReLoginSignal(err) {
|
||
return utils.Fail(c, 401, "登录凭证已过期,请重新登录")
|
||
}
|
||
return utils.Fail(c, 503, "获取续假信息失败: "+err.Error())
|
||
}
|
||
return utils.Success(c, fiber.Map{
|
||
"leaveId": req.LeaveID,
|
||
"typeWid": d.LeaveCodeNum,
|
||
"beginTime": d.EndTime, // 续假开始时间 = 原假单结束时间
|
||
"endTime": d.EndTime,
|
||
"leaveReason": "",
|
||
"isLeaveOut": "",
|
||
})
|
||
}
|
||
|
||
rd, err := cpd.FetchLeaveNewReplyDetail(cookieMap, host, req.LeaveID)
|
||
if err != nil && isCookieExpired(err) {
|
||
if refreshErr := refreshCpdailyCookie(user); refreshErr == nil {
|
||
cookieMap = cpd.ParseCookieJSON(user.Cookie)
|
||
rd, err = cpd.FetchLeaveNewReplyDetail(cookieMap, host, req.LeaveID)
|
||
} else {
|
||
err = wrapNeedReLogin(refreshErr)
|
||
}
|
||
}
|
||
if err != nil {
|
||
slog.Error("获取续假预填失败", "userId", user.ID, "leaveId", req.LeaveID, "error", err)
|
||
if needReLoginSignal(err) {
|
||
return utils.Fail(c, 401, "登录凭证已过期,请重新登录")
|
||
}
|
||
return utils.Fail(c, 503, "获取续假信息失败: "+err.Error())
|
||
}
|
||
|
||
// extendId 为空通常意味着该假单当前不可续假(已销假/已结束/未到可续假状态)
|
||
if strings.TrimSpace(rd.ExtendID) == "" && strings.TrimSpace(rd.BeginTime) == "" {
|
||
return utils.Fail(c, 400, "该请假单当前不可续假")
|
||
}
|
||
|
||
return utils.Success(c, fiber.Map{
|
||
"leaveId": rd.LeaveID,
|
||
"typeWid": rd.TypeWid,
|
||
"beginTime": rd.BeginTime, // 续假开始时间 = 原假单结束时间
|
||
"endTime": rd.EndTime,
|
||
"leaveReason": rd.LeaveReason,
|
||
"isLeaveOut": rd.IsLeaveOut,
|
||
})
|
||
}
|