275 Commits

Author SHA1 Message Date
becomer 4b1dea3d3c 待适配学校支持拒绝操作:拒绝必填理由并邮件通知联系邮箱
ci/woodpecker/tag/build Pipeline was successful
- 新增管理端接口 POST /admin/pending-schools/:id/reject,拒绝理由必填(≤500字)
- 拒绝时该校全部待处理记录标记为 rejected 并保存理由
- 新增 NotifySchoolRejected 邮件模板,拒绝理由 HTML 转义后发送至该校全部联系邮箱
- 列表接口返回 rejectReason 并支持 status=rejected 筛选
- 管理页新增拒绝按钮(组级+行级)、拒绝理由弹窗、已拒绝状态标签与理由展示、已拒绝筛选
v1.2.15
2026-09-09 22:31:06 +08:00
becomer 0d665ad0fe 重构任务详情获取:执行时严格按任务名从当天列表实时匹配,移除全部兜底回退
ci/woodpecker/tag/build Pipeline was successful
- 执行链路新增 FetchTodayTaskDetail:仅用当天任务列表按任务名匹配未签实例,
  wid 每次执行时实时获取;匹配失败直接报明确错误(未找到/今日已签),不再退回配置 wid
- 预览/历史预填充改用 GetTaskDetailByWid 纯 wid 查询,无隐式回退
- 删除 findLatestTaskInstance 与 fetchTaskDetail 的 allowFallback 递归回退逻辑
- RealTitle 直接取列表真实任务名,去掉二次匹配
v1.2.14
2026-09-08 23:12:29 +08:00
becomer 67d925bb91 refactor: 任务实例 wid 改为执行时实时获取,配置快照仅作兜底
ci/woodpecker/tag/build Pipeline was successful
- 任务执行入口优先按任务名从当天列表实时匹配未签到的实例,
  循环任务跨天不再依赖配置时保存的 signWid/signInstanceWid 快照
- 月度列表中的历史漏签实例不再被误当作可提交目标
  (历史实例提交会被今日校园判定"已结束")
- 当天列表无可用实例(无同名任务/接口异常)时退回配置 wid 兜底,
  详情为空再按任务名匹配近期已签实例还原表单结构
v1.2.13
2026-09-08 22:59:29 +08:00
becomer bf0e1656ab fix: 循环签到/查寝任务自动切换到当日任务实例,修复"查寝已结束"
ci/woodpecker/tag/build Pipeline was successful
循环任务(如每日晚归寝打卡)每天生成新的 signInstanceWid,历史实例的
详情接口仍可返回数据,导致原有的"详情为空才回退"逻辑不触发,提交到
过期实例被今日校园判定为"查寝已结束"。

现在获取任务详情时,若当日列表中同名任务存在未签到的实例且与详情返回
的实例不一致,自动切换到当日实例后再填充表单提交。
v1.2.12
2026-09-08 22:51:03 +08:00
becomer 66d07781be fix: 执行日志弹窗细节优化
ci/woodpecker/tag/build Pipeline was successful
- 时间列只显示 HH:MM:SS(日期由弹窗筛选决定)
- 状态徽标禁止换行
- 说明列显示完整错误信息,不再截断
v1.2.11
2026-09-08 22:41:17 +08:00
becomer 99c16652a7 feat: 后台用户管理新增 VIP 列
ci/woodpecker/tag/build Pipeline was successful
- 列表接口返回 vipStatus(active/expired/none)与 vipExpireAt
- 表格新增 VIP 列:有效显示金色徽标+到期日期,过期显示已过期,未开通显示非VIP
v1.2.10
2026-09-08 22:31:42 +08:00
becomer cc4aa1c00e feat: 后台当天执行总次数可点击查看执行日志明细
ci/woodpecker/tag/build Pipeline was successful
- 后端新增 GET /admin/task-logs 接口:按日期(默认当天)、成功/失败状态、
  关键字(用户名/姓名/任务标题)筛选,联表 sys_user 返回用户与学校信息,分页返回
