Commit Graph
14 Commits
Author SHA1 Message Date
Drsakura 13d67c804f feat: 多用户权限体系、AI 助手、SKU 目录与合同清洗(开源准备)
本地长期开发成果的整体入库快照,包含后端鉴权/权限、AI 接入、合同解析、
SKU 目录等模块,以及前端相应页面与样式改版。

后端
- 新增鉴权与会话:scrypt 密码哈希、HttpOnly cookie(happy_sid)、登录失败锁定
- 新增「角色 → 权限组 → 权限点」三级权限模型与审计日志
- 新增 AI 提供商接入与预设(兼容 OpenAI 协议,内置 DeepSeek / 通义千问等)
- 新增合同解析、合同文件保留策略、客户归属与访问控制
- 新增 SKU 目录、组织品牌、新客开发、系统日志等路由

前端
- 新增登录页与用户 / 权限组 / 系统日志管理页
- 新增客户详情、客户公海、询盘详情、报价编辑器、合同清洗中心
- 新增 AI 配置、组织品牌、包装参数、SKU 选择器等组件
- 新增英文大写金额、未保存改动拦截、抽屉与骨架屏
- 新增 stage1 样式层;产品、供应商、订单等页面改版
- EmbeddedSku 页面并入现有产品体系后删除

开源准备
- 新增 AGPL-3.0 LICENSE
- README:移除未启用的 SQLCipher 加密声明(改为如实的「已知限制」)、
  补充环境变量说明、许可证由「私有项目」改为 AGPL-3.0
- 移除历史遗留的空文件 _index_backup.txt
- 文档中的项目路径更新为 happy-export
2026-09-17 14:53:02 +08:00
Drsakura 436519e0a6 feat(embed): 合同导入与工作台融成一体(主题/字体/配色/滚动全对齐)
深色外壳里嵌一张米白纸、外加两层滚动条,是「没浑然一体」的根源:

- 宿主把当前主题下的设计令牌 postMessage 给嵌入页(跨源读不到对方的
  CSS 变量),两边共用同一套配色/字体/圆角;切主题即时跟随,不用刷新
  (src 里的 theme 只作首帧初值,避免换主题触发 iframe 重载白闪)
- 收起嵌入页里重复的部件:自带侧栏、顶栏指标条(货号总数/供应商/待核对)、
  右下角「问一句」悬浮球(宿主已有小皮)
- 只留一层滚动:路由区固定为视口高度,滚动交给 iframe 内部
- 输入框沿用宿主的「无方框」规则:去掉描边与焦点光环,改底色区分
- 页面头去掉「新窗口打开」(打开的是裸 SKU 页),刷新改成图标按钮
- 令牌名对不上时会告警,免得嵌入页悄悄回落到旧配色
2026-09-11 12:53:22 +08:00
Drsakura fa4dd6482b feat(ui): 助手正名「小皮」+ 全站输入框去掉描边方框
助手改名
- 「小屁」→「小皮」(AI 浮窗标题/按钮/占位文案/工作台引导语 + 注释)

输入框一律无方框(靠底色区分,聚焦换成 primary 底色)
- 根因一:全局选择器写成 input[type="text"] 列表,AI 浮窗输入框没写 type
  完全没吃到样式,渲染成浏览器默认的 2px 灰直角框(就是「丑出天际」那个),
  顺手补上 input:not([type]) 兜底 + 给该输入框补 type="text"
- 根因二:聚焦时同时叠了 input[type] 的 1px 描边 + 3px 光环,以及
  :focus-visible 的 2px 外描边(鼠标点文本框也会命中),一共三层方框
- 覆盖范围:全局 form 控件、顶栏搜索、汇率金额、备忘录添加行、
  日历添加日程、跳转浮层年月输入框、设置里 API Key / 下拉
2026-09-11 11:45:20 +08:00
Drsakura 850abe9327 feat(calendar): 跳转浮层年月改为直接输入,回车快速跳转
- 点开 🗓 后的浮层标题由「弹出拨盘」改为输入框:前 4 位是年、后 1~2 位是月,
  只填 4 位则沿用当前月;回车跳转并关闭编辑态,Esc 取消且不关浮层
