xcbyy
|
e595defaaf
|
fix(admin): 用户360画像订单归属改用 expert_id IN (本人档案 id),与列表口径一致且避免 id 撞号
|
2026-10-22 11:35:46 +08:00 |
|
xcbyy
|
32defce50c
|
fix(order): 关闭按用户 id 撞库档案 id 的订单归属兜底,避免潜在越权读取
- getOrdersForUser/countOrdersForUser 仅按 companions.user_id 关联本人档案,不再使用 companions.id = 用户 id
- 补充回归断言;116 套件/758 用例全绿;线上已验证用户订单仍正常
|
2026-10-22 11:33:47 +08:00 |
|
xcbyy
|
d876288394
|
feat(list): 订单/通知/组局列表分页,生产 NODE_ENV 切换 production
- 仓储层 getOrders/getOrdersForUser/getActivities/getUserNotifications 支持 LIMIT/OFFSET,新增 countOrders/countOrdersForUser/countActivities/getUserNotificationTotal
- 接口支持 page/pageSize/status/keyword/payType/creatorId/category,返回 list/total/hasMore;未传 page 保持旧数组格式,兼容后台与工作台
- 小程序订单/通知/组局三页触底加载,筛选与搜索下推服务端,避免只过滤当前页
- 新增 116 套件/758 用例,全绿;线上实测分页与筛选接口正常
|
2026-10-22 10:52:40 +08:00 |
|
xcbyy
|
082ec1c385
|
feat(order): 禁止自己接自己发布的订单
- claimOrder 校验 buyer_id 与大神登录用户 id,相同直接 403「不能接自己发布的订单」
- 派单池支持 excludeBuyerId:已登录大神不会看到自己发布的待接单
- 115 套件/753 用例全绿;线上实测自接 403、他人可抢、自己的单不出现在自己的池子
|
2026-10-22 10:35:56 +08:00 |
|
xcbyy
|
81368f870f
|
fix(order): 统一 expert_id 为大神档案 id,统计兼容历史接单;修复提现卡单告警误报
- claimOrder 写入 expert_id=companion.id、claimed_by=user.id;启动时幂等回填历史 expert_id=claimed_by 的数据
- getExpertStats / getExpertRevenueTrends 按 (expert_id=? OR claimed_by=?) 双口径统计,解决工作台与接单大厅口径不一致导致漏单
- withdrawals 新增 updated_at(ON UPDATE),提现卡单巡检改用最后更新时间,避免审核旧工单立即误报
- 115 套件/752 用例全绿;线上实测抢单写入 expert_id=9/claimed_by=2010,改后统计两口径一致
|
2026-10-22 10:31:21 +08:00 |
|
xcbyy
|
abf1f5afbb
|
fix(subscribe): 识别演示账号假 openid,完善订阅消息测试诊断
- 新增 isPlausibleWechatOpenid:wx_openid_ 前缀/长度异常的种子 openid 一律视为无效,notifyBySubscribe 与内容安全 openid 均跳过,避免 40003 无效 openid 噪音
- 后台模拟推送返回 openidValid 诊断,并对演示账号给出「请改用真实微信登录用户测试」的明确提示;表单默认 UID 清空
- 115 套件/751 用例全绿;实测 2010 已走到微信侧(43101 用户未授权,需小程序内点击允许)
|
2026-10-22 10:05:53 +08:00 |
|
xcbyy
|
65ddc7301a
|
feat(ops): 每日数据库备份 + 资金异常巡检告警 + 后台操作审计
- 新增 system_alerts/admin_audit_logs 表与 (status,created_at) 索引;启动即巡检、每 5 分钟扫描提现卡单/支付与订单不一致/待接单超时
- 后台新增「系统告警与操作审计」页(告警处理 + 审计列表),并接入消息铃铛待办
- 余额调整/封禁/删除/大神审核/提现打款/告警处理等敏感操作写入审计日志(含 IP)
- 新增 server/scripts/backup-db.sh 并已在生产配置每日 03:30 cron(校验+保留 14 天)
- 清理空的 order_messages 表;115 套件/750 用例全绿;线上实测告警接口/审计落库/备份均通过
|
2026-10-22 09:54:10 +08:00 |
|
xcbyy
|
d941a16d28
|
fix(miniapp): 清理剩余身份兜底并修正待接单状态/客服入口
- 修复 user/index 使用 normalizeUserId 未导入(分享按钮会报错)
- 待接单独立为 PENDING_ACCEPT:新增待接单 tab/状态色/取消订单与联系客服操作,不再显示为进行中
- 移除 hall/bill-records/reports/settings/favorites/order-create/activity-create/activity-detail/apply 的 1001/2006 身份兜底
- 线下订单(含指定大神)必须填写碰面地点;再次预约不再兜底到 101 号大神;评价不预选标签
- 接单大厅去掉「已实名认证/信誉积分100」等伪造信任文案;客服按钮统一为「联系客服」
- 114 套件/745 用例全绿
|
2026-10-22 09:25:27 +08:00 |
|
xcbyy
|
be1c7be5d3
|
revert(order): 移除订单站内聊天,沟通统一走官方客服
- 删除 pages/order/chat、聊天接口/仓储方法/order_messages 建表与客户端 API
- 买家「联系大神」、大神「联系老板」、大神详情「在线客服」、组局「私聊」统一改为 openSupportSheet(读取后台 customer_service 配置的客服微信/热线)
- 保留派单实时通知与雷达/大厅轮询
- 114 套件/742 用例全绿;聊天接口线上已 404
|
2026-10-22 09:10:16 +08:00 |
|
xcbyy
|
aca35db200
|
feat(order): 派单实时通知 + 订单站内聊天
- 新派单(余额支付立即入池 / 微信支付确认后入池)向在线认证大神推送 ORDER_POOL 站内通知;雷达 20s、接单大厅 30s 自动轮询
- 新增 order_messages 表与订单会话接口:仅买家与已认领大神可访问,服务端拦截手机号与违规内容,消息落库并推送 CHAT 通知
- 新增 pages/order/chat 聊天页(3s 轮询、已读、发送),买家订单「联系大神」与大神工作台「联系老板」接入
- 114 套件/744 用例全绿;线上实测聊天/越权/手机号拦截/新单通知均通过,测试数据已清理
|
2026-10-22 08:52:12 +08:00 |
|
xcbyy
|
33b6a3ea7d
|
feat(activity): 发单页统一组局与平台派单入口,接单大厅展示附近组局
- 移除附近活动页顶部单独的派单按钮(入口重复)
- 「我要发单」新增发布类型切换:发起组局 / 平台派单,派单模式填预算与时长并内联拉起支付,支付成功进入待接单池
- 接单大厅新增「附近组局(可报名)」区块,展示招募中的组局并可进入详情报名
- 113 套件/738 用例全绿
|
2026-10-21 18:03:09 +08:00 |
|
xcbyy
|
14ce4b25f5
|
feat(admin): 用户列表新增「调余额」人工充值/扣减入口
- 新接口 POST /api/admin/users/:id/balance(requireAdmin):事务锁行、扣减不可为负、单次上限 100 万、写 finance_records 并推送站内通知
- 后台用户列表每行新增「调余额」按钮与弹窗(当前余额/方向/金额/备注)
- 新增 admin-balance-adjust 护栏;113 套件/737 用例全绿
|
2026-10-21 17:41:54 +08:00 |
|
xcbyy
|
4e3283ff01
|
fix(miniapp): 修复 hall.vue 混入 TS 类型标注导致编译失败
- countByType 的 (cls: string)/(o: any) 改为纯 JS 写法
- 新增 miniapp-script-syntax 护栏:未声明 lang=ts 的 vue 脚本禁止 TS 类型标注(112 套件/734 用例全绿)
|
2026-10-21 16:48:32 +08:00 |
|
xcbyy
|
18035fefad
|
feat(activity): 附近活动页新增「发布陪玩需求(平台派单)」入口
- 组局活动与抢单订单是两套数据:组局进活动大厅,平台派单订单才进入待接单池
- 入口直接跳转 /pages/order/create(不指定大神时自动进入平台派单模式)
|
2026-10-21 16:35:01 +08:00 |
|
xcbyy
|
16f6419cba
|
refactor(data): 全面移除小程序写死的演示/兜底数据,测试数据统一落库
- 删除无引用的 common/mock.js;登录页与个人中心的演示账号改为 DB 配置 demo_accounts + /api/auth/demo-accounts、/api/auth/demo-login(签发真实 token)
- 移除订单/活动/大神/动态/推广/工作台/门票/充值/举报等页面的演示列表与假兜底;新增真实空态
- 修复伪造成功:活动调价、评价回复、核销、海报保存、图片上传失败、提现/核销固定 1001、随机开黑房号、随机即时匹配、假语音播放等
- 服务端移除 101/2006 合成用户与合成大神兜底、移除默认服务包虚构价格;演示账号清单可在后台关闭
- 111 套件/733 用例全绿;已部署 20261021_162041,demo-accounts/demo-login 实测通过
|
2026-10-21 16:21:10 +08:00 |
|
xcbyy
|
77aa4cb50b
|
feat(order): 平台派单闭环(发需求单进入待接单池)
- 下单页新增「指定大神 / 平台派单」模式:平台派单填品类、预算、地点/选点,expertId=0
- 服务端:平台派单单据支付后进入待接单池(余额支付即时入池,微信支付确认后入池),预算由买家出价但受 1~2000 元/小时约束
- 抢单由认领大神写入 expert_id 并转履约中;30 分钟无人接单沿用自动全额退款
- 修复订单 INSERT 占位符少一个导致下单报 Column count doesn't match 的问题,并新增列数/占位符一致性护栏
- 111 套件/737 用例全绿;线上 1 元实测:下单→待接单→池内 640m,测试数据已回滚
|
2026-10-21 15:16:03 +08:00 |
|
xcbyy
|
5538d8ce7e
|
fix(miniapp): 接单大厅分类数量取真实数据,抢单失败不再伪造订单
- 分类 chip 的 12/4/3 写死数量改为按真实订单统计
- 雷达页抢单失败时删除「自动落盘创建订单」兜底(原逻辑会伪造一笔 buyerId=2001 的订单并提示成功),改为如实提示已被抢/状态不可接/未认证
- 抢单使用当前登录身份(userId 由服务端 token 覆盖),成功后刷新列表
- 110 套件/730 用例全绿
|
2026-10-21 14:55:01 +08:00 |
|
xcbyy
|
68e41ca962
|
feat(lbs): 真实距离与按距离派单落地
- 数据库:orders/activities 新增 latitude/longitude(含存量表 ALTER 迁移)
- 服务端:Haversine 计算 distanceKm/distanceText,派单池支持 lat/lng/radius 过滤并按距离升序;历史无坐标订单用腾讯地理编码兜底并回写缓存
- 新增 /api/lbs/reverse 逆地址解析(Key 仅服务端持有,登录 + 限流)
- 小程序:雷达/接单大厅改用真实定位与真实距离,删除全部写死演示距离;下单页新增地图选点,组局页保存选点经纬度
- 修复接单大厅点接单会新建订单的问题,改为真正 claimOrder 认领
- 新增 lbs-distance 护栏(110 套件/729 用例全绿)
|
2026-10-21 14:29:33 +08:00 |
|
xcbyy
|
ecc4a116c4
|
feat(pay): 商家转账场景 1005 打通提现打款
- 转账场景报备信息按佣金报酬要求固定传「岗位类型/报酬说明」两段,否则微信参数校验拒绝
- 处理 WAIT_USER_CONFIRM(用户确认模式):推送「提现待你确认收款」,提示 24 小时内确认
- 提现申请增加单笔上限校验(finance_rules.maxWithdrawAmount,默认 200,对齐微信商家转账额度)
- /api/posts 身份优先取服务端会话 token
- 文档补充佣金报酬场景与用户确认模式说明(109 套件/722 用例全绿)
|
2026-10-21 14:03:22 +08:00 |
|
xcbyy
|
40e601e345
|
fix(security): 鉴权签名密钥 fail-closed,禁用仓库内置默认密钥
- ADMIN_TOKEN_SECRET 的随机化闸门由 NODE_ENV 改为 SECURE_MODE:线上以 development 运行时不再使用公开默认密钥(该密钥可伪造管理员/用户 token)
- 运行模式与安全开关常量前移到模块顶部,避免鉴权常量初始化顺序问题
- 启动自检与回归用例同步(109 套件/720 用例全绿)
|
2026-10-21 12:14:16 +08:00 |
|
xcbyy
|
dd836b674e
|
fix(security): 安全闸门与 NODE_ENV 解耦,支付/提现 fail-closed
- 新增 SECURE_MODE(仅 ALLOW_INSECURE_DEV_AUTH=1 时放开):后台登录口令、上传、内容检测、核销码归属全部改为默认收紧,修复线上以 NODE_ENV=development 运行时闸门失效
- 提现审核:未开通真实转账且未显式 ALLOW_SANDBOX_PAY=1 时一律 503,杜绝只改状态不打款
- 预支付:未开启沙箱时不再下发沙箱参数;小程序删除预支付失败伪造沙箱成功的兜底,改为抛错
- 订阅消息支持 MINIPROGRAM_STATE=formal|trial|developer 显式配置,避免真实用户收不到通知
- 动态列表/点赞身份统一 normalizeUserId;文档补充安全闸门与订阅消息环境变量
- 109 套件/720 用例全绿,tsc 构建通过
|
2026-10-21 11:50:11 +08:00 |
|
xcbyy
|
87cb6a6374
|
fix(miniapp): 提现/财务接口不再用 1001 演示身份,修复 403
- getUserProfile/getUserWithdrawals/getUserFinanceRecords 去掉 userId=1001 默认值,改由 normalizeUserId 解析登录身份
- withdraw.vue / withdraw-records.vue / workspace.vue 调用改为 normalizeUserId(),不再硬编码 1001
- normalizeUserId 将 1001 视为演示占位符:登录态下传 0 由 token 识别,未登录才兜底 1001
- request.js 遇 403 身份校验失败时清理错配登录态并提示重新登录(其它 403 权限拒绝不受影响)
- 登录态闸门补齐用例(108 套件/714 用例全绿)
|
2026-10-21 11:38:26 +08:00 |
|
xcbyy
|
9217dfcf11
|
fix(miniapp): 导出 normalizeUserId 修复入驻页编译失败
- api.js 的 normalizeUserId 之前是内部函数,apply.vue 具名导入导致 HBuilderX 编译报错,现改为 export
- 新增 miniapp-imports.spec.ts:静态校验小程序所有具名导入都存在对应导出,避免再出现只能靠人工编译才发现的问题(108 套件/711 用例全绿)
|
2026-10-21 11:32:03 +08:00 |
|
xcbyy
|
a249a5ee62
|
feat(voice): 录音时实时读秒,60 秒自动停止
- 入驻申请页/大神工作台:点击开始录音后,按钮显示已录秒数,状态栏显示剩余秒数(每秒刷新)
- 录音中按钮转为红橙渐变并呼吸闪烁,状态文字高亮;离开页面/出错自动清理计时器
- 60 秒到点自动 stop 录音,避免超长被服务端拒绝
- voice-intro-consistency 增补读秒护栏(107 套件/710 用例全绿)
|
2026-10-21 11:20:22 +08:00 |
|
xcbyy
|
ae62f2b805
|
feat(voice): 入驻页录音 + 后台审核真实试听
- 入驻申请页新增「语音自我介绍(可选,≤60s)」录音/试听,申请成功拿到大神档案 id 后自动上传,失败不影响入驻结果
- 管理端审核「真人语音包核听」由 3 秒假播放改为按 voiceIntroUrl 真实播放,未上传显示灰色标记
- 清理小程序审核敏感词(语音房/连麦/开麦),入驻页身份改用 normalizeUserId 与 token 保持一致
- 新增 voice-intro-consistency.spec.ts(107 套件/709 用例全绿)
|
2026-10-21 11:12:42 +08:00 |
|
xcbyy
|
7a1e32688c
|
fix(miniapp): 修复登录态错配导致的 403(userId 与 userToken 原子写入/清除)
- completeLogin 统一接收 sessionToken:有 token 写入、无 token(体验账号回退)清除旧 token,杜绝旧 token 属主与新 userId 不一致
- 微信手机号登录把 token 交给 completeLogin 统一落库
- normalizeUserId 移除历史 101→2006 映射;有 token 但本地 userId 缺失时传 0,由服务端按 token 识别
- 新增 login-identity-consistency.spec.ts(106 套件/706 用例全绿)
|
2026-10-21 10:59:22 +08:00 |
|
xcbyy
|
f56bbe76d7
|
fix(api): 收藏状态接口不再把 401 吞成 500
- /api/favorites/check 的 catch 改为透传 err.status/err.code(未登录返回 401 + 40010/40100,而非 500)
- 线上日志确认根因:未携带用户 token 时 resolveSecureUserId 抛 401 被包装成 500
- 新增 favorites-status-code.spec.ts(105 套件/703 用例全绿);冒烟 3/3
|
2026-10-21 10:52:13 +08:00 |
|
xcbyy
|
720cb97877
|
feat(voice): 大神语音介绍真实落地(录制/上传/试听)
- DB: companions.voice_intro_url;仓储 updateCompanionVoice;详情与 /api/expert/me 返回 voiceIntroUrl/voiceDuration
- 后端: POST /api/companions/:id/voice(音频白名单 mp3/m4a/aac/wav/ogg、5MB、≤60s、限流、仅本人或管理员)
- 小程序: api.uploadVoiceIntro(uni.uploadFile + 用户令牌);工作台新增「语音介绍」卡片(录制/重录/试听,60s mp3);详情页改为 uni.createInnerAudioContext 真实播放,卸载销毁
- 修复 uploadImage 未携带用户令牌(生产 fail-closed 后会导致上传失败)
- 新增 voice-intro.spec.ts(104 套件/701 用例全绿);冒烟 7/7
|
2026-10-20 18:25:11 +08:00 |
|
xcbyy
|
d06bf11740
|
security: 危险兜底默认关闭(secure by default)——修复 NODE_ENV 未设导致的身份伪造/沙箱支付/隐私泄露
根因:线上 NODE_ENV 未设为 production 时,以下"开发兜底"全部自动生效:
- resolveSecureUserId 信任客户端声明的 userId → 任意用户身份伪造
- ALLOW_SANDBOX_PAY = ... || !IS_PRODUCTION → 无真实收款即可推进订单(资损)
- GET /api/users/:id 按"本人"返回余额/佣金/手机号 → 隐私泄露
修复(兜底改为必须显式开启):
- 新增 ALLOW_INSECURE_DEV_AUTH(默认 false);resolveSecureUserId 改为 `if (IS_PRODUCTION || !ALLOW_INSECURE_DEV_AUTH) 401`
- ALLOW_SANDBOX_PAY 改为仅 `process.env.ALLOW_SANDBOX_PAY === '1'`
- assertCompanionActor 与用户资料"本人视角"兜底加 ALLOW_INSECURE_DEV_AUTH 限制
- /api/health 新增 mode 与 sandboxPayAllowed;启动自检打印两个危险开关并告警
- 文档补充危险开关说明(生产禁止开启)
验证:本地模拟 NODE_ENV 未设 → 通知/订单/下单 均 401、用户资料不泄露隐私、沙箱支付关闭;
开启 ALLOW_INSECURE_DEV_AUTH=1 后联调能力保留;production 模式行为一致。(冒烟 13/13)
新增 secure-default-auth.spec.ts(103 套件/696 用例全绿)
|
2026-10-20 16:35:04 +08:00 |
|
xcbyy
|
e09f072f55
|
security: /api/health 暴露运行模式与沙箱支付开关(便于发现生产跑成 development)
- health 新增 mode(production/development) 与 sandboxPayAllowed
- 便于部署自检:非 production 时身份校验放宽且允许沙箱支付,属资损级配置风险
- 新增 runtime-mode-selfcheck.spec.ts(102 套件/691 用例全绿)
|
2026-10-20 16:04:09 +08:00 |
|
xcbyy
|
f3ea26d161
|
feat(admin): 方案A—消息铃铛接真实待办聚合 + 清理空壳接口与空卡片
【消息铃铛(真实数据)】
- POST /api/message/list 改为待办聚合:待接单订单/待审核大神/待审核提现/待处理举报/待仲裁工单(复用 getDashboardTodos + 新增 pendingOrdersCount)
- POST /api/message/read 持久化已读:新表 admin_message_reads 记录"已读时的数量",待办数量增加会重新变未读
- 两个接口均加 requireAdmin(待办数量属运营数据,不再匿名可见)
【删除空壳/死接口(前端已无调用方)】
- /api/user/save-info、/api/chat/list、/api/user/my-team/list、/api/user/latest-activity、/api/user/my-project/list
【后台页面清理】
- 「用户与个人中心 → 管理员资料」移除 我的项目/最近动态/我的团队/站内通知 四张空卡(保留真实的管理员资料头部)
- 删除对应 4 个组件;api/user-center.ts 移除 queryMyProjectList/queryMyTeamList/queryLatestActivity/saveUserInfo;api/message.ts 移除 queryChatList
【验证】
- 新增 admin-todo-bell.spec.ts;更新 admin-demo-data-cleanup.spec.ts
- 全量 101 套件 / 690 用例全绿;冒烟 8/8(未登录50008、待办数量、已读、新增后重新未读)
- 后台 pnpm build 通过
|
2026-10-20 15:52:04 +08:00 |
|
xcbyy
|
05815b4708
|
feat(ui): 余下两页接入主题 + 清理后台模板 demo(1+2)
【1. 主题补全】
- pwuniapp/pages/expert/workspace.vue(大神工作台):根节点加 theme class,66 处深色硬编码改为全局主题变量(bg-primary/surface/surface-elevated/text-*/border-subtle/color-brand(-gradient))
- pwuniapp/pages/activity/my-ticket.vue(我的门票):同样接入主题;条码/二维码区域保持黑白(可扫描,不做主题化)
- 两页 onShow 刷新 currentThemeKey,切换主题回到页面即时生效
【2. 后台模板 demo 清理】
- 删除模板路由模块:form / list / profile / result / visualization(原本 hideInMenu 不可见)
- 删除对应 views 目录、api(form/list/profile/visualization/dashboard)、dashboard/monitor
- 删除 src/mock 与全部 views/**/mock.ts,并移除 main.ts 的 `import './mock'`
- 可见工作台移除:content-chart(调用不存在的 /api/content-data)、popular-content(写死假活动数据);分类占比卡片改为整行
- 同步清理 zh-CN/en-US locale 中对应导入与展开
【验证】
- 后台 `pnpm build` 通过,产物显著减小(chart 分块 1026KB→576KB)
- 新增 theme-and-admin-cleanup.spec.ts;更新 dashboard-reality.spec.ts
- 全量 100 套件 / 685 用例全绿
|
2026-10-20 15:01:50 +08:00 |
|
xcbyy
|
dde3cce562
|
fix(ui): 下单页背景/卡片/文字跟随全局主题(修复暖色主题下仍是深色底)
- create.vue 原先把整套深色配色写死,仅局部有 .theme-warm 覆盖 → 暖色主题下页面底色/卡片仍是深色
- 统一改用全局主题变量:容器 var(--bg-primary)、卡片 var(--bg-surface)、次级面 var(--bg-surface-elevated)、文字 --text-primary/secondary/muted、描边 --border-subtle、品牌 --color-brand(-gradient)、底部支付栏 --bg-surface-glass
- 替换 15 处深色时代的中性半透明白(rgba(255,255,255,0.03~0.1))为对应主题变量,暖色下不再白上白
- 主按钮渐变改用 var(--color-brand-gradient),暖色下自动变为橙色渐变
- theme-consistency.spec.ts 增加下单页断言(99 套件/682 用例全绿)
|
2026-10-20 14:00:27 +08:00 |
|
xcbyy
|
4119bfc303
|
fix(ui): 优化大神详情页底部操作栏布局(不再挤压换行)
- 左侧「私聊/收藏/举报」独立成 bar-actions 组:固定 76rpx 宽、flex-shrink:0、文案 nowrap,杜绝被价格块挤压换行
- 价格块改为右对齐两行展示:小字标签「当前选定」+ 金额(独立 ¥ 符号,大号加粗),不再与标签挤在一行
- 「立即预约」按钮 flex-shrink:0 + min-width 220rpx,胶囊圆角(999rpx),保证任何机型都可点且不被压缩
- 未认证大神的提示改为独立的 guest-tip(右对齐、单行)
- 底部栏高度改为 min-height+内边距并保留安全区;暖色主题同步补充 summary-sym/guest-tip 配色
- 新增回归护栏 detail-bottom-bar.spec.ts(99 套件/681 用例全绿)
|
2026-10-19 16:00:37 +08:00 |
|
xcbyy
|
d5c50aabe6
|
fix(order): 修复大神无服务包时下单页崩溃(Cannot read properties of null reading 'title')
- 起因:上一批移除"系统自动生成演示服务包"后,未配置服务包的大神返回空列表,下单页模板直接取 selectedService.title 触发空指针
- 下单页新增 serviceView 安全视图(computed 带兜底对象),模板统一改用 serviceView.title/price/unit,杜绝解引用 null
- 无服务包时按大神基础时薪兜底生成"<品类>基础陪伴服务",保证仍可下单(价格仍由服务端档案价二次校验)
- 详情页取 services[0] 前先判空,并新增"暂未配置服务项目"空态提示
- 新增回归护栏 null-service-guard.spec.ts(98 套件/677 用例全绿)
|
2026-10-19 15:51:23 +08:00 |
|
xcbyy
|
a1e3a137b6
|
fix(ui): 修复优惠券页/消息页导航栏位置偏高(标题与返回按钮应贴胶囊行)
- 原因:初版用 padding-top=safe-header-gap + 44px 内容行,把标题推到状态栏下方,顶部留白过大
- 改为与其它页面一致的规范:导航栏总高=var(--safe-header-gap),内容行 position:absolute;bottom:0;height:var(--capsule-height) 贴底对齐胶囊;标题绝对居中(translateX(-50%))
- 页面根改为 height:100vh + flex 纵向布局,列表用 flex:1 撑满剩余空间(tab-bar/滚动区不再按 100vh 硬算)
- 返回按钮对齐既有规范(64rpx 圆形底 + 38rpx 图标)
- 回归 97 套件/674 用例全绿(theme-consistency.spec.ts 增加导航规范断言)
|
2026-10-19 15:42:18 +08:00 |
|
xcbyy
|
ae569d0ca6
|
fix(ui): 优惠券页/消息页主题配色跟随全局主题切换
- coupons.vue / notifications.vue 由写死深色改为复用全局 CSS 变量(--bg-primary/--bg-surface/--color-brand-gradient/--text-*/--border-subtle/--nav-bg),随 theme-warm(暖阳晨曦)与默认冷光暗夜自动适配
- 大神工作台新增的服务包表单样式同步复用主题变量
- 新增回归护栏 theme-consistency.spec.ts(97 套件/673 用例全绿)
|
2026-10-19 15:27:04 +08:00 |
|
xcbyy
|
b70a24327b
|
chore(ops): /api/health 增加 build 与 features 能力清单,便于部署自检
- 线上小程序请求新接口 404 时,可先 curl /api/health 确认线上构建版本与已包含能力
- features 覆盖:用户令牌/后台口令闸门/安全头/限流/5xx脱敏/令牌吊销/通知中心/服务包自助/优惠券/大神搜索
- 回归 96 套件/669 用例全绿
|
2026-10-19 15:16:32 +08:00 |
|
xcbyy
|
d0d31d0380
|
feat(search): 大神关键词搜索走服务端(昵称/品类/段位/标签)
- 仓储 getCompanions(keyword?):参数化 LIKE 搜索 name/track/rank_name/tags 及 id 精确匹配
- 接口 /api/companions 支持 ?keyword=(长度截断 40)
- 小程序 api.js getCompanions(keyword) 带 encodeURIComponent;首页监听 searchKeyword 防抖 350ms 走服务端搜索,搜索态以服务端结果为准(含空结果不展示陈旧数据)
- 回归 95 套件/668 用例全绿;冒烟 4/4(昵称/品类命中、无匹配空数组、无关键词向后兼容)
|
2026-10-19 15:10:11 +08:00 |
|
xcbyy
|
6576c9e4be
|
feat(coupon): 优惠券中心(领取)+ 我的券 + 下单核销/回退
- 新表 user_coupons(快照面额/门槛/类目/有效期)+ orders.user_coupon_id
- 仓储:getCouponsWithClaimed/claimCoupon/getUserCoupons/resolveUserCoupon/consumeUserCoupon/releaseUserCouponByOrder
- 接口:POST /api/marketing/coupons/:id/claim(同券仅一次、受总量限制)、GET /api/marketing/my-coupons(自动标记过期)、券中心带 claimed 标识
- 下单:createOrder 支持 userCouponId(校验归属/门槛/类目/有效期,服务端算抵扣,与订单同事务占用)
- 回退:买家取消/大神拒单/超时退款/仲裁退款 均把券退回为 UNUSED
- 小程序:新增 pages/user/coupons(券中心+我的券)、个人中心入口(可用张数)、下单改为选择"我的券"并传 userCouponId
- 回归 94 套件/666 用例全绿;冒烟 9/9(领取/重复领取409/不存在404/下单抵扣100-10=90/取消回退)
|
2026-10-19 15:05:56 +08:00 |
|
xcbyy
|
500aac306e
|
feat(expert): 大神服务包自助维护(新增/编辑/删除/上下架)+ 去掉演示服务包
- 后端:新增 POST/PUT/DELETE /api/companions/:id/services[...](仅本人大神或管理员),含名称/单价区间(平台定价规范)/长度/内容安全/每人20个上限校验
- 仓储:createExpertService/updateExpertService/deleteExpertService/countExpertServices/getCompanionByUserId;移除"首次读取自动生成 3 个演示服务包",并在建表后一次性清理历史演示数据
- 新增 GET /api/expert/me:工作台按登录用户解析真实大神档案(不再固定演示 id 101)
- 小程序:api.js 增加 getMyExpertProfile/createExpertService/updateExpertService/deleteExpertService;工作台新增「新增服务」入口、每项「编辑/删除」按钮与服务包表单弹窗,收益/服务统计改用真实大神 id
- 新增回归护栏 expert-service-crud.spec.ts(93 套件/662 用例全绿);冒烟 9/9(含跨大神越权 403、低价 400)
|
2026-10-19 14:46:05 +08:00 |
|
xcbyy
|
ca7f849b14
|
feat(notify): 新增站内消息通知中心(订阅消息兜底)+ 清理后台伪造数据
- 新表 user_notifications + 仓储方法(创建/列表/未读数/标记已读)
- 用户接口 GET /api/notifications、POST /api/notifications/read(生产需登录)
- 关键节点落库:订单开始服务/接单/拒单/申请完成/完成结算/提现到账/报名成功/退款受理
- 小程序新增「消息通知」页(pages/user/notifications) + 个人中心入口与未读角标;api.js 增加 getNotifications/markNotificationsRead
- 清理后台伪造数据:/api/user/certification 改空态、/api/user/my-project/list 改空数组、/api/user/info 去掉编造邮箱/电话/网址
- 更新 pages 数量断言(26→27);新增回归护栏 notification-center.spec.ts(92 套件/658 用例全绿);冒烟 9/9
|
2026-10-19 14:31:11 +08:00 |
|
xcbyy
|
12bbf4fc6b
|
security: 后台登录态可吊销(令牌版本号) + 清理未使用的 prisma 依赖(依赖漏洞 46→0)
- admin token 载荷新增 ver 版本号,与当前版本不一致即失效;版本持久化到 platform_configs,重启/多实例(30s同步)均生效
- 新增 POST /api/admin/session/revoke-all(requireAdmin):一键吊销全部后台登录态;后台右上角新增入口
- 令牌有效期改为可配置 ADMIN_TOKEN_TTL_HOURS(默认由 7 天收紧到 24 小时)
- 移除 server 未使用的 @prisma/client / prisma(server/src 零引用),pnpm 移除 331 个包;pnpm audit --prod 由 46 个漏洞降为 0
- 新增回归护栏 admin-token-revocation.spec.ts(91 套件/653 用例全绿);冒烟 6/6
|
2026-10-19 14:08:58 +08:00 |
|
xcbyy
|
0752acda40
|
fix(ratelimit): 全局限流改为优先按用户分桶并按 1200/分放宽,避免反代未透传 XFF 时全站误伤
|
2026-10-19 13:51:27 +08:00 |
|
xcbyy
|
25d8474877
|
security: 新增全局限流 + 5xx 错误脱敏 + 兜底错误处理
- 内存级限流器(令牌桶):/api 全局 600/分;写接口单独限流(发帖10、评论20、组局申请20、举报5、上传30、下单20、支付30、充值/提现10、浏览1次/3秒);超限 429+Retry-After
- 5xx 统一脱敏:内部错误仅记服务端日志,对外返回“服务器内部错误”,不再回传 SQL/堆栈/内部原因
- 新增兜底错误处理中间件,避免 Express 默认 HTML 堆栈外泄
- 更新 upload 断言;新增回归护栏 ratelimit-5xx.spec.ts(90 套件/648 用例全绿);冒烟 7/7
- 文档补充限流与错误脱敏说明
|
2026-10-19 13:50:51 +08:00 |
|
xcbyy
|
a61051fa96
|
security: 修复公开配置接口泄露密钥(map_location_config/security_words)
- /api/system/configs 无需登录,此前原样下发 map_location_config(腾讯位置服务 SecretKey)与 security_words(风控词库)
- getPlatformConfigs 改为:排除 security_words/map_location_config,并递归剔除 secret/private/apiv3/token/pem/cert/mchid 等敏感字段
- wechat_pay_config 仍仅返回脱敏字段(mode/appId/mchIdConfigured)
- 新增回归护栏 public-config-privacy.spec.ts(89 套件/644 用例全绿);冒烟 5/5
|
2026-10-19 13:39:04 +08:00 |
|
xcbyy
|
699d2bd951
|
security: 后台默认口令生产 fail-closed(修复 admin/admin 可登录的高危漏洞)
- 生产环境未配置 ADMIN_PASSWORD(或仍为 admin/admin123)时,后台登录直接 503 拒绝
- 启动自检新增两条告警:未配有效 ADMIN_PASSWORD、非 production 身份校验放宽
- 部署文档补充 ADMIN_PASSWORD/ADMIN_USERNAME 必配说明
- 新增回归护栏 admin-credential-hardening.spec.ts(88 套件/642 用例全绿);冒烟 5/5
|
2026-10-19 13:36:36 +08:00 |
|
xcbyy
|
b88442af28
|
fix(subscribe): 修复小程序授权"未获得提醒授权"——避免授权弹窗与公告弹窗重叠
- openNotice 改为串行:先请求订阅授权,等授权弹窗关闭后再展示平台公告(此前两原生弹窗重叠会取消授权,回调全 reject)
- 授权结果区分展示:成功显示已开启项数;未同意提示可在微信设置中重新允许;接口报错显示 errCode
- requestSubscribeAll 单次最多取前3个模板(微信限制),并返回 resultMap 便于排查
- 回归 87 套件/639 用例全绿
|
2026-10-19 11:36:12 +08:00 |
|
xcbyy
|
c17afd20d5
|
feat(admin): 模板列表支持「一键按标题填入槽位」,避免手抄长模板ID出错
- 列表每行新增「填入」按钮,按标题(订单/提现/活动报名/核销)自动写入对应槽位
- 顶部新增「一键按标题填入槽位」,批量填入后提示保存落库
- 回归 87 套件/639 用例全绿
|
2026-10-19 11:27:12 +08:00 |
|
xcbyy
|
c58449ddae
|
fix(subscribe): 模板ID按微信字符集规范化,根治「看起来一样却比对不上/40037」
- 新增 normalizeTemplateId:仅保留 [A-Za-z0-9_-],剔除零宽空格(U+200B)等 trim() 无法清除的不可见字符
- 模板比对、真实下发(notifyBySubscribe)、测试推送、下发小程序的模板ID统一走规范化
- 后台保存 message_template_rules 时落库前规范化,避免脏值再次进入
- 回归 87 套件/638 用例全绿;冒烟 5/5 验证:脏值落库被清洗、下发值无不可见字符
|
2026-10-19 11:18:12 +08:00 |
|