- 前端用户管理页「当天执行总次数」卡片改为可点击,弹出日志明细弹窗
- 弹窗支持日期切换(可查历史日期)、状态筛选、关键字搜索与分页浏览
v1.2.9
2026-09-08 22:12:41 +08:00
becomer 15eceea38a docs: 随机设备码适用人群提示改为帮打卡导致频繁切换设备的用户
ci/woodpecker/tag/build Pipeline was successful
v1.2.8
2026-09-08 20:21:54 +08:00
becomer a9dbc2661d feat: 设备码绑定改为非强制 + 随机绑定入口
ci/woodpecker/tag/build Pipeline was successful
- 登录后不再强制跳转设备绑定页(MobileLayout 移除拦截)
- 新建签到任务时检测未绑定设备码,弹窗提示「请先在个人中心绑定设备码」并支持跳转
- 个人中心设备码栏新增「随机」按钮:随机生成 UUID 设备码直接绑定,
  前端连续两次风险确认(随机后现有手机会提示频繁切换设备无法签到)
- 后端新增 POST /device/random-bind(登录态,随机 UUID v4 绑定,mobile_type=manual)
- 新手引导在「新建每日签到任务」前新增「先绑定设备码」步骤
v1.2.7
2026-09-08 20:15:24 +08:00
becomer ebc94ec9a0 fix: 复制按钮与 toast 层级修复
ci/woodpecker/tag/build Pipeline was successful
- copyToClipboard 调整为先同步 execCommand(用户手势内最可靠),
  Clipboard API 仅作异步兜底;修复移动端先 await Clipboard API 被拒后
  手势丢失导致 execCommand 静默失败的问题(单行复制不生效)
- 单行复制成功也弹「已复制」toast,失败提示明确,不再无反馈
- toast 容器 z-50 提至 z-[100],不再被弹窗遮罩盖住
v1.2.6
2026-09-08 18:27:23 +08:00
becomer 98cf8666f6 feat: 新手引导 VIP 步骤移到最后;CDK 列表展示类型与额度
ci/woodpecker/tag/build Pipeline was successful
- 引导顺序调整为:领取次数 → 新建任务 → 执行任务 → 邀请好友 → VIP 会员
- CDK 列表「次数」列拆为「类型」(次数卡/VIP周卡/VIP月卡徽标)+「额度」(N 次 / N 天)
- CDKCode 类型补充 type/vipDays 字段(后端已输出)
v1.2.5
2026-09-08 17:51:34 +08:00
becomer ff3593f057 fix: VIP 展示与复制按钮等 7 项体验修复
ci/woodpecker/tag/build Pipeline was successful
- VIP 徽标:修复 position 覆盖导致徽标挤变形头像,加 z-10 浮于头像上层
- VIP 用户「可签到次数」显示无限次
- VIP 兑换弹窗标题统一「续费 VIP」,去掉提示文案;按钮统一「续费 VIP」
- 新增 utils/clipboard:兼容 HTTP/移动端的复制(Clipboard API + execCommand 回退),
  修复待适配学校密码复制、CDK 结果列表单个复制按钮不生效
- 新手引导新增一步:VIP 会员与普通签到次数的区别
v1.2.4
2026-09-08 13:25:13 +08:00
becomer 74422b1848 fix: VIP 卡默认价改为周卡 30 元 / 月卡 100 元(对齐单次扣费 6 元的定价逻辑)
ci/woodpecker/tag/build Pipeline was successful
v1.2.3
2026-09-08 12:40:20 +08:00
becomer 84f87cd168 feat: VIP CDK 改为周卡/月卡两档(7天/30天),价格分开配置
ci/woodpecker/tag/build Pipeline was successful
- 后端:vip_price_week(周卡,默认5元)/ vip_price_month(月卡,默认15元),
  VIP CDK 仅支持 7/30 天,vip-info 返回双价格
