Commit Graph
43 Commits
Author SHA1 Message Date
yeuimu d625b40873 fix(admin): merge-candidates by SKU/family; config dialog merge block always shown; cfg badge adjacency
- 修正合并同名候选匹配:此前用名称 3 段组键(含工艺段),工艺写法不同的
  同款(如 光板不打印 vs 单面印花(前印))全部漏配导致候选为空、合并同名
  区块被 v-if 隐藏 —— 用户看到的"checkbox 和搜索框被吞"即此因。
  改为 族归属精确匹配 或 款号(名称第 2 段,如 BRTF004)一致,全局跨分类;
  区块常显,无候选时空态提示
- 修左树「N 个配置」徽标错位:good-name-col 改 flex 布局,徽标紧贴名称
- 验证:admin typecheck + 22/22 + 构建绿;DB 实测 BRTF004 光板链接候选池
  恢复(单面印花(前印),同族 857)
2026-08-29 02:16:35 +08:00
yeuimu 6f2d836ef5 fix(admin): one row per family on left tree; restore right-tree config entry
按用户反馈调整上一批优化:
- 左树撤回族组展开层(虚线层+重复名称行):改为一族只显示一行(排序最前的
  代表商品),行内「N 个配置」徽标悬浮列出该族全部配置(名称/国家·分类/打开
  按钮),不再有额外层级与重复名称
- 右树恢复配置入口:撤回「族已配置拦截」,本链接未单独建商品即显示「配置」
  按钮(含族已配置情形,供调整归族/重新配置),拖拽路径同步解除拦截
- 国家模式拖拽排序回退为分组内简单排序(族组节点已不存在)
- 文档同步更新徽标/入口语义

验证:admin typecheck + 22/22 + 构建绿;浏览器实测美国分组 25 行一族一行、
「8 个配置」徽标悬浮列表可打开、国内工厂深层成族链接显示「配置」按钮
2026-08-29 01:53:09 +08:00
yeuimu 5e8183c220 feat(admin): family-folded left tree, toolbar regroup, sync log humanize
视觉走查驱动的后台优化(feature/admin-ui-polish-dev,确认后再合并):
- 左树(国家/品类模式)同款多配置折叠为一行族组节点:代表名 + "N 个配置"
  徽标,展开看各行;locateInLeftTree 沿父链展开保证定位有效;国家模式
  拖拽排序适配族嵌套(同容器内排序,按折叠后展示顺序保序重分配优先级)
- 工具栏分区重排:模式切换(品类/国家/全局)移至最左,筛选组居中,
  新增自定义商品靠右,消除 1680 宽下的折行错乱
- 商品行属性小字/国家徽标颜色加深提升对比度
- 右树原产品行加拖拽提示 title
- 数据同步日志人话化:inserted/updated/total/delisted 等报文渲染为
  "新增 0 · 更新 536 · 共计 536",原始报文进 tooltip
- 计划文档 plans/feature/admin-ui-polish-feature.md(含一项误报修正:
  右树 29/3 计数为截图裁切误读,实际 29/33 无 bug)

验证:admin typecheck + 22/22 + 构建绿;浏览器实机复拍国家模式折叠、
族组展开、同步页文案均生效
2026-08-28 23:22:04 +08:00
yeuimu 0e451d07e6 fix(admin): drag-to-reorder goods inside country groups
国家模式左树商品节点支持拖拽排序:行内 before/after 指示线,落点即保存。
优先级采用保序重排(该国家现有优先级集合不变、按新顺序重新分配),
尽量少扰动全局/品类维度的既有排序;跨国家拖动不支持(商品归属固定)。
2026-08-28 21:37:27 +08:00
yeuimu fdfe435ecd fix(admin): config dialog merge candidates search globally by name group
合并同名候选不再局限于当前分类节点:collectSiblings 改为按名称 3 段组键
(sameOriginGroup)遍历整棵右树收集同款链接(含已配置,勾选归族幂等),
跨分类的同款链接(如 BRTF004 分布在多个分类组)也能勾选归族
2026-08-28 20:04:29 +08:00
yeuimu 1e07c62fc8 feat(admin): country drag-sort + always-available member detail sync
- Country 加 sort_order(默认 0 保持 id 序);PATCH /countries/sort 批量保存
  顺序(对齐 /tags/sort 模式);findAll 与公开 /public/countries 均按
  sortOrder 排序
- CountriesView 表格改为可拖拽行列表:拖动松开即全量保存新顺序,失败回滚
- 商品编辑弹窗成员展开面板:同步详情按钮常驻(已同步显示 重新同步详情),
  不再只在未同步态出现
