Files
websopy-taro/.workbuddy/memory/MEMORY.md
T
gxwebsoft 9eb6622eee refactor(official): 使用演示数据兜底官网内容展示
- 在关于我们页补充企业优势和联系方式演示数据展示
- 资讯列表页增加分类标签,实现按分类筛选资讯
- 文章详情页新增相关推荐文章展示逻辑
- 主页使用演示数据兜底导航、Banner、核心业务、公司简介和文章列表
- 各页面均优化站点信息使用,优先展示真实数据,缺失时使用演示数据
- 留言页增加公司联系信息展示,提升体验
- 个人中心页支持分享官网,展示演示数据防止空白
- 主页Banner支持无图时使用渐变背景和文字占位
- 统一使用演示数据,保证页面无空白,提升整体稳定性和用户体验
2026-08-12 19:23:17 +08:00

9.2 KiB
Raw Blame History

项目长期记忆(websopy-taro

核心约定

开发者身份的表示方式

  • 开发者身份主校验位 = sys_user.is_developer 布尔位(数据库列 is_developer),登录态 MainController.loginByDeveloperSms 校验它才允许开发者登录。
  • 后端仓库:/Users/gxwebsoft/JAVA/com.gxwebsoft.core(单 Maven 模块,包名 com.gxwebsoft 分包)。
  • 标记接口:PUT /api/system/user/developer/{userId}UserController.setDeveloperUserService.markAsDeveloper),成功后经 syncMessageProducer 同步 websopy。
  • 前端调用:@/api/system/usersetUserDeveloper(userId)
  • vip-review 审核通过流程(用户 2026-07-22 最终确认,2026-07-23 补充):前端 handleApprove 依次调 ① updateShopDealerApply(applyStatus=20);② setUserDeveloper(userId)(不碰 sys_user_role);③ addShopStoreUser——在当前门店下给申请人补一条 shop_store_user(店员)记录(userId=申请人, storeId=审核店员所属门店, tenantId=同店员, isDelete=0)。后端 markAsDeveloper 做两件事:① 把 sys_user.is_developer1;② 替换用户角色为 developer——roleService.getByRoleCode(roleCode=developer, tenantId=用户租户) 找到角色 → 删掉该用户现有 sys_user_role → 只绑定 developer 这一个角色,不与原角色并存(角色替换包 try/catch,失败不影响 isDeveloper 落库)。即"升级为开发者 = 单角色 developer + isDeveloper 标记位 + 一条门店店员记录",不是新增第二个角色。审核店员的 storeId/tenantId 来自 getMyClerk() 返回值(存于 clerkStoreId/clerkTenantId state)。
  • 注意:前端 vip-review / vip-upgrade 等页面的变量名仍残留 VIP_ROLE_*pendingVipCountdealerPrice 等旧标识符(仅文案改成了「开发者」),后端角色与缓存 key 仍对应这些旧名,重命名需谨慎。

超级管理员(isSuperAdmin=true)访问门槛(2026-07-23 确认)

  • 用户对象字段 isSuperAdmin(user as any)?.isSuperAdmin === true,布尔 true 才算),前端此前未引用,由后端 sys_user 返回。
  • 平台管理pages/admin/index/index)与门店中心pages/store/center/index)两个入口,菜单与首页工作台均只在 isSuperAdmin===true 时显示(原先平台管理是 isAdmin、门店中心是店员 storeInfo)。
  • 门店中心页面已改为「仅超级管理员可进」:移除原 getMyClerk() 店员门槛;非超管访问弹「仅超级管理员可访问」并 navigateBack;超管若同时是店员仍会加载门店信息用于头部,否则头部兜底显示「门店中心」+ 管理员昵称/手机号。
  • 两页都用 useUser()loadinguserLoading)做首屏门卫,避免超管用户未从 storage 解析完时先闪「无访问权限」。注意:pages/store/center 的入口曾依赖 user.tsx 里的 storeInfogetMyClerk),现已不再用 storeInfo 决定菜单可见性。

后端代码风格(com.gxwebsoft.core

  • Controller 继承 BaseController,统一返回 ApiResult(成功 code=0,失败 code=1),用 success()/fail()
  • 「按 userId 置一个标志位」的范式:new User(){{setUserId(); setXxx();}}userService.updateById(u)(参考 updateStatus/updateRecommend/auditUser)。
  • 用户变更后如需同步 websopy,经 syncMessageProducer.sendUserSyncMessage("websopy","UPDATE",user)(在 UserServiceImpl 内,@Autowired(required=false) 注入)。
  • 用户相关代码都在 com.gxwebsoft.common.systementity/service/controller),业务应用数据在 com.gxwebsoft.websopy(无 Controller)。