- 后台:生成弹窗改为周卡/月卡选择,设置页拆分周卡/月卡售价两项
- 前台:开通按钮展示 周¥x · 月¥y 双价格
v1.2.2
2026-09-08 12:29:59 +08:00
becomer 386e9269bf fix: VIP 价格设置前端兜底值与后端默认一致(15 元)
ci/woodpecker/tag/build Pipeline was successful
v1.2.1
2026-09-08 12:23:31 +08:00
becomer 17a71b1e2a feat: 新增 VIP 功能(CDK 兑换开通、徽标展示、免扣次数、后台管理)
ci/woodpecker/tag/build Pipeline was successful
- 数据库:sys_user.vip_expire_at、cdk_codes type/vip_days、系统设置 vip_price
- 后端:CDK 生成支持 count/vip 类型(VIP 默认 30 天),兑换延长 VIP 到期时间,/cdk/vip-info 查询售价
- 任务执行:VIP 有效期内的用户跳过次数扣减
- 前台:个人中心 VIP 徽标(反光动画)+ 到期时间 + CDK 兑换弹窗
- 后台:CDK 生成弹窗类型选择 + 系统设置 VIP 月卡售价项
v1.2.0
2026-09-08 12:19:23 +08:00
becomer 1b4f029602 feat: 后台用户列表增加学校列;待适配学校表格小屏横向滚动
ci/woodpecker/tag/build Pipeline was successful
用户列表在真实姓名后新增学校列(数据接口本已返回 schoolName),
各列宽度相应调整;待适配学校账号表格外层增加 overflow-x-auto
并设置最小宽度,修复手机端表格溢出被裁剪无法查看完整信息的问题。
v1.1.47
2026-09-08 07:40:59 +08:00
becomer 2246752724 fix: 引导页手指改指右上角菜单,浏览器打开后自动跳回原页面
ci/woodpecker/tag/build Pipeline was successful
1. 手指图标按业界通用引导样式移至右上角,指向模拟的 ···
   菜单按钮并带点动动画
2. 修复微信右上角"在浏览器打开"仍停留在引导页的问题:
   - 引导页在正常浏览器 UA 下由守卫自动 replace 回 redirect 原地址
   - 放行纯 QQ 浏览器 App(MQQBrowser),避免安卓微信唤起 QQ
     浏览器后再次被拦造成死循环;仍拦微信与手机QQ内置浏览器