- 非数字自动过滤、上限 6 位;月越界或年份越界标红提示且保留焦点
- 进入编辑态时把「2026年9月」换成「202609」并全选,两种触发(鼠标按下/聚焦)都稳
- 工具条上的年月文字仍保留 iOS 拨盘入口
2026-09-11 11:22:04 +08:00
Drsakura 0453a49e4e feat(calendar): 年月拨盘(iOS 闹钟式滚轮)替换工具条的月份文字
- 新增 components/MonthYearWheel.jsx:年、月两列滚轮
  · scroll-snap 吸附 + 指针按住拖动 + 鼠标滚轮/触摸板,停稳 140ms 后落值
  · 滚动过程中实时算居中行,中间行放大加粗高亮、相邻行缩小淡出(像苹果拨盘)
  · 点某一行直接跳到该行;「回到今天」一键回当月
  · 年份范围默认前后 12/20 年,两侧夹在视口内,下方放不下自动翻到上方
- 两个入口:
  · 工具条上的「2026年9月」由 <strong> 换成按钮,点击弹出拨盘,再点一次收起
  · 日期跳转浮层里的标题同样可点:点击后浮层收起、同位弹出拨盘
- 拨盘选完年月,主日历与跳转浮层同步过去

修掉一个竞态:两列在同一帧内先后停稳时,后一次会读到渲染期闭包里的旧值,
把前一次的结果覆盖(滚到 2028年12月 会退回 2026年12月)。
改为组件内用 ref 保存最新年月、每次落值先更新 ref 再回调。

顺带修正跳转浮层标题多出来的一个右花括号。
2026-09-11 11:06:36 +08:00
Drsakura 4c3ec995b6 feat(workspace): 日历再瘦身 + 右侧面板等高填满 + 日期跳转按钮 + 小屁浮窗化
日历
- 单元格 72→60px,日号 19→17px、字号 11→10px,事件条与周标同步收紧,
  标题区 padding 与提示文案一起压小
- 工具条右边的「月」按钮删掉,换成日历小图标按钮:悬浮/展开变蓝(primary 实底),
  点击弹出迷你月历(自带年月切换 + 回到今天),点某天即跳月并选中该日

右侧面板
- 「今日 to do」与「待办事项」改成按列高 58/42 平分,列表自身 flex 撑满并可滚动;
  之前待办被挤到底部只剩一条空文案,现在两块都填满整列
- 跳转浮层 z-index 82,压过小屁浮窗(78);设置遮罩提到 90,保证仍是最高层

AI 助手 → 小屁
- 全屏遮罩 + 右侧整条抽屉删掉,改成右上角 348px 宽浮动小窗:
  可拖动(位置记 localStorage,越界自动夹回视口)、可最小化成小条、双击标题栏切换
- App.jsx 不再因为小屁打开而 inert 主界面(只有设置才是模态),
  所以可以一边让小屁干活一边自己点系统:实测开着窗导航、选日期、填备忘录都正常
- 文案全部改名小屁,顶栏按钮、面板标题、工作台摘要里的引导语一并更新

顺手
- 顶栏搜索的 ⌘K 提示块加 nowrap,1024 宽度下不再折成两行
2026-09-10 23:56:52 +08:00
Drsakura b9d6296591 feat(workspace): 日历瘦身 + 右侧「今日 to do / 选中日待办」双面板
日历
- 行高 92→72px,行程条只留 2 条(超出折成 +N 并压缩成小 chip),标题区与周标同步收窄
- 选中态重做:去掉了原来生硬的 2px 内描边,改成单元格内嵌圆角环 + 淡入缩放动画;
  「今天」改为日号描边圆环,与「选中」的实心日号区分开
- 侧栏宽度不足时(≤1200px)自动改为上下排布

右侧新增两块
- 「今日 to do」:备忘录性质。底部常驻加号输入框,回车即建;建完前面出现勾选框,
  勾选后划线变淡并沉到已完成组末尾(输入框始终在最后一行);可取消勾选回到未完成组;
  悬浮出现删除按钮;列表过长可滚动,勾选后自动滚进视野
