Compare commits

..

4 Commits

Author SHA1 Message Date
becomer 7ede964c4c fix: 未签到任务表单中地址和经纬度仍错误使用管理员配置数据
ci/woodpecker/tag/build Pipeline was successful
- ParseFormJson: 完全移除 signPlaceSelected 提取(始终是管理员范围数据)
- ParseFormJson: 将 longitude/latitude/position/signAddress 提取全部包进 if hasHistory
- QueryFormByTitle: 已签到(相同 instanceWid)时将自身 rows 设为 historyRows
- 确保无历史数据的未签到任务不会错误显示管理员范围名称(如"7")
2026-07-04 00:59:33 +08:00
becomer 4b50af3ae0 fix: woodpecker 只应在推送 tag 时触发,移除 push event 2026-07-04 00:51:27 +08:00
becomer 65293c4f81 fix: 编辑表单时签到地址错误显示为管理员范围名称的问题
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/tag/build Pipeline was successful
当任务没有历史已签到数据时,ParseFormJson 中 histRows 回退到 rows
(当前任务定义),此时 signPlaceSelected 包含的是管理员后台圈定范围的
数据(范围名称如"7"),而不是用户实际签到地址。

修复:
1. ParseFormJson: 只有有实际历史数据(historyRows 存在)时才从
   signPlaceSelected 提取地址/经纬度,否则跳过
2. QueryFormByTitle: 当前任务自身已签到时,不再将自身 rows 作为
   historyRows,让逻辑正常从历史月份查找其他已签到实例
2026-07-04 00:48:58 +08:00
becomer a41341e732 fix: 修复历史任务经纬度/地址获取到的是教师边界坐标而非用户历史提交数据的问题
ci/woodpecker/tag/build Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
- sign.go: 移除 signInstanceWid 比较限制,当已签到任务与当前任务是同一实例时,
  直接复用已有详情数据作为历史数据,确保 ParseFormJson 能从 signPlaceSelected 提取用户真实坐标