v1.1.46
2026-09-07 22:16:38 +08:00
becomer a303782ab4 feat: 微信/QQ 内置浏览器访问时跳转浏览器打开引导页
ci/woodpecker/tag/build Pipeline was successful
检测 MicroMessenger/QQ/MQQBrowser UA 时路由守卫优先拦截,
跳转 /open-in-browser 引导页(手指动画指向"用浏览器打开"
按钮),点击复制原地址含全部 query;系统浏览器打开后自动
回到原页面。
v1.1.45
2026-09-07 22:07:02 +08:00
becomer 2cac0cdfee fix: 查寝历史位置超出签到范围时自动改用最近签到点提交
ci/woodpecker/tag/build Pipeline was successful
学校老师频繁调整查寝组签到点(小半径500~1000m),历史记录位置
卡在边缘(如距边角修正1仅540m),配置一变即触发"位置不在签到
范围内"。提交前校验历史位置与 signPlaceSelected 各点距离,全部
出界时自动改用最近签到点坐标,位置在范围内则继续沿用历史记录。
v1.1.44
2026-09-07 21:51:18 +08:00
becomer 75d334680b feat: 用户新建工单时邮件提醒管理员
ci/woodpecker/tag/build Pipeline was successful
复用待适配学校通知模式: GetAdminEmails + SendMailAsync, 邮件含标题/
用户/学校/内容摘要(HTML转义防注入, 500字截断), 仅新建工单触发。
v1.1.43
2026-09-06 18:37:53 +08:00
becomer 35fa5a6560 feat: 后台用户管理展示邀请人
ci/woodpecker/tag/build Pipeline was successful
- sys_user 新增 inviter_id 字段, 注册时记录邀请关系
- ListUsers/GetUserDetail 返回 inviterId/inviterName(姓名优先)
- 前端用户列表加邀请人列, 详情弹窗加邀请人卡片
- 历史数据通过系统公告(邀请奖励到账/新人注册奖励 同刻配对)回填
v1.1.42
2026-09-05 22:06:52 +08:00
becomer dbd3c88d32 fix: 修复芜湖职业技术大学等CAS学校登录入口错选问题
ci/woodpecker/tag/build Pipeline was successful
getCasValidLoginUrl 原来按 AmpUrl/AmpUrl2 顺序取第一个可用URL, 部分学校
AmpUrl 是自研门户(ehall), 登录后cookie落在门户域, 与后续签到/查寝任务
接口所在campusphere网关域不匹配, 导致姓名同步失败且任务拉取返回302页面。
芜湖与安徽师范结构同构(网关+AmpUrl2), 修改为先取campusphere/wec网关入口。
v1.1.41
2026-09-04 21:33:05 +08:00
becomer 33e29573ca fix: 验证码限流改令牌桶(同IP 5分钟最多10次), 前端显示限流提示不再静默失败
ci/woodpecker/tag/build Pipeline was successful
原 SetNX 固定 10 秒/次:共享出口 IP 下易互相挤占且失败时前端静默,
表现为"验证码不显示且无提示"。改为 Redis Lua 原子令牌桶(容量10、速率
每30s回补1个),429 返回动态等待文案;登录主验证码、失败工单弹窗、
兑换弹窗三处加载失败均展示错误提示并支持点击重试。
v1.1.40
2026-09-04 18:46:02 +08:00
becomer 4a80382b60 fix: 全局时间统一北京时间(Asia/Shanghai), 修复记录与展示偏移8小时
ci/woodpecker/tag/build Pipeline was successful
根因: 运行容器默认 UTC 且后端未设时区, time.Now()/gorm 时间戳/DSN
loc=Local/手动 Format 全部按 UTC, 导致展示为"美国时间"、月度与每日
边界错位。修复:
- main.go 在 database.Init 前固定 time.Local=Asia/Shanghai
  (DSN loc=Local 随之一致, 一处生效覆盖全部业务点)
- pending_school.go 今日判断改北京时间当日0点(原 Truncate 按UTC午夜偏移8h)
- Dockerfile/build.yml/compose 加 TZ=Asia/Shanghai 双保险
配套: 存量 datetime 列已 +8h 迁移(备份 /root/cpdaily-backup-pre-tz-*.sql)
v1.1.39
2026-09-03 21:06:59 +08:00
becomer 8eaaf5781a fix: 引导强播标记改为一次性消费, 杜绝看完引导后刷新又弹且不上报
ci/woodpecker/tag/build Pipeline was successful
?guide=1 强播标记此前写入 sessionStorage 后在整页加载时只置位不清除,
同一标签页后续普通刷新被残留标记误判为强播: 关闭引导不写库、刷新又弹。
现 MobileLayout 读取标记后立即消费(removeItem), 仅当次加载内强播生效,
刷新后回到数据库判定(未看过 v2 才弹, 关闭即上报写库)。
v1.1.38
2026-09-03 16:51:13 +08:00
becomer 111cc0439c fix: 引导气泡 bottom 模式定位失效致遮住高亮按钮(r.bottom 为 NaN)
ci/woodpecker/tag/build Pipeline was successful
holeRect 数据模型只有 top/left/width/height,bubbleStyle 的 bottom
分支却直接读 r.bottom(undefined+12=NaNpx),被浏览器丢弃后气泡
永远停留在 center 兜底的 top:96px 压住目标按钮;改为 r.top+r.height
合成底部坐标(v1.1.36 引入 bottom 优先后暴露此问题)
v1.1.37
2026-09-03 16:32:33 +08:00
becomer a97537660e fix: 引导气泡方位改为下方优先 + 统一决策/越界自愈, 杜绝顶部溢出遮住目标
ci/woodpecker/tag/build Pipeline was successful
- 方位决策抽为 choosePos:下方可完整容纳优先(移动端向下展开、
  贴合"上方高度不足应放下方"的预期);下方不足再上方;两侧都不足时
  比较视口裁切量选溢出更少一侧(原兜底在两侧都不足时可能选顶部导致
  气泡被顶出屏幕遮住高亮目标)