- 「待办事项」:显示日历上选中那天的日程与节日(未选中时默认今天),
  带优先级点与说明,右上角「新建」直接为该日添加日程
- 原左栏重复的 [TASK QUEUE] 面板移到这里后删除,避免同名面板出现两次

后端
- todos 增加 list 列(schedule 日历日程 / memo 备忘录待办),老库启动时自动补列
- GET /api/todos 支持 list=memo;POST 支持 list,memo 不写日期
- 新增 PATCH /api/todos/:id(勾选完成/取消、改标题等)与 DELETE /api/todos/:id
2026-09-10 23:35:20 +08:00
Drsakura 33dc71f8c3 feat(calendar): 工作日历选中态 + 再次单击添加日程 + 日程/节日悬浮详情
- 单击日期选中(主题色底 + 内描边环),再次单击同一日期弹出「添加日程」浮层
- 浮层支持标题 / 优先级 / 备注,保存后写库并即时刷新日历与工作台待办
- 悬浮日程或节日显示详情小窗:日程含日期/优先级/状态/客户/备注,
  节日含外贸视角的具体说明(对出货、订舱、客户响应的影响)
- 节日补充春节(2025–2035 逐年查表)、感恩节与黑色星期五
- 超过 3 项时折叠为 +N,悬浮查看剩余条目
- 后端新增 GET /api/todos(按日期范围)与 POST /api/todos
- 浮层用 fixed 定位 + 视口翻转/夹取,渲染后按真实高度校正一次;
  滚动跟随锚点;Esc 与点击外部关闭;日期格支持键盘 Enter/Space
2026-09-10 23:16:29 +08:00
Drsakura 46a963e23d feat(header): 顶栏时钟可切时区 + 汇率计算器;工作台移除运行日期
1) 工作台
   - 删掉欢迎区右侧的「运行日期」卡片,含 luxury.css 里对应样式与窄屏残留

2) 顶栏时钟(仿小满 CRM)
   - 新增 TimeZoneClock:时钟图标 +「东八区:北京,上海 ⌄」+ 大号时间(20px 等宽,
     tabular-nums 保证秒位不跳动),下方小字带日期
   - 点整块展开时区列表,23 个时区由西向东排列,每行右侧实时显示该地时间与 UTC 偏移
   - 时区用 IANA 名(Europe/London 等)而非写死偏移,夏令时自动正确;
     打开列表会自动滚到当前选中项;选择记 localStorage('happy.clockZone')
   - 新增 src/timezones.js 集中时区表与格式化工具

3) 顶栏汇率计算器
   - 新增 FxCalculator:计算器图标点开浮层,默认 USD→CNY
   - 左右两侧各带可搜索的币种下拉(币种来自接口返回的全部币种,常用币种排前),
     中间一键互换;任一框输入另一框实时反算;显示主汇率与倒数汇率
   - 换币种时锁住所改那一侧的数字(与 Google 换算一致)
   - 金额按数量级自动取精度(USD→VND 与 CNY→USD 都不出现一堆无意义的零)
   - 新增 src/currencies.js(币种中文名 + 排序 + 交叉汇率与格式化)

4) 后端汇率接口
   - 新增 /api/fx/rates:以 USD 为基准返回全量汇率,前端据此算任意币种交叉汇率
   - 主源 open.er-api.com(166 币种),备源 frankfurter.app(欧洲央行);
     内存 + 落盘缓存 1 小时,并发请求只发一次网络
   - 网络不可用时依次回退「上次成功的数据」→「内置离线汇率表」,
     并在响应里用 source/warning 标注,前端明确提示数据来源

5) 顶栏排布
   - 时钟变宽后中等屏会溢出,新增 ≤1440px 断点收紧留白/品牌区/搜索框;
     搜索框允许收缩;1280/1100/980/700 各档实测无横向溢出
   - 移动端(≤680px)汇率浮层改用固定定位铺满两侧,避免左侧被裁

6) .gitignore
   - backend/data/ 整体忽略(trade.db、fx-cache.json 等全是运行时产物)
