Drsakura
1ffcc1ea07
feat: add admin web updates and verified username changes
...
Add isolated update jobs with database backups, progress logs and application rollback. Remove default account hints and prevent default admin recreation after renaming.
Enforce customer and order search scopes, secure session cookies, fix quotation rounding and amount wording, and update backend dependencies. Add API and deployment regression coverage.
2026-10-22 17:24:19 +08:00
Drsakura and Claude Opus 5
dc607e4ea3
perf(static): 带 hash 的前端资源缓存一年,index.html 不缓存
...
线上实测 /assets/index-u1PUen4p.js 返回的是 express.static 的默认
Cache-Control: public, max-age=0 —— 每开一次页面就要为每个 JS/CSS 跑一趟
回源校验。而这些文件名里本来就带内容 hash,内容一变文件名就变。
分两档:
assets/* max-age=31536000, immutable(连 304 都不用问)
index.html no-cache
index.html 必须不缓存:它文件名固定、里面引用的才是带 hash 的资源名。
缓存住的话发了新版用户还拿着旧 index.html、指向旧资源,等于白更新。
SPA fallback 那条单独加了一遍 no-cache —— 它走 sendFile,不经过
express.static 的 setHeaders,/orders 这类深链拿到的同样是 index.html。
Co-Authored-By: Claude Opus 5 <[email protected] >
2026-10-22 16:17:44 +08:00
Drsakura and Claude Opus 5
f32a2daaef
feat(order): 订单支出台账(快递费/吊卡费等杂费)
...
订单上原本只有「卖给客户多少钱」,而一张单真实花出去的还有寄样品的快递费、
印吊卡的费用、商检报关拖车。不记下来就算不出这单赚没赚 —— 小单子几百块
杂费能把毛利吃掉一截。
· 新表 order_expenses,一张订单挂多笔:类型/金额/币种/日期/收款方/单号/
已付未付/备注。单独成表而不是往 orders 加列,因为杂费是多笔不定项的,
寄三次样品就是三条快递费,各有单号;塞进 orders 只能存一个合计,事后
对不出「这 800 块是哪来的」。
· 跨币种强制填汇率并存快照。杂费基本是人民币、订单常是美元;不存快照的话
汇率一变历史订单毛利跟着变,账永远对不上。同币种强制按 1,防止前端传个
7.2 把美元支出又乘一遍。
· 新权限点 order.expense,不复用 order.edit。掏钱寄样品的是销售业务员,
而销售业务组只有 order.view —— 挂在 order.edit 上要么他记不了账,要么
为了让他记账得把「改订单金额」一起给他。启动时 syncNewPermissions()
会自动把这个新点补给四个默认组。
· 订单列表加「杂费」列(合计 + 未付)。SUM 外层再 ROUND 一次:不加会漏出
348.15999999999997 这种浮点尾巴直接显示在页面上。
· 金额逐行取两位再相加,保证明细几行加起来等于合计。
Co-Authored-By: Claude Opus 5 <[email protected] >
2026-10-22 15:22:56 +08:00
Drsakura and Claude Opus 5
3e9fd2dc97
fix(customer): 联系人新增与跟进编辑补上归属校验
...
两个端点都只有 requirePermission('customer.edit'),而那只说明「这个人有权
编辑客户」,没说明「有权编辑**这一条**客户」。实测一个 sales_rep 账号:
GET /api/customers/4 → 404(读是隔离的)
POST /api/customers/4/contacts → 201(写进去了)
PATCH /api/customers/4/follow-ups/12 → 200
把「客户确认 3000 套订单」改成了「客户取消了订单」
也就是说一个销售能往看不见的客户里插联系人(还能把自己设成主联系人),
还能改写另一个销售客户的跟进历史。
两处都有对照组:紧挨着的 PATCH /contacts 和 POST /follow-ups 一直有这道
检查,所以是漏了而不是设计如此。补上后重放两个利用都是 403,归属人自己
仍然 201/200。
Co-Authored-By: Claude Opus 5 <[email protected] >
2026-10-22 15:22:15 +08:00
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
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
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