- locate 找到目标后先立即测量一次再滚动定位:消除切步/跨页等待滚动
  期间气泡停留在顶部兜底样式(top:96px)压住目标按钮的窗口
- 自愈增强:top 模式顶部被裁切、bottom 模式底部被裁切、center 兜底
  样式与目标相交时,按真实气泡尺寸重走同一 choosePos 决策(与 measure
  同源,不会两侧乒乓);center 相交则直接重新定位
v1.1.36
2026-09-03 16:21:07 +08:00
becomer 664d8a2594 feat: 新手引导改为数据库记录判定, 跨设备一致(用户选项: 存量未看过 v2 也会弹一次)
ci/woodpecker/tag/build Pipeline was successful
- SysUser 新增 guide_version 字段(GORM 自动迁移加列, 存量默认空)
- GET /auth/userinfo 返回 guideVersion; 新增 POST /auth/guide/complete
  记录用户已看完当前版本引导(v2)
- 前端移除 localStorage 完成标记: 登录后按 userInfo.guideVersion
  判定是否展示引导, 关闭/完成引导后上报写库 → 换设备不再重复打扰
- ?guide=1 测试强播入口保留, 且强播来源关闭引导时不上报数据库,
  便于 QA 反复重测而不污染账号引导状态
v1.1.35
2026-09-03 16:17:42 +08:00
becomer 6ede88b01b feat: 引导支持 ?guide=1 强制重播(测试入口), 气泡按钮改主题纯色
ci/woodpecker/tag/build Pipeline was successful
- 新手引导完成标记存于浏览器 localStorage(设备维度,与账号无关),
  服务器无法按学号远程清除;新增 URL ?guide=1 一次性强制重播入口:
  main.ts 消费参数存入会话标记(登录跳转丢失 query 也不影响),
  MobileLayout 每次进入时命中即重播,关闭引导后恢复常规逻辑
- 引导气泡主按钮去掉蓝紫渐变,改为与站内主按钮一致的纯主题蓝
v1.1.34
2026-09-03 16:12:52 +08:00
becomer 6b42cff492 fix: 引导切步无重绘闪烁, 滚动稳定后再测位, 第三步空任务展示示例卡引导
ci/woodpecker/tag/build Pipeline was successful
- 气泡切步不再以 :key 重建(去掉重放入场动画与"遮罩重新生成"观感);
  同 tab 切步保留旧高亮作为过渡锚点,测到新目标后平滑滑移而非闪黑
- locate 改为等待平滑滚动静默 120ms/最长 800ms 后测量,杜绝滚动中途
  错位导致气泡方位误判(跑到页面顶部/遮住目标按钮)
- 气泡方位判定高度保守化 need=max(240, bH+24),保证整颗气泡落在
  目标一侧且始终保留间隙
- 第三步无真实任务时全屏压暗并展示仿真实样式的示例任务卡(含执行
  按钮),引导新用户理解任务执行流程;第二步文案按要求更新
- 轮询新增目标升级/失联自动重定位:邀请码异步返回导致 生成→复制、
  行→兑换按钮 v-if 切换时高亮自动跟随
