Commit Graph

1054 Commits

Author SHA1 Message Date
mzl92 db0be8486f fix: 公海列表空响应——Util::mask 按字节截断多字节字符串产生非法UTF-8
mask() 用 mb_strlen 量长度却用 substr 按字节截断,俄语等非ASCII
联系方式被拦腰截断产生非法 UTF-8,json_encode 整包失败 → 接口返回
200+空体 → 前端"请求失败"、公海列表打不开(用户72等 hesu 侧必现,
因公海最新数据含俄语询盘)。
修复:substr 改 mb_substr(ASCII 行为不变)。使用处仅公海三字段脱敏。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 11:10:16 +08:00
mzl92 d4deb8855e feat: 审批历史支持PI号筛选,并修复原搜索框后端未实现的问题
- 新增 pi_no 参数:模糊匹配备货单 pi_no -> 单id -> 审批实例biz_id
  (whereHas,todo/history 场景通用)
- 顺带修复:历史页一直发送的 keyword 参数后端从未处理(搜索框是摆设),
  现按 单号/PI号/客户名称 任一模糊匹配;与 pi_no 同传时取交集

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 10:10:31 +08:00
mzl92 694056c8cc fix: 业务主管备货单列表恢复"自己+直属下属"视图
原因:生效角色列表 [1,5,6] 不含业务主管(4),且主管分支被注释,
导致主管落到默认条件只看自己。
修复:intersect 改为 [1,4,5,6],新增主管分支——
salesperson_id IN (自己 + report_to 指向自己的直属下属,一级,
不过滤审批状态即含草稿)。内勤/超管分支优先级不变。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-31 20:39:28 +08:00
mzl92 2de6342058 fix: 备货单车辆附件图片过期打不开——url 改为响应期重签
原因:attachment[].url 存的是上传时生成的带签名OSS地址(默认1小时
有效),过期后 AccessDenied/Request has expired。
修复:OssService 新增 resignAttachmentUrls(),从存量 url(完整签名URL/
未签名URL/纯对象键三种格式)提取对象键重新签名(7天);
detail(prepareVehicleListData)与 show(crm/admin 两控制器 showFormat
的 items)三处响应时统一重签。存储不动,前端无需改。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-26 11:51:40 +08:00
mzl92 2e2188d6e5 feat: 备货单 detail 接口车辆列表补充返回 attachment
prepareVehicleListData 组装每辆车时带上 attachment(模型 array cast
取出即 [{url, original_name}]);同款车按 unique_id 合并的行,
各车附件按 url+文件名并集去重后拼接。show 接口本就带,不动。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-26 11:43:01 +08:00
mzl92 6fa80336a6 feat: 询盘导入改为公平分配——按近10天窗口实际分到数排序(三脚本共用)
新增 InquiryFairAssigner:统计 crm_customer(合塑谷歌/导入/未删/近10天)
中名单内每人的已有条数,按 少者优先 -> 最久未分到优先 -> 名单顺序 排序,
三个导入命令分配前统一调用并打印排序结果(含各人窗口内条数)。
解决:日询盘量少于人数时固定只分给名单前几人的问题;
名单增删(离职/暂停回归)自适应,跨脚本/跨天共享,无额外状态。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 15:40:45 +08:00
mzl92 89b9162f09 fix: 三个询盘导入命令——未分到询盘的用户不再发送空汇总邮件
sendDigests 循环前校验该用户分配条数,为0则跳过并提示
"user N 未分到询盘,不发送"(询盘数少于人数时避免群发空邮件)。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 15:18:16 +08:00
mzl92 d5f05a81a4 feat: 合塑谷歌AI客服询盘导入命令(新询盘建档+分配+邮件)
新命令 inquiry:import-hesu-google-ai:
- 按表头名解析16列(手机/WhatsApp/邮箱/微信/意向/目标国家/预算/
  意向品牌/意向车型/采购数量/采购用途/其他备注/评估理由/完整对话记录等)