- goods.service.spec 的 FamilyRecomputeService mock 补齐 syncFamilyTags 等
  方法(全量并行时其他套件的扫名归族会把本套件夹具收进族,create/update
  会调用到,mock 缺方法导致偶发 TypeError)
- api 164/164、admin typecheck+22/22+构建全绿
2026-08-28 20:00:56 +08:00
yeuimu fe6ab3825d fix(admin): family-aware right-tree badges; flatten union size-chart cells
- 右树徽标/定位/配置按钮改按族语义:族内任一链接已配置 → 全族显示绿色
  已配置(本链接未单独建商品时标题注明并入该款),配置入口在全族未配置时
  才出现;拖拽已配置族链接配置时拦截提示(公开契约一族一款,重复商品官网
  不可见);分组头计数与仅未配置筛选同步族感知(AUTM003/DG120 场景)
- 编辑弹窗族级尺码表把 measurements 数组摊平成列键(与成员级渲染一致),
  修复列头在、格子全空的问题
2026-08-28 19:16:15 +08:00
yeuimu 8a052773cd feat(public): family-first contract — goodId=familyId, strict 5-dim price matrix
公开契约族化(前端只需知道款号/族):
- GET /public/goods 一族一条(goodId=族ID,price=族起价,分页作用于分组后);
  无族商品(自定义)不进任何公开端点(列表/首页/分类树/标签统计)
- GET /public/goods/:goodId 仅认族 ID;公共字段取代表 Good,变体=全体成员并集,
  尺码表/包装规格=族物化并集;旧 SDS 链接 ID 寻址 404
- priceMatrix 严格五维:尺码×颜色×印花数量×工艺×物流;维度来源改为链接级
  标签(人工接管按人工标签),弃用原始 craftLabel;CUSTOM 成员尊重显式标签
- 名称派生补裸「单面/双面」写法(直喷双面→双面印花+直喷,18 条存量链接修复)
- family_price_overrides 加 print_count 列(五键唯一),PUT/DELETE/校验五键化
- admin 编辑弹窗矩阵消费适配(SKU 列直读 printCount,成员格子三维匹配,
  改价 payload 带 printCount)
- 存量 339 族已全量重算;api 162/162、admin 22/22、双端构建绿
2026-08-28 18:43:30 +08:00
yeuimu 1ef82c4c14 fix(admin): proxy /api/docs without prefix strip so Swagger UI works through vite dev server 2026-08-28 17:43:41 +08:00
yeuimu f07e843130 fix(admin): move family union tabs to the bottom of edit dialog 2026-08-28 17:37:58 +08:00
yeuimu c7e6c35fbf feat(admin): family-level size/package/SKU union tabs in edit dialog; searchable merge-sibling list in config dialog 2026-08-28 17:26:41 +08:00
yeuimu 7c85f7fe9f fix(admin): config dialog lists all same-category sibling links (incl. configured); drop merge tip text 2026-08-28 17:11:36 +08:00
yeuimu c2d50c9fa3 fix(admin): restore session via /auth/me in router guard (refresh no longer logs out); simplify member price table (no title/source/action columns) 2026-08-28 17:02:25 +08:00
yeuimu f28f51155f feat(goods): per-member detail tabs in edit dialog; revert right-tree to raw names; split configured/family badges; add GET /origin-goods/:id 2026-08-28 16:55:07 +08:00
yeuimu 10197c47a8 refactor(admin): split GoodsView into dialog components; fix(GoodsView): raw member names, no primary badges, member price grid; feat(tag): 光板 maps to 不打印 2026-08-28 16:40:48 +08:00
yeuimu 6f22a6fd1f feat(admin): expandable family members with per-link tag config + SKU pricing dims columns 2026-08-28 16:00:46 +08:00
yeuimu 1128167aef feat(admin): family-aware goods view - auto tags readonly, clean link names, config badges, locate highlight 2026-08-28 15:33:11 +08:00
yeuimu eedfbb344e feat(product-family): auto-derive logistics/craft tags from family members 2026-08-28 14:57:25 +08:00
yeuimu 353e51e871 revert(admin): restore original layout, replace primary/secondary source UI with family members 2026-08-28 14:35:34 +08:00
yeuimu 7b17fff86f fix(admin): fail loudly when dev port 5173 is occupied 2026-08-28 14:21:37 +08:00
yeuimu 4eadb67c36 feat(product-family): replace legacy good merge with family mechanism in config view and public detail 2026-08-28 14:14:58 +08:00
yeuimu fd7ca5d53f feat(admin): goods view family badges and sibling matching 2026-08-28 13:29:54 +08:00
yeuimu 07f3134f79 feat(admin): product family management tab 2026-08-28 13:28:37 +08:00
yeuimu dcd2b235b9 feat(admin): family match util 2026-08-28 13:25:31 +08:00
yeuimu c492469d70 feat(admin): product families api client and types 2026-08-28 13:25:10 +08:00
yeuimu 8233dda07a fix(admin): initial goods load also uses pageSize 1000 2026-08-28 09:49:40 +08:00
yeuimu b3bd10de06 fix(admin): load all goods in left tree (pageSize 1000) so low-priority new goods are searchable 2026-08-28 09:31:02 +08:00
yeuimu ac29a0c7bf feat(admin): show merged count badge on good nodes 2026-08-27 18:45:51 +08:00
yeuimu ac3a39f40d feat(admin): manage merged origin goods in good edit modal 2026-08-27 18:43:30 +08:00
yeuimu 491e74b905 feat(admin): add origin name grouping utils with vitest coverage 2026-08-27 18:40:22 +08:00
yeuimu 0aa6cbf1d9 feat(admin): suggest and merge sibling origin goods in config modal 2026-08-27 18:40:13 +08:00
yeuimu 697b82a64b fix(admin): resolve pre-existing template type errors blocking build 2026-08-27 18:40:08 +08:00
yeuimu 6c61a4e871 feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma
  binaryTargets for openssl 3.0
- nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal
  cron, http->https redirect
- prisma: add origin_goods.delisted migration, sync missing schema
  (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz
- api: CORS wildcard reflection, helmet CORP cross-origin, price
  backfill in persistProductDetail, categoryIcon ancestor fallback,
  mediaByColor per-color gallery in public goods detail
- admin: /admin base path (vite + router)
- import-data.mjs: udt_name casting, serial sequence advance fix
2026-08-26 14:23:09 +08:00
yeuimu be0b90e68f feat(security): HttpOnly cookie sessions, token revocation, and RBAC
- Add User.role (enum Role/ADMIN) and User.tokenVersion with migration
- Login now issues short-lived access token (30m default) + 7d refresh
  token, both embedding tokenVersion and a typ discriminator
- Tokens delivered via HttpOnly SameSite cookies (ir_at, ir_rt scoped
  to /auth); refresh token never leaves the cookie
- New endpoints: POST /auth/refresh (rotation), GET /auth/me,
  POST /auth/logout (bumps tokenVersion, revoking all tokens)
- JWT strategy accepts bearer or cookie, rejects refresh tokens, and
  verifies tokenVersion + user existence on every request
- Global RolesGuard: authenticated routes require ADMIN unless widened
  via @Roles(...)
- Admin SPA: session fully cookie-based, no token in localStorage;
  router guard restores session via /auth/me; axios auto-refreshes once
  on 401; stale localStorage keys cleaned up
2026-08-22 12:04:56 +08:00
yeuimu 9ed569f5bc fix(admin): simplify product forms 2026-08-21 14:54:08 +08:00
yeuimu b04623ebdd feat(goods): add editable custom products 2026-08-21 14:45:42 +08:00
yeuimu a4151607c5 fix(sync): hydrate all origin product details 2026-08-21 14:05:15 +08:00
yeuimu a43353aa98 fix(dev): support admin access over LAN 2026-08-21 10:53:47 +08:00
yeuimu 6e5f7edbb7 chore: update admin generated types and env ignore 2026-08-21 10:39:23 +08:00
yeuimu d375df810d feat(admin): manage and sync product details 2026-08-21 10:18:57 +08:00
yeuimu fcbf8bb494 chore: stop tracking env files (.env, .env.development)
Credentials and per-environment config should not be committed.
Files stay on disk locally; .gitignore now covers .env.development.
2026-08-20 18:44:44 +08:00
yeuimu 79fabd85f7 feat(product-center): implement Figma-designed UI, upload module, and website tests
- Redesign website homepage & product-center per Figma (fonts, logos, hero/footer/customer cases)
- Add API upload module (multer) with static serving for uploads/public assets
- Add OriginGood.delisted flag and SDS request retry logic
- Add admin ImageUpload component and goods import/upload flows
- Add vitest suite for website components and composables (32 tests)
- Add skills, docs, plans and PRODUCT.md
2026-08-20 14:32:03 +08:00
yeuimu 7e04877bb6 chore: migrate to pnpm workspaces monorepo with Turborepo
- Restructure directories: apps/api, apps/admin, apps/website
- Add root pnpm-workspace.yaml, turbo.json, .prettierrc, .gitignore
- Rename packages to @inkreach/api, @inkreach/admin, @inkreach/website
- Add shared packages: packages/tsconfig, packages/shared-types
- Add pnpm.onlyBuiltDependencies for native builds
- Update docs: README.md, structs.md
- All three projects build successfully
2026-07-11 16:54:05 +08:00