v1.1.33
2026-09-03 16:08:40 +08:00
becomer cc1150c1ac fix: 引导高亮实时校正定位, 气泡绕开高亮目标
ci/woodpecker/tag/build Pipeline was successful
- 引导展示期间 300ms 轮询重测 + body/目标/气泡 ResizeObserver, 修正异步数据/图片加载导致布局变化后的高亮错位
- 气泡方位按真实气泡高度选择, 内容文案变化后自动重排; top/bottom 定位始终与目标保留间隙
- 渲染后自检气泡与真实目标相交则翻侧绕开(400ms 防抖), 杜绝气泡遮住高亮按钮
- 气泡位置变化加 CSS 过渡平滑跟随
v1.1.32
2026-09-03 15:54:47 +08:00
becomer 032c8e526f fix: 部署脚本移除 cp backed/config.toml(配置已出库, 由宿主机运维维护, 修复 v1.1.30 部署中止)
ci/woodpecker/tag/build Pipeline was successful
v1.1.31
2026-09-03 15:45:57 +08:00
becomer d442f538e1 feat: 新手引导升级为 spotlight 真实页面高亮引导, 邀请奖励积分动态读取系统配置
ci/woodpecker/tag/build Pipeline failed
- 引导改为遮罩挖洞高亮真实 DOM 元素 + 气泡 tooltip, 四步跨首页/个人中心, 全屏拦截点击由气泡推进
- GUIDE_DONE_KEY 升级为 xz_guide_v2_done, 所有存量用户重走一遍引导
- 引导完成前不查询公告强制弹窗, 关闭引导后统一补齐
- HomeView/ProfileView 目标元素增加 data-guide 标记, 支持懒加载轮询等待与无任务降级分支
- 后端 GetMyInviteInfo/GenerateMyInviteCode 返回 inviterRewardPerInvite/inviteeRewardPerInvite
- ProfileView 与引导气泡邀请奖励文案动态化, 接口失败降级泛指文案
v1.1.30
2026-09-03 15:43:32 +08:00
becomer 20921c6317 chore: 生产配置移出版本库, 提供脱敏模板
backed/config.toml 内含生产数据库/Redis/JWT/captcha 凭证,随仓库分发
将导致凭证泄露(已实测凭仓库内 JWT 密钥可离线伪造超管 token)。
本地文件保留(git rm --cached 不删磁盘),新增 config.toml.example
脱敏模板说明部署方式;生产配置在服务器 /opt 下由容器挂载,不受影响。
2026-09-03 15:32:11 +08:00
becomer 097aed6f40 fix: 收紧管理端越权, 全量CDK/代理列表/公告管理/系统设置仅超管
ci/woodpecker/tag/build Pipeline was successful
实测发现任意代理 token 可访问 /admin/all-cdks、/admin/all-agents、
/agent/list 查看全站数据,并可创建全站强制弹窗公告、篡改系统计费与
SMTP 配置。为这些接口补充 AdminOnly 中间件;公告收取仍走
/my-announcements,代理自管理功能(自有CDK/下级代理)不受影响。
v1.1.29
2026-09-03 15:28:43 +08:00
becomer a75d57f309 feat: CDK分页/禁用恢复/生成结果复制 + 引导v2四步并延迟公告查询
ci/woodpecker/tag/build Pipeline was successful
- CDK列表服务端分页(状态筛选/关键字/汇总统计),修复admin全量列表Preload缺失关联问题
- CDK禁用/恢复接口(代理限自己、admin全部),用户管理补充每页条数选择
- 生成CDK后弹窗展示全部CDK并支持复制全部/单个
- 新手引导新增第4步(邀请好友赚积分),引导升级v2机制:所有现有用户重新走一次
- 公告强制弹窗延迟到引导完成后查询,避免弹窗冲突;移除路由调试请求
v1.1.28
2026-09-03 15:18:49 +08:00
becomer fc3bfe09f4 feat: 验证码走Redis防刷 + 新用户首次登录三步引导
ci/woodpecker/tag/build Pipeline was successful
- 验证码存储迁移 Redis(TTL 5 分钟自动过期,不再内存无限增长),
  Redis 不可用时兜底内存存储,不影响登录可用性
- 验证码生成接口按客户端 IP 限频(10 秒/次,SetNX),移除每次
  打印验证码的调试日志,防止日志刷屏
- 登录响应新增 firstLogin 标记,新注册用户首次进入自动展示全屏
  三步新手引导:个人中心积分兑换次数→首页新建签到任务→执行任务