- 入库映射:phone/WhatsApp/email、country_id(en/cn忽略大小写匹配,
  匹配不上留空并在dry-run提示)、intended_vehicles=品牌+车型
- contacts=第一个非空联系方式;magnitude=1 银牌;corp=1/channel=4/type=2
- 未对应字段分块拼入 desc_collect 富文本:询盘信息/意向车型/其他备注/
  AI评估/完整对话(对话灰底pre-wrap保留换行),空字段空块自动跳过
- 去重:手机/WhatsApp/邮箱任一重复(库内+文件内)跳过
- --users 轮询分配;汇总邮件 remark=车型+预算;manifest(groups)防重发
- 支持 --dry-run / --no-notify / --notify-only / --only-user

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 14:41:12 +08:00
mzl92 8bf0984a9c feat: 管理后台客户详情同步显示WhatsApp导入截图
crmAdmin 的 getCustomer() 增加与业务端相同的截图键->签名<img>转换
(列表/详情弹窗 v-html 渲染)。注:Excel 导出走 strip_tags,
截图键文本将不再出现在导出文件中(私有图片本也无法嵌入Excel)。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 09:20:24 +08:00
mzl92 705f402c78 feat: 业务端客户详情显示WhatsApp导入截图
getCustomer()(/crm/customer/list 列表与详情弹窗共用)把 desc_collect 中
crm_whatsapp 截图的 OSS 对象键替换为带签名 <img>(7天有效期,每次请求重签)。
键按原文签名(历史双斜杠键的对象即存于该键);前端 v-html 渲染,零改动。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-19 11:05:01 +08:00
mzl92 21c1d6afd9 fix: WhatsApp截图OSS对象键双斜杠(OSS_MAIN_DIR自带尾斜杠)
rtrim 尾斜杠后再拼接,避免 x_server//crm_whatsapp/;已入库记录的键与
OSS对象位置一致不受影响,仅影响后续导入。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-19 10:45:35 +08:00
mzl92 09fdd7a5d5 fix: 询盘导入命令 notify-only 改为从 manifest 读分配结果
问题:--no-notify 建档后号码/邮箱已入库,--notify-only 重新解析时会被
去重逻辑全部判为重复,导致补发邮件变"共 0 条"。
修复:建档成功即把每人分配明细存入 manifest(groups),notify-only 从
manifest 读取补发(无 manifest 则报错提示先跑 --no-notify/完整命令)。
顺带修复重跑场景:无新建档时沿用已有 manifest 结果,不会误发空邮件。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-19 10:14:40 +08:00
mzl92 37e63637a4 feat: 合塑谷歌网站whatsapp询盘导入命令(截图传OSS+建档+分配+邮件)
新命令 inquiry:import-hesu-google-wa:
- 解析 WhatsApp 询盘 Excel(列头:WhatsApp号码/最后留言/截图文件名等)
- 号码归一化(去横线空格);contacts=号码、号码存 WhatsApp 字段、phone/email 空
- 按号码去重:对比库内 crm_customer 的 WhatsApp 与 phone 两列 + 文件内同号只留首条
- 截图按文件名从 --images-dir 找图传 OSS(OSS_MAIN_DIR/crm_whatsapp/),
  对象键写入 desc_collect;缺失/失败不阻断,dry-run 只报数量不上传
- 建档口径:corp_id=1、channel_id=4、type=2、grade=0、magnitude=2、created_at=当前
- --users 轮询分配;汇总邮件复用 InquiryDigestMail,manifest 防重发
- 支持 --dry-run / --no-notify / --notify-only / --only-user 分步执行

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 16:26:31 +08:00
mzl92 3a3ed12fd5 feat: 合塑谷歌网站询盘导入命令(新询盘建档+分配+邮件)
新命令 inquiry:import-hesu-google,处理库外新询盘 Excel:
- 按表头名解析(客户姓名/电话WhatsApp合并列/邮箱/留言内容/产品页链接)
- 建档固定口径:corp_id=1(合塑)、channel_id=4(合塑谷歌)、type=2(导入)、
  grade=0、magnitude=2、created_at=当前时间、code 走模型钩子自动生成