2026-09-10 17:44:36 +08:00
Drsakura 1edf5ac995 feat(nav): 侧栏高对比度 + 顶栏已打开页面标签 + 折叠态只留日夜切换 + 换明月图标
1) 侧边栏对比度
   - 新增 --sb-* 专属色板(固定深色底,不随日夜主题翻转),文字 #c3d7e3、
     hover 纯白、选中纯白 + 品牌色强调条 + 内描边,参考 GoodJob 的 Command Deck
   - 原过渡曲线(--transition-fast/base)保持不变
   - luxury.css 里把侧栏刷回浅底的覆盖一并改为同一套色板

2) 顶栏「已打开页面」标签
   - 新增 src/navigation.js:NAV_GROUPS 与 PAGE_LABELS 单点维护,App 与顶栏共用
   - GlobalHeader 用 useLocation 自动登记访问过的页面,工作台恒定置顶且不可关闭,
     其余按最近使用排序,可单独关闭,最多 10 个,落 localStorage(happy.openTabs)
   - 关掉当前标签会退到剩下的最近一个,没有则回工作台

3) 折叠态页脚
   - .sidebar.collapsed .settings-btn 隐藏,76px 宽度下只留一个日夜切换按钮

4) 明月图标
   - MoonIcon → MoonStarsIcon,造型取自 igoutu.cn/icon/101343/moon-and-stars,
     重绘为矢量(月牙 = 两段圆弧相减,两枚凹边圆角四角星),走 currentColor 随主题变色
   - 源图存 design-refs/(已忽略,不入库)

5) 顶栏排布修正
   - 标签条加入后头部变挤,收窄品牌区/搜索框,按钮加 nowrap 防止文字折行
   - ≤1280px 隐藏标签条
2026-09-10 17:25:38 +08:00
Drsakura d650ff9c4d refactor(layout): 顶栏横跨整宽并压在侧边栏之上,侧栏去标题、按钮移到工作台右侧
- App.jsx: 新增 .app-shell / .app-body 两层结构,GlobalHeader 提到侧边栏之前;
  inert 上移到 .app-shell,行为不变
- 侧边栏删除带 happy出口通 的 .sidebar-header(logo 与名字统一交给顶栏,且更大)
- 折叠/展开按钮从侧栏标题栏移到「工作台」右侧(.sidebar-top),收起时自动落到工作台下方
- 新增 --header-height 变量(80px,≤680px 时 62px),顶栏 min-height 与侧栏 sticky top/
  height、route-content min-height 全部据此计算
- 移除已失效的 .sidebar-header 规则(含 ≤900px 媒体查询)
2026-09-10 17:04:05 +08:00
Drsakura 47f6214056 feat: 品牌标识用云+数据库矢量图标(favicon + 页眉品牌标)
- Icons.jsx 新增 CloudDbIcon:照 icons8-云 重绘为矢量,左云随主题色、右圆柱用品牌蓝
- GlobalHeader 品牌区前置该图标,原「系统在线」绿点改为挂在其右下角
- index.html 增加 rel=icon / mask-icon 指向 public/favicon.svg
- luxury.css 补品牌样式,并让 :not() 选择器排除 .brand-mark 避免样式误伤
2026-09-10 16:58:52 +08:00
Drsakura e4537d5bf0 feat: 设置页新增「系统与更新」,按 GitHub 版本号检查更新
- 顶层 package.json 作为应用版本唯一来源(happy-export v1.0.0)
- backend/lib/updater.js:查 GitHub Release(优先)或 tag,与本机版本做 semver 比对
- backend/routes/system.js:GET /api/system/info、GET /api/system/check-update(30s 缓存)
- /api/health 版本号改为读真实版本
- 设置页新增第 4 个分类:当前版本 / 更新源仓库 / 检查更新(含更新说明折叠)
- 新增 RefreshIcon
2026-09-10 16:23:42 +08:00
Drsakura d8df2c3960 chore: happy 出口通初始提交(前端 React + 后端 Express,采购管理已原生化) 2026-09-10 16:16:59 +08:00