官网分包 official2026-08-11 落地)

  • 位置 src/official/6 页:index/article/article-detail/about/message/mine+ src/official/components/OfficialTabBar/ArticleCard/SectionTitle),在 src/app.config.tssubpackages 中 root=official。入口在 src/pages/index/index.tsx 搜索栏下的「企业官网」卡片。
  • 数据层统一从 @/api/official 引入(re-export src/api/cms/*)。租户靠 TenantId 请求头。
  • ⚠️ official 页面必须用扁平文件写法src/official/<page>.tsx,同 passport/login.tsx),不要用 <page>/index.tsx 文件夹结构。文件夹写法会让 Taro 把 .js 输出到扁平层、index.json/index.wxml 输出到嵌套层,二者不同目录 → 微信按 official/<page> 找不到 index.json → 整包白屏。2026-08-12 已把 6 个页全部改扁平并修复。
  • ⚠️ 构建官方分包必须用 npm run build:weapp:safe(脚本 scripts/safe-build-weapp.shmv dist 再构建,规避 SAFE_DELETE 守卫打断)。勿用 npm run build:weapp,否则守卫会中断构建导致产物缺失/白屏。演示兜底数据在 src/official/data/demo.tsCMS 有数据自动覆盖)。
  • ⚠️ CMS 请求链路(2026-08-11 修正,勿回退)CMS 接口不能走 shop-api——shop-api.websoft.top/api/cms/... 返回 404shop-api 并未代理 /cms(早前"已代理"的判断是错的)。现全部走独立 https://cms-api.websoft.top/api
    • config/env.js 三环境均有 CMS_API_BASE_URLconfig/app.ts 导出 CmsBaseUrl
    • src/utils/cmsRequest.ts 基于 request 封装、默认 baseUrl=CmsBaseUrlAPI 与 request 一致。
    • src/api/cms/ 下 34 个 index.ts 一律 import cmsRequest新增 CMS 接口必须用 cmsRequest,不要用 request
    • 需在小程序后台把 cms-api.websoft.top 加入 request 合法域名白名单。
    • 批量替换技巧:macOS sedrequest\.(get|post)\( 替换无效,改用 perl -pi -e 's/request\.get/cmsRequest.get/g'
  • CMS 字段陷阱:文章封面 image(非 cover)、摘要 overview(非 summary)、ARTICLE_STATUS.PUBLISHED = 00 才是已发布);留言内容字段是 need(非 content),小程序提交带 source:'miniapp'
  • 微信原生 tabBar 不支持分包页面,官网底部导航是自实现的 OfficialTabBar(用 redirectTo)。
  • 品牌色统一 tokentailwind brand 色阶(600=#185FA5+ app.scss--brand-color/--brand-light。富文本用 .official-rich(定义在 app.scsspx 自动转 rpx)。

⚠️ Taro 构建陷阱:dist 清空触发批量删除保护(2026-08-11)

npm run build:weapp 启动时 Taro 会 emptyOutputDir 清空 dist/,文件数 >50 会被安全删除守卫中断并抛 SAFE_DELETE_BULK_CONFIRM_REQUIRED解决:构建前先 mv dist /tmp/taro-dist-bak/dist-$(date +%s),再执行构建,完成后 rm -rf /tmp/taro-dist-bak

⚠️ Taro 小程序 nutui-react-taro 兼容性陷阱(2026-07-23 确认)

问题@nutui/nutui-react-taro@2.7.4Cell / Price / Divider / Button 等展示类组件,内部用 React.createElement("div", ...) 构建布局。Taro 4 的 babel/swc 没有把这些 div 转成 view,而 dist/base.wxml 里完全没有 <div> 模板,导致这些组件在 weapp 中"空壳化"——外层元素不存在,内层内容(<div>)被丢弃。

症状:组件位置完全空白 / 按钮不可见 / 价格显示为空。Text/View 与 @nutui/icons-react-taro 的图标(Tips/Check/Close/Clock,基于 SVG)渲染正常。

解决办法(最小改动):在该页面用 Taro 原生组件替代:

nutui(不可用) Taro 原生 / 项目自定义
import { Button, Cell, Price, Divider } from '@nutui/nutui-react-taro' import { Button } from '@tarojs/components' + import Price from '@/components/common/Price'
<Cell title="X" description={Y} /> <View className="flex justify-between px-4 py-3 border-b border-gray-100"><Text className="text-gray-600">X</Text><Text className="text-gray-800">{Y}</Text></View>
<Price price={n} size="large" thousands /> <Price price={n} size="large" />用项目自定义 Price,不用 nutui 的)
<Divider /> border-b border-gray-100 替代
<Button type="primary" block loading={x} onClick={y}>...</Button> <Button loading={x} onClick={y} className="flex-1 bg-blue-500 text-white rounded-full border-0">...</Button>className 控制颜色,loading prop 仍然支持)

适用范围判断:项目里其它页面(qr-login、register、passport/forget 等)也用了 nutui 的 Cell/Card/Divider/Button,遇到同类"组件消失"现象时按同样模式替换即可。已修:src/passport/pay/index.tsx(2026-07-23,扫码进入小程序后支付页空白的 bug)。

验证手段:跑 npm run build:weapp 后在 dist/<page>/index.js 里 grep nut-cell|nut-button|nut-divider|nut-price,应为 0grep l.zxTaro Button 在 weapp 编译后的局部变量名)应出现 2 次(取消 + 立即支付)。

已知的 nutui 组件清单(按 2026-07-23 grep 结果):Buttonpassport/pay, passport/login/setting/forget/register, pages/order/*, pages/booking/*, components/common/{FixedButton,EmptyState} 等大量页面;Cellpassport/pay, pages/order/order.tsxDividerpassport/pay, passport/qr-loginPricepassport/pay。修复顺序建议:pay(已修)→ 视觉影响最大的页面 → 批量。