- sleepcheck.go: 移除 if !isFromSigned 守卫条件,无论当前任务是否已签到都尝试获取历史数据
2026-07-02 00:36:42 +08:00
3 changed files with 120 additions and 138 deletions
-2
View File
@@ -1,6 +1,4 @@
when:
- event: push
branch: [main, master]
- event: tag
branch: [v*]
+40 -45
View File
@@ -21,7 +21,6 @@ import (
"github.com/gogf/gf/v2/container/gvar"
"github.com/google/uuid"
"github.com/samber/oops"
"github.com/tidwall/gjson"
"github.com/tidwall/match"
"resty.dev/v3"
)
@@ -226,20 +225,26 @@ func (c *CpdailyAutoSignTask) QueryFormByTitle(ctx context.Context, titleGlob st
// 尝试从已签到的历史任务中获取历史数据用于预填充
signedMatch := findMatchTitle(signedTasks)
if signedMatch != nil && (signedMatch["signInstanceWid"] == nil || matchTask["signInstanceWid"] == nil || signedMatch["signInstanceWid"].String() != matchTask["signInstanceWid"].String()) {
histResp, histErr := c.client.R().
SetBody(map[string]*gvar.Var{
"taskName": gvar.New(signedMatch["taskName"].String()),
"signWid": signedMatch["signWid"],
"signInstanceWid": signedMatch["signInstanceWid"],
}).
WithContext(ctx).
Post(c.getReqUrl("detailSignInstance"))
if histErr == nil {
histJSON := utils.ReadJson[map[string]*gvar.Var](histResp.Body)
histDatas := histJSON["datas"].MapStrVar()
if len(histDatas) > 0 {
result["historyRows"] = gvar.New(histDatas)
if signedMatch != nil {
if matchTask != nil && signedMatch["signInstanceWid"] != nil && matchTask["signInstanceWid"] != nil &&
signedMatch["signInstanceWid"].String() == matchTask["signInstanceWid"].String() {
// 任务已签到(同一个 instanceWid),自身 rows 中的 longitude/latitude/position 就是用户自己提交的数据
result["historyRows"] = gvar.New(formDatas)
} else {
histResp, histErr := c.client.R().
SetBody(map[string]*gvar.Var{
"taskName": gvar.New(signedMatch["taskName"].String()),
"signWid": signedMatch["signWid"],
"signInstanceWid": signedMatch["signInstanceWid"],
}).
WithContext(ctx).
Post(c.getReqUrl("detailSignInstance"))
if histErr == nil {
histJSON := utils.ReadJson[map[string]*gvar.Var](histResp.Body)
histDatas := histJSON["datas"].MapStrVar()
if len(histDatas) > 0 {
result["historyRows"] = gvar.New(histDatas)
}
}
}
}
@@ -436,9 +441,11 @@ func (c *CpdailyAutoSignTask) ParseFormJson(ctx context.Context, rawJson map[str
// 优先从 historyRows(已签到的历史任务详情)中提取历史值,否则从 rows 中提取
histRows := rows
hasHistory := false
if hr := rawJson["historyRows"]; hr != nil {
if hrMap := hr.MapStrVar(); len(hrMap) > 0 {
histRows = hrMap
hasHistory = true
}
}
@@ -450,47 +457,35 @@ func (c *CpdailyAutoSignTask) ParseFormJson(ctx context.Context, rawJson map[str
histSignPhotoUrl := ""
histIsMalposition := ""
// 优先从 signPlaceSelected 提取经纬度和地址
if sps := histRows["signPlaceSelected"]; sps != nil && sps.String() != "" && sps.String() != "[]" {
placeArr := gjson.Parse(sps.String()).Array()
if len(placeArr) > 0 {
place := placeArr[0]
lng := place.Get("longitude").String()
lat := place.Get("latitude").String()
addr := place.Get("address").String()
if lng != "" && lat != "" {
histLatAndLon = lng + "," + lat
}
if addr != "" {
histAddress = addr
}
}
}
if histLatAndLon == "" {
// 只有有真实的已签到历史数据时,才从历史数据中提取地址和经纬度
// 否则 rows 中包含的是管理员圈定的范围配置数据,不是用户实际签到地址
// signPlaceSelected 始终是管理员圈定范围,不应使用
if hasHistory {
// 先从 longitude/latitude/position/signAddress 提取
if lon := histRows["longitude"]; lon != nil && lon.String() != "" {
if lat := histRows["latitude"]; lat != nil && lat.String() != "" {
histLatAndLon = lon.String() + "," + lat.String()
}
}
}
if histAddress == "" {
if pos := histRows["position"]; pos != nil && pos.String() != "" {
histAddress = pos.String()
if histAddress == "" {
if pos := histRows["position"]; pos != nil && pos.String() != "" {
histAddress = pos.String()
}
}
if histAddress == "" {
if addr := histRows["signAddress"]; addr != nil && addr.String() != "" {
histAddress = addr.String()
}
}
}
if photo := histRows["signPhotoUrl"]; photo != nil && photo.String() != "" {
histSignPhotoUrl = photo.String()
}
if mal := histRows["isMalposition"]; mal != nil {
if mal.Int() == 1 {
histIsMalposition = "是"
} else {
histIsMalposition = "否"
if photo := histRows["signPhotoUrl"]; photo != nil && photo.String() != "" {
histSignPhotoUrl = photo.String()
}
if mal := histRows["isMalposition"]; mal != nil {
if mal.Int() == 1 {
histIsMalposition = "是"
} else {
histIsMalposition = "否"
}
}
}
+80 -91
View File
@@ -221,7 +221,6 @@ func (c *CpdailySleepCheckTask) QueryFormByTitle(ctx context.Context, titleGlob
signedTasks := datas["signedTasks"].Array()
var matchTask map[string]*gvar.Var
isFromSigned := false
matchTask = findMatchTitle(unSignedTasks)
if matchTask == nil {
@@ -229,9 +228,6 @@ func (c *CpdailySleepCheckTask) QueryFormByTitle(ctx context.Context, titleGlob
if matchTask == nil {
matchTask = findMatchTitle(signedTasks)
if matchTask != nil {
isFromSigned = true
}
if matchTask == nil {
utils.OkOrPanic(errors.NewBusinessError(503, fmt.Sprintf("没有查询到查寝任务: %s", titleGlob)), func(err error) error {
@@ -281,11 +277,15 @@ func (c *CpdailySleepCheckTask) QueryFormByTitle(ctx context.Context, titleGlob
result["taskInfo"] = gvar.New(matchTask)
result["rows"] = gvar.New(datas)
// 如果当前任务不是已签到的,尝试从已签到的历史任务中获取历史数据用于预填充
if !isFromSigned {
// 先看今天有没有已签到的同名任务
signedMatch := findMatchTitle(signedTasks)
if signedMatch != nil {
// 尝试从已签到的历史任务中获取历史数据用于预填充
// 无论当前任务是否已签到,都尝试获取历史数据
signedMatch := findMatchTitle(signedTasks)
if signedMatch != nil {
if matchTask != nil && signedMatch["signInstanceWid"] != nil && matchTask["signInstanceWid"] != nil &&
signedMatch["signInstanceWid"].String() == matchTask["signInstanceWid"].String() {
// 任务已签到(同一个 instanceWid),自身 rows 中的 longitude/latitude/position 就是用户自己提交的数据
result["historyRows"] = gvar.New(datas)
} else {
histResp, histErr := c.client.R().
SetBody(map[string]*gvar.Var{
"taskName": gvar.New(signedMatch["taskName"].String()),
@@ -302,63 +302,63 @@ func (c *CpdailySleepCheckTask) QueryFormByTitle(ctx context.Context, titleGlob
}
}
}
// 今天没有已签到的同名任务,从历史月份中只查 signedTasks
if result["historyRows"] == nil {
func() {
defer func() { recover() }()
now := time.Now().In(cst.TimeZoneShangHai)
year := strconv.Itoa(now.Year())
month := strconv.Itoa(int(now.Month()))
if len(month) == 1 {
month = "0" + month
}
resp, e := c.client.R().
SetBody(map[string]any{
"statisticYearMonth": fmt.Sprintf("%s-%s", year, month),
}).
WithContext(ctx).
Post(c.getReqUrl("getStuSignInfosByWeekMonth"))
if e != nil {
return
}
respJSON := utils.ReadJson[map[string]*gvar.Var](resp.Body)
monthDatas := respJSON["datas"].MapStrVar()
monthRows := monthDatas["rows"].Vars()
}
// 今天没有已签到的同名任务,从历史月份中只查 signedTasks
if result["historyRows"] == nil {
func() {
defer func() { recover() }()
now := time.Now().In(cst.TimeZoneShangHai)
year := strconv.Itoa(now.Year())
month := strconv.Itoa(int(now.Month()))
if len(month) == 1 {
month = "0" + month
}
resp, e := c.client.R().
SetBody(map[string]any{
"statisticYearMonth": fmt.Sprintf("%s-%s", year, month),
}).
WithContext(ctx).
Post(c.getReqUrl("getStuSignInfosByWeekMonth"))
if e != nil {
return
}
respJSON := utils.ReadJson[map[string]*gvar.Var](resp.Body)
monthDatas := respJSON["datas"].MapStrVar()
monthRows := monthDatas["rows"].Vars()
// 只从 signedTasks 中查找匹配的已签到任务
for _, row := range monthRows {
rowMap := row.MapStrVar()
signed := rowMap["signedTasks"].Vars()
for _, st := range signed {
item := st.MapStrVar()
tn, exist := item["taskName"]
if !exist || tn.String() == "" {
// 只从 signedTasks 中查找匹配的已签到任务
for _, row := range monthRows {
rowMap := row.MapStrVar()
signed := rowMap["signedTasks"].Vars()
for _, st := range signed {
item := st.MapStrVar()
tn, exist := item["taskName"]
if !exist || tn.String() == "" {
continue
}
if match.Match(tn.String(), titleGlob) {
// 找到已签到的历史任务,获取详情
dr, de := c.client.R().
SetBody(map[string]*gvar.Var{
"signInstanceWid": item["signInstanceWid"],
"signWid": item["signWid"],
"taskName": gvar.New(tn.String()),
}).
WithContext(ctx).
Post(c.getReqUrl("detailSignInstance"))
if de != nil {
continue
}
if match.Match(tn.String(), titleGlob) {
// 找到已签到的历史任务,获取详情
dr, de := c.client.R().
SetBody(map[string]*gvar.Var{
"signInstanceWid": item["signInstanceWid"],
"signWid": item["signWid"],
"taskName": gvar.New(tn.String()),
}).
WithContext(ctx).
Post(c.getReqUrl("detailSignInstance"))
if de != nil {
continue
}
dj := utils.ReadJson[map[string]*gvar.Var](dr.Body)
dd := dj["datas"].MapStrVar()
if len(dd) > 0 {
result["historyRows"] = gvar.New(dd)
return
}
dj := utils.ReadJson[map[string]*gvar.Var](dr.Body)
dd := dj["datas"].MapStrVar()
if len(dd) > 0 {
result["historyRows"] = gvar.New(dd)
return
}
}
}
}()
}
}
}()
}
return result
@@ -518,9 +518,11 @@ func (c *CpdailySleepCheckTask) ParseFormJson(ctx context.Context, rawJson map[s
// 优先从 historyRows(已签到的历史任务详情)中提取历史值,否则从 rows 中提取
histRows := rows
hasHistory := false
if hr := rawJson["historyRows"]; hr != nil {
if hrMap := hr.MapStrVar(); len(hrMap) > 0 {
histRows = hrMap
hasHistory = true
}
}
@@ -533,48 +535,35 @@ func (c *CpdailySleepCheckTask) ParseFormJson(ctx context.Context, rawJson map[s
histSignPhotoUrl := ""
histIsMalposition := ""
// 优先从 signPlaceSelected 提取经纬度和地址
if sps := histRows["signPlaceSelected"]; sps != nil && sps.String() != "" && sps.String() != "[]" {
placeArr := gjson.Parse(sps.String()).Array()
if len(placeArr) > 0 {
place := placeArr[0]
lng := place.Get("longitude").String()
lat := place.Get("latitude").String()
addr := place.Get("address").String()
if lng != "" && lat != "" {
histLatAndLon = lng + "," + lat
}
if addr != "" {
histAddress = addr
}
}
}
// 降级:直接从 longitude/latitude/position 字段取
if histLatAndLon == "" {
// 只有有真实的已签到历史数据时,才从历史数据中提取地址和经纬度
// 否则 rows 中包含的是管理员圈定的范围配置数据,不是用户实际签到地址
// signPlaceSelected 始终是管理员圈定范围,不应使用
if hasHistory {
// 先从 longitude/latitude/position/signAddress 提取
if lon := histRows["longitude"]; lon != nil && lon.String() != "" {
if lat := histRows["latitude"]; lat != nil && lat.String() != "" {
histLatAndLon = lon.String() + "," + lat.String()
}
}
}
if histAddress == "" {
if pos := histRows["position"]; pos != nil && pos.String() != "" {
histAddress = pos.String()
if histAddress == "" {
if pos := histRows["position"]; pos != nil && pos.String() != "" {
histAddress = pos.String()
}
}
if histAddress == "" {
if addr := histRows["signAddress"]; addr != nil && addr.String() != "" {
histAddress = addr.String()
}
}
}
if photo := histRows["signPhotoUrl"]; photo != nil && photo.String() != "" {
histSignPhotoUrl = photo.String()
}
if mal := histRows["isMalposition"]; mal != nil {
if mal.Int() == 1 {
histIsMalposition = "是"
} else {
histIsMalposition = "否"
if photo := histRows["signPhotoUrl"]; photo != nil && photo.String() != "" {
histSignPhotoUrl = photo.String()
}
if mal := histRows["isMalposition"]; mal != nil {
if mal.Int() == 1 {
histIsMalposition = "是"
} else {
histIsMalposition = "否"
}
}
}