v1.1.27
2026-09-03 15:11:10 +08:00
becomer b49ef238dd feat: 修复IAP登录错误识别/邮件通知/IP过滤
ci/woodpecker/tag/build Pipeline was successful
- IAP doLogin resultCode 兼容字符串枚举:FAIL_UPNOTMATCH→"用户名或密码不匹配"、
  CAPTCHA_NOTMATCH→"验证码错误",未知结果码记录响应日志便于诊断
- 学校无可用登录地址时返回友好提示(替代 "Get \"\"" 技术性报错)
- 待适配学校 IP 提取真实公网地址(过滤 X-Forwarded-For 链中 127.0.0.1/内网)
- 新增邮件服务:后台可配置 SMTP 与管理员邮箱;新待适配提交异步提醒管理员、
  适配完成异步通知学校全部联系邮箱;支持测试邮件发送
v1.1.26
2026-09-03 13:09:42 +08:00
becomer 9212273e04 feat: 删除任务增加 loading 反馈并删除后自动刷新任务/日志列表
ci/woodpecker/tag/build Pipeline was successful
- 新增 deletingId 状态:删除中按钮图标转圈、按钮禁用防止重复点击
- 删除成功后再拉取最新任务列表与日志列表
v1.1.25
2026-09-02 20:36:14 +08:00
becomer 0af640881e fix: 修复任务删除接口路径不匹配导致删除失败
ci/woodpecker/tag/build Pipeline was successful
- deleteTask 请求路径 /task/${id} 与后端路由 /task/delete/:id 不一致,
  删除请求 404 静默失败;改为 /task/delete/${id}
- removeTask 增加成功/失败提示,避免静默失败
v1.1.24
2026-09-02 20:33:11 +08:00
becomer 7c3e2be828 fix: 任务实例过期后详情为空——自动匹配最新实例,恢复图片字段与签到
ci/woodpecker/tag/build Pipeline was successful
问题:晚查寝等循环任务保存的 signInstanceWid 过期后,detailSignInstance
返回空数据,导致:1) 表单编辑页丢失必填的"签到照片"字段(isPhoto判定失效);
2) 执行签到报"请求参数SignInstanceWid为空"。

修复:
- FetchTaskDetail 详情为空时自动按同名任务匹配最新可用实例重试
  (当天未签实例优先,其次历史已签实例)
- ParseTaskForm 图片字段判定增加历史记录 isPhoto 兜底
v1.1.23
2026-09-02 20:25:43 +08:00
becomer aa0ecfc4f1 feat: 后台用户管理改版——新列与当天统计
ci/woodpecker/tag/build Pipeline was successful
- 列表列调整:学工号/真实姓名/设备码(脱敏缩略+一键复制完整值)/
  可执行/已执行(累计成功执行次数)/积分/邀请数/今天执行状态/创建时间
- 顶部统计卡片:当天执行总次数、成功执行总次数、当天新增用户数、当天登录用户数
- ListUsers 接口新增 executedCount、todayStatus 与 todayStats 统计
v1.1.22
2026-09-01 22:30:50 +08:00
becomer 0b019ab4b9 fix: 任务名查重 + 验证码空识别结果直接重试,避免提交空验证码
ci/woodpecker/tag/build Pipeline was successful
- CreateTask 禁止同一用户创建相同 title 的任务
- submitCaptcha:AI 识别结果为空或场景码为空时直接报错重试,
  不再向今日校园提交空验证码(修复"验证码的值不能为空")