- desc_collect=留言内容+产品页链接,intended_vehicles=从 URL 提取车型 slug
- 去重:电话或邮箱与现有未删除客户重复(含文件内重复)跳过并列清单
- 轮询分配 --users;汇总邮件复用 InquiryDigestMail,manifest 防重发
- 支持 --dry-run / --no-notify / --notify-only / --only-user 分步执行

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 14:40:53 +08:00
mzl92 e096157063 feat: 备货单成交统计报告生成脚本(固定工具)
scripts/stock_deal_report.py:从 Navicat 全库 dump 流式解析 stock_orders/items,
按单据日期统计成交(有备货单即成交),支持单月/区间:
- 剔除草稿/拒绝/作废;初终版(object_id 互指)同月并存只计终版
- 新车/二手车按明细 mileage 判定;国家取清关目的国
- 输出 PDF 报告(月度分布/车型/国家/业务员/详单)+ 详单 CSV
- 每个 dump 自动建解析缓存,重跑秒级

用法:python3 scripts/stock_deal_report.py --year 2026 --month 7
      python3 scripts/stock_deal_report.py --frm 2026-01 --to 2026-06

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 09:49:25 +08:00
mzl92 06b0647fc4 feat: 备货单车辆明细支持 attachment 附件字段
按前端对接文档,stock_order_items 每辆车支持附件 [{url,original_name}]:
- 模型 StockOrderItems:fillable 增加 attachment,新增 $casts=['attachment'=>'array']
  (写自动 json_encode 落库、读自动 decode 回显)
- processVehicleItems:create 前归一化 attachment 为数组(store/update 共用此路径)
- generateVehicleUniqueId:排除 attachment,避免附件影响车辆去重/数量

show/detail 经模型 items 关系 + cast 自动回显 attachment;字段已由前端在库表就绪。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-06 15:01:03 +08:00
mzl92 6e2e8e1cc6 feat: 备货单列表支持 view_scope(all/self) 视图切换(仅 user_id=73)
在 /crm/stock/order/list 的 buildQueryConfig index 分支最前面短路:
- 仅当前用户 uid=73 且传 view_scope 时生效,最高优先级,覆盖角色范围逻辑
- all:自己和别人的单,排除草稿(approval_status>=1)
- self:只看自己(salesperson_id=73,含自己草稿)
- 非73用户或未传该参数:走原逻辑,向后兼容,无越权

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-06 11:49:28 +08:00
mzl92 b2684ecbb2 feat: 询盘批量分配接入事务写库与汇总邮件发送
- applyAssignments: 单事务更新 crm_customer.user_id + 写 crm_customer_his
- sendDigests: 按 user 表邮箱每人发一封汇总邮件,失败重试1次
- manifest: runtime 下 JSON 记录 emailed 状态,防重复发送
- 新增 --no-notify(只写库不发邮件),与 --notify-only 配合分步执行

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 15:09:52 +08:00
mzl92 61c34db99e feat: 新增询盘批量分配命令(骨架+Excel解析+code匹配+dry-run)
- InquiryDigestMail: 汇总邮件 HTML 模板
- InquiryBulkAssignCommand: assign 轮询、parseExcel、matchCustomers(code+排除软删除)、dry-run 报告、--self-test