v1.1.21
2026-09-01 22:08:17 +08:00
becomer 5298e30bd0 fix: 修复 iPad/iOS Safari 底部导航栏不可见(100vh → 100dvh + safe-area)
ci/woodpecker/tag/build Pipeline was successful
- #app 高度 100vh 在 iOS/iPadOS Safari 地址栏展开时超出视口,配合 overflow:hidden 导致底部 TabBar 被裁切不可见;改用 100dvh(保留 100vh 兜底)
- viewport 增加 viewport-fit=cover,TabBar 增加 env(safe-area-inset-bottom) 适配 Home 条安全区
- 管理后台 min-h-screen 统一改为 min-h-dvh
v1.1.20
2026-09-01 21:56:21 +08:00
becomer 3a26aaa155 fix: 公告target绑定类型防串台 + 绑定设备页增加退出登录
ci/woodpecker/tag/build Pipeline was successful
- 公告查询/已读校验中 target_user_id 未与 target_type 绑定,用户表与代理表自增 ID 重叠(均为 1000 起)导致管理员在后台收到发给前台用户的公告;现改为 target_type 与 target_user_id 联合匹配
- 绑定设备页底部增加退出登录按钮,未扫码时可随时退出当前账号,避免一直卡在绑定页
v1.1.19
2026-08-30 22:21:36 +08:00
becomer 14270ab02d fix: 南昌理工登录重试时刷新公钥 + 流水线 tag 事件触发条件修复
ci/woodpecker/tag/build Pipeline was successful
- nut_login:每次 attempt 重新获取 CAS 动态公钥(密钥对随登录页刷新轮换,
  旧公钥加密会致服务端解密失败误报"用户名或密码错误")
- nut_login:"用户名或密码错误"也纳入重试(OCR 误识别时 CAS 可能统一提示),
  最多 3 次尝试后仍失败才返回错误
- woodpecker:when 条件 branch:[v*] 改为 tag:v*(tag 事件无分支名,
  v1.1.18 推送被过滤未触发构建)
v1.1.18
2026-08-30 22:14:42 +08:00
becomer edd4e90719 fix: 修复提交IP记录为反代网关地址 + 邀请码只读 + 待适配页展示已适配学校
ci/woodpecker/tag/build Pipeline was successful
- 后端:fiber 配置 TrustedProxies(172.22.0.0/16)+X-Forwarded-For,待适配学校提交记录真实客户端 IP
- 后端:pending-schools 列表 status=completed 时正确过滤已完成记录
- 前端:登录页邀请码由邀请链接自动带入,改为 disabled 不可编辑
- 前端:待适配学校页面顶部展示已适配学校列表,学校分组标注"已适配"徽标
2026-08-30 22:12:39 +08:00
becomer 2f93e24a39 fix: 适配南昌理工学院自研 CAS→IAP 混合登录(学校ID匹配,独立于通用IAP/CAS逻辑)
ci/woodpecker/tag/build Pipeline was successful
该校登录链路与标准金智 IAP/Apereo CAS 均不同:
- /portal/login → /iap/login 页面实际转发到学校自研 CAS(my.nut.edu.cn/cas/login),
  表单为 username/password/authcode/execution/_eventId 风格
- 登录成功后 302 回跳 /iap/loginSuccess?sessionToken=xxx&ticket=ST-... 建立 IAP 会话
- 密码加密特殊:先反转,明文块按小端 16-bit digit 装配后直接 m^e mod n
  (无 PKCS#1 填充),公钥由 /cas/v2/getPubKey 动态获取,hex 空格分隔
- 每次登录均需图形验证码(/cas/kaptcha),OCR 识别失败自动重试最多3次

新增 nut_login.go 专用实现,CpdailyLogin 按 school.ID 匹配路由,不动通用 IAP/CAS 代码。
v1.1.17
2026-08-30 22:03:09 +08:00
becomer 49e1cef31c fix: 任务类型 tag 不换行 + 图片上传 loading 动画 + 移除照片提示文案
ci/woodpecker/tag/build Pipeline was successful
1. 任务列表/标题选择/日志三处任务类型 tag 加 shrink-0 whitespace-nowrap,
   标题加 min-w-0 truncate,标题过长不再挤换行
2. 创建与编辑表单的图片区域上传中显示旋转 loading
3. 移除签到照片字段下方的"您可以上传多张图片"提示
v1.1.16
2026-08-23 19:49:28 +08:00