写库/发邮件逻辑见后续提交。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 14:56:36 +08:00
mzl92 3d3caddc7d docs: 询盘批量分配+汇总邮件方案设计
崔琪2.xlsx 1427 条询盘按 Excel 行序轮询分配给 6 名业务员,
更新 crm_customer.user_id 并发每人一封汇总邮件。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 14:46:04 +08:00
mzl92 b89ac48dd8 feat: 新增业务人员公共接口(role_id=2,全量返回)
- PublicApiController 新增 staffList():通过 user_roles 关联筛选业务人员
- 返回 id/name/sn/phone/email,支持 keyword 模糊匹配,不分页全量返回
- 路由组新增 /common/public/staff/list
- .gitignore 忽略 docs/*.sql(数据导出文件,不入库)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 13:37:48 +08:00
mzl92 71dca13119 fix: fb_leads 导入时对 full_name 增加 URL 过滤与长度截断
修复询盘自动导入因 full_name 含粘连 URL(如 "Saif Ullahhttps://...")
导致同步到 inquiry_log.contacts(varchar 255) 时超长报错、整批回滚卡死的问题。

- 新增 normalizeFullName():去掉粘连 URL + 截断到 255
- switch 新增 full_name 分支

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 16:47:42 +08:00
mzl92 35d98c16e9 feat: 新增备货单公共 API 接口(PI 号/VIN 号列表)
- 新增 ApiKeyAuth 中间件(hash_equals 防时序攻击)
- 新增 PublicApiController(piList/vinList 两个只读接口)
- 仅返回已审批通过(approval_status=2)的数据,支持分页和模糊搜索
- LIKE 通配符已转义,异常信息不暴露内部细节
- 附对接文档 docs/public-stock-api.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 17:44:53 +08:00
mzl92 929bae6f13 Finish Hotfix-1 2026-03-16 14:37:54 +08:00
mzl92 a72b30a699 调整合塑询单分配人 2026-03-16 14:37:39 +08:00
18338781771 75a59a7197 优化 2026-03-03 17:44:10 +08:00
18338781771 30f3e211af 抓取品牌 2026-02-05 09:16:24 +08:00
18338781771 eee09316df 抓取车型信息 2026-02-04 17:35:08 +08:00
mzl 2da3804953 Finish Hotfix-1 2026-02-03 11:15:03 +08:00
mzl eae699cd27 ts 2026-02-03 11:14:45 +08:00
18338781771 4ea4204ff4 渠道调整 2026-02-03 10:51:08 +08:00
18338781771 67a39917f0 过滤未提交的 2026-01-22 17:20:29 +08:00
mzl92 b6851cdef0 Finish Hotfix-1 2026-01-22 10:15:19 +08:00
mzl92 733996f346 修改询盘自动配置 2026-01-22 10:15:05 +08:00
18338781771 607de6c70a 超管 2026-01-20 15:41:24 +08:00
18338781771 e7c5e17592 内勤可以看自己组员的备货单 2026-01-20 15:30:24 +08:00
mzl92 2ec89a880a Finish Hotfix-1 2026-01-08 15:08:44 +08:00
mzl92 dffaac5b07 ts 2026-01-08 15:08:35 +08:00
mzl92 907be759a0 Finish Hotfix-1 2026-01-08 15:04:47 +08:00
mzl92 f7b94da39f ts 2026-01-08 15:04:39 +08:00
mzl92 c6fada47fc Finish Hotfix-1 2026-01-08 15:02:05 +08:00
mzl92 b09e695ca7 ts 2026-01-08 15:01:51 +08:00
mzl92 de39108efa Finish Hotfix-1 2026-01-08 14:49:54 +08:00
mzl92 7dceb4b828 ts 2026-01-08 14:49:44 +08:00
mzl92 d056ba5f6f Finish Hotfix-1 2026-01-08 09:14:34 +08:00
mzl92 99551bba7f 移除加纳询盘独立分配 2026-01-08 09:14:17 +08:00
18338781771 5e06b1737c Merge branch 'hotfix/email' 2026-01-05 09:44:33 +08:00
18338781771 b43335c0d9 邮件清洗查询状态过滤 2026-01-05 09:44:26 +08:00
18338781771 ac6bfcf16c Merge branch 'hotfix/email' 2026-01-04 16:13:55 +08:00
18338781771 9f74934f37 邮件 2026-01-04 16:13:21 +08:00