Compare commits

..

514 Commits

Author SHA1 Message Date
xingyu4j b37657a92d Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin 2026-06-08 10:39:47 +08:00
金毛88 f23c9f5e19 chore: update deps 2026-06-07 18:54:43 +08:00
YunaiV 21998d8044 fix(iot): 修复 IoT 场景联动最近触发时间不显示
- 对齐后端字段 lastTriggerTime
- 修复 web-antd、web-ele、web-antdv-next 的 API 类型、表格列和插槽读取
2026-06-07 14:55:30 +08:00
xingyu4j 413ec8c060 docs: update deps 2026-06-07 12:59:11 +08:00
xingyu4j fd4d247e37 chore: update deps 2026-06-07 12:58:47 +08:00
xingyu4j c376a60e83 fix: lint 2026-06-07 12:52:18 +08:00
xingyu4j aad62cf5ca fix: dhtmlx-gantt 第三方类名使用下划线命名,无法重命名,故禁用 BEM 类名规则 2026-06-07 12:51:48 +08:00
xingyu e6ecade0ee
!359 fix(@vben/web-antdv-next): 适配 antdv-next 组件写法并修复迁移兼容问题
Merge pull request !359 from XuZhiqiang/feat-antdv-next
2026-06-07 02:17:59 +00:00
YunaiV 9c68eb18c1 fix(web-antdv-next): 修复商城组件类型与 WMS 枚举导入
- 修复 web-antdv-next 商城 Banner、活动选择、DIY 装修等组件类型问题
- 收窄热区、魔方、导航栏、公告栏等装修组件配置类型
- 修复 web-antd WMS 首页单据统计枚举从 vue 错误导入的问题
- 修复商城统计时间参数、客服消息类型导入等类型错误
- 对齐 web-antd、web-ele、web-antdv-next 的商城促销组件类型定义
- 修复 DIY 装修、组合活动、积分活动、运费模板等组件兼容问题
2026-06-07 00:52:07 +08:00
YunaiV f2a5bc522d fix(mall): 修复多端商城模块类型与组件兼容问题
- 修复商城统计时间参数、客服消息类型导入等类型错误
- 对齐 web-antd、web-ele、web-antdv-next 的商城促销组件类型定义
- 修复 DIY 装修、组合活动、积分活动、运费模板等组件兼容问题
2026-06-07 00:31:26 +08:00
YunaiV f8fb3d881d fix(mall): 修复首页账户充值金额单位显示错误
- 首页运营数据的账户充值金额从分转换为元后展示
- 同步修复 Vue3 与 Vben 的 antd、ele、antdv-next 三端
2026-06-06 23:40:11 +08:00
XuZhiqiang 4b77779e60 fix(web-antdv-next): 同步 CRM 回款预填和 ERP 单据弹窗修复 2026-06-06 23:08:42 +08:00
XuZhiqiang 7bc60c481a fix(web-antdv-next): 统一 Popover 和 Tooltip trigger 数组写法 2026-06-06 22:56:31 +08:00
XuZhiqiang 8fe46edfba fix(web-antdv-next): BPM 模型菜单使用 MenuItem 适配 antdv-next 2026-06-06 22:53:56 +08:00
XuZhiqiang 4f5caf1566 fix(web-antdv-next): TableAction 和 AI 菜单使用 MenuItem 并修正 Dropdown trigger 2026-06-06 22:51:07 +08:00
XuZhiqiang d3bcfd7177 fix(web-antdv-next): IoT 历史数据表使用 render 替换 customRender 2026-06-06 22:39:03 +08:00
XuZhiqiang 852fd0e44f fix(web-antdv-next): IoT 模拟设备页使用 Tabs items 和 contentRender 适配 antdv-next 2026-06-06 22:34:40 +08:00
XuZhiqiang 08a246d472 fix(web-antdv-next): CRM 和 Mall 模块使用 Tabs items 和 contentRender 适配 antdv-next 2026-06-06 22:29:15 +08:00
YunaiV 9d2446b6ff fix(crm): 修复回款新增弹窗预填数据被清空
- 将回款表单下游字段清空逻辑从 schema 依赖刷新移到用户选择事件
- 修复从回款计划新增回款时合同、期数、金额等预填数据被清空的问题
- 兼容回款管理、回款计划、客户/合同详情等新增回款入口
- 同步处理 web-antd、web-ele、web-antdv-next
2026-06-06 22:26:20 +08:00
XuZhiqiang 1900c051fc fix(web-antdv-next): 使用 Tabs items 和 contentRender 迁移 IoT 详情页签 2026-06-06 22:22:56 +08:00
XuZhiqiang 4646900de1 fix(web-antdv-next): <Tabs.TabPane> 改成 Tabs :items="xxxTabItems",使用 items 和 contentRender 迁移 MES 剩余页签 2026-06-06 22:16:41 +08:00
XuZhiqiang 13acbdd556 fix(web-antdv-next): <Tabs.TabPane> 改成 Tabs :items="xxxTabItems",使用 items 和 contentRender 迁移 MES 页签 2026-06-06 22:12:19 +08:00
YunaiV 651a525187 fix(erp): 修复单据选择弹窗宽高与嵌套关闭问题
- 调整 ERP 单据选择弹窗宽度为 80%
- 固定选择弹窗 Grid 高度,避免表格被压扁
- 禁用主表单弹窗遮罩点击关闭,避免子弹窗操作误关闭主弹窗
- 同步处理 web-antd、web-ele、web-antdv-next
2026-06-06 21:40:45 +08:00
xingyu4j 8e0564cc42 chore: node v24 2026-06-06 21:07:55 +08:00
XuZhiqiang b02d602a21 fix(web-antdv-next): 统一 Collapse 面板和表格插槽写法 2026-06-06 20:56:57 +08:00
xingyu4j 017b3c3fce ci: bump actions/stale from 9 to 10 2026-06-06 20:49:34 +08:00
xingyu4j 126275b417 ci: bump dessant/lock-threads from 5 to 6 2026-06-06 20:48:51 +08:00
xingyu4j bc908e29eb ci: bump amannn/action-semantic-pull-request from 5 to 6 2026-06-06 20:48:19 +08:00
XuZhiqiang 72f3d62a20 fix(web-antdv-next:mall): 替换 Space 组件为 SpaceCompact 实现垂直布局 2026-06-06 20:31:33 +08:00
xingyu4j efe3c25310 chore: update deps 2026-06-06 19:36:39 +08:00
xingyu4j d85ac2c976 feat: form 表单赋值 2026-06-06 19:33:31 +08:00
xingyu4j c816591b69 fix: modal 下拉等不能选中 2026-06-06 19:32:31 +08:00
xingyu4j 564b349700 fix: vue/custom-event-name-casing 2026-06-06 16:21:25 +08:00
xingyu4j ce495d67a0 feat: 同步 antdv-next 的组件 2026-06-06 16:20:36 +08:00
xingyu4j 8094d1ffb9 chore: update deps 2026-06-06 16:19:32 +08:00
XuZhiqiang 5c9a163c46 fix(web-antdv-next): 统一 TextArea 和 InputPassword 引用方式 2026-06-06 12:46:01 +08:00
XuZhiqiang 2aa2c8676f fix(web-antdv-next): 统一日期范围和分组组件引用方式 2026-06-06 12:32:49 +08:00
XuZhiqiang d7b23d67ce fix(web-antdv-next): 使用 SpaceCompact 替换组合组件写法 2026-06-06 12:27:40 +08:00
XuZhiqiang b8d992f828 fix(web-antdv-next): 替换 Button 和 Input 组合组件写法 2026-06-06 12:17:02 +08:00
XuZhiqiang 693f0b48c2 fix(web-antdv-next): 统一 Select 和 Radio 子组件引用方式 2026-06-06 12:05:23 +08:00
XuZhiqiang 4f66adb999 fix(web-antdv-next): 修复Form.Item、Descriptions.Item 报错提示 2026-06-06 12:00:51 +08:00
xingyu da85dcf87c
!357 feat(web-antdv-next): 同步 MES/WMS/IoT 模块并对齐上游 Vben 框架
Merge pull request !357 from XuZhiqiang/feat-antdv-next
2026-06-06 03:43:07 +00:00
XuZhiqiang 1123f00795 fix(web-antdv-next): adapt notification and open change APIs 2026-06-06 11:17:21 +08:00
XuZhiqiang 0efde47539 chore(web-antdv-next): sync MES formatting 2026-06-06 07:37:45 +08:00
XuZhiqiang 569ded85f9 fix(web-antdv-next): sync dashboard workspace spacing 2026-06-06 07:36:56 +08:00
XuZhiqiang e046050ef0 fix(web-antdv-next): sync BPM timeout duration format 2026-06-06 07:35:49 +08:00
XuZhiqiang 615749daf1 chore: 保证和上游Vben-admin的框架依赖一致性 2026-06-06 06:53:11 +08:00
XuZhiqiang db3081ee62 chore: 应该和vben-admin版本保持一致 2026-06-06 06:35:10 +08:00
xingyu4j 58d4be5893 fix: type 2026-06-05 19:03:12 +08:00
xingyu4j 0483d5cd8b Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin 2026-06-05 19:03:00 +08:00
xingyu a0735e1bba
!354 fix: [bpm] OA 请假流程重新发起问题修复
Merge pull request !354 from Jason/master
2026-06-05 10:22:47 +00:00
jason 705aa2fa7b fix: [bpm] web-ele 审批等按钮点击没反应问题修复 2026-06-05 10:07:09 +08:00
jason 1b5a06f3a2 fix: [bpm] web-ele 修复审批等按钮不能操作等问题 2026-06-05 08:11:00 +08:00
afe1 748b182e44
fix: workflow (#8013)
* fix: catelog

* fix: system

* chore: sync upstream changes

* feat:  component and workflow error
2026-06-05 05:13:08 +08:00
XuZhiqiang cf0f7cedca fix(web-antdv-next): sync dept delete confirmation state 2026-06-04 22:57:28 +08:00
XuZhiqiang 70aed10752 fix(@vben/web-antdv-next): 在web-antdv-next,表单适配器只有TextArea,没有Textarea 2026-06-04 16:42:46 +08:00
XuZhiqiang 03f167b7d0 fix(web-antdv-next): sync remaining upstream fixes 2026-06-04 16:22:52 +08:00
XuZhiqiang f6a8c6e652 fix(web-antdv-next): sync shared UI fixes 2026-06-04 16:20:42 +08:00
XuZhiqiang 09970d89a4 feat(web-antdv-next): sync IoT module 2026-06-04 16:17:45 +08:00
XuZhiqiang 6315055c08 feat(web-antdv-next): migrate MES module 2026-06-04 16:08:03 +08:00
XuZhiqiang 82b22173c0 feat(web-antdv-next): migrate WMS module 2026-06-04 15:57:43 +08:00
XuZhiqiang e6e4d8ce1e fix(@vben/web-antdv-next): 修复IOT模块若干导入异常问题 2026-06-04 15:28:56 +08:00
XuZhiqiang bac2f92d1a chore(@vben/web-antdv-next): 升级antdv-next版本为1.3.3 2026-06-04 15:27:45 +08:00
jason a357dbf940 fix: [bpm] OA 请假流程重新发起问题修复 2026-06-04 14:11:30 +08:00
金毛88 6544340d80 Merge branch 'fork/HaroldZhangCode91/feature/fix_freeze_scrollbar_of_modal' 2026-06-04 13:54:21 +08:00
jason 8146ebde8c Merge remote-tracking branch 'yudao/master' 2026-06-04 12:42:27 +08:00
jason b91268923f fix: [bpm] 超时时间天的格式问题修复 2026-06-04 12:40:51 +08:00
jason 4a597c0806 fix: 发起人节点显示审批意见 2026-06-04 12:37:51 +08:00
Harold Zhang 6b7cb7b1fc feat: fixed the regression of changing Menu to MenuUI 2026-06-04 11:46:53 +08:00
Harold Zhang d90d45a128 fix: fixed modal freeze issue 2026-06-04 11:19:38 +08:00
Harold Zhang 66077b3bcf Merge branch 'main' into feature/fix_freeze_scrollbar_of_modal 2026-06-03 18:07:37 +08:00
Harold Zhang 0328594747 feat: fixed the overlay layer can not work with reka-ui 2026-06-03 17:52:41 +08:00
金毛88 790e114d41 chore: 固定vite 8.0.10,避免编译后异常 2026-06-03 17:32:13 +08:00
Harold Zhang cc60ca9592 feat: fixed the defects the scrollbar disapear when modal close 2026-06-03 16:10:17 +08:00
HaroldZhangCode91 79707a2ebd
feat: fixed regression of modal for element plus (#7999) 2026-06-03 13:27:12 +08:00
金毛88 0eb72ca4fd feat: add useTDesignDesignTokens 2026-06-03 13:25:23 +08:00
金毛88 7fd4b1de04 Merge branch 'fork/SaleriHQ/feat/form-field-array' 2026-06-03 13:22:21 +08:00
xingyu 1f8e9f6bb0
update README.md.
Signed-off-by: xingyu <xingyu4j@vip.qq.com>
2026-06-02 00:55:21 +00:00
YunaiV 044ba2382d feat(im):增加 im 的功能说明 2026-06-01 08:17:48 +08:00
Saleri 9ffd42f013 chore: add changeset for form field array 2026-05-31 23:06:00 +08:00
芋道源码 72aac700ff
!353 fix(bpm): clean up BPMN viewer resize observer
Merge pull request !353 from 芋道源码/dev
2026-05-31 13:50:10 +00:00
芋道源码 e943f4fcfd
!352 MES 所有功能的迁移
Merge pull request !352 from 芋道源码/migration
2026-05-31 11:33:31 +00:00
YunaiV 840f4efbbe fix(bpm): 完善流程实例打印字段展示
- Vben5 web-antd/web-ele/web-antdv-next 同步支持更多表单字段打印
- Vue3 + Element Plus 流程打印补齐字典、用户、部门、省市区、文件、图片、开关、富文本等字段展示
- 普通字段和流程记录改为安全文本渲染,保留富文本 HTML 展示
- 打印时间改为每次打开弹窗时刷新
- web-ele 补充 ElButton 显式导入,避免运行时组件解析风险
2026-05-31 18:25:33 +08:00
YunaiV 64eea34a63 fix(bpm): 完善流程实例打印字段展示
- Vben5 web-antd/web-ele/web-antdv-next 同步支持更多表单字段打印
- Vue3 + Element Plus 流程打印补齐字典、用户、部门、省市区、文件、图片、开关、富文本等字段展示
- 普通字段和流程记录改为安全文本渲染,保留富文本 HTML 展示
- 打印时间改为每次打开弹窗时刷新
- web-ele 补充 ElButton 显式导入,避免运行时组件解析风险
2026-05-31 18:22:15 +08:00
YunaiV 54e5036171 fix(form-create): 修复字典选择器 modelValue 回显兼容
- Vben5 web-ele 使用默认 modelValue 绑定,修正相关注释避免误用 model-value
- Vben5 web-antd 保留 value 绑定并明确组件库差异
- Vue3 DictSelect 显式接收 modelValue 并派发 update:modelValue,避免选择值更新后回显异常
2026-05-31 17:16:17 +08:00
YunaiV 1896c60f53 feat(mes): add MES production task issue API and improve combination record validation 2026-05-31 16:48:00 +08:00
芋道源码 099d480ff4
!351 !347 feat: 流程的报表页面支持多种表单类型
Merge pull request !351 from 芋道源码/master
2026-05-31 08:43:04 +00:00
YunaiV 3327655d46 docs(mes): 登记 B037 修复,R008/R009 经核实判 rejected
- INDEX.md: R006 转 fixed(关联 B037);R008、R009 由 disputed 转 rejected
- bug_done.md: 追加 B037(@vben/constants 补齐 6 个共享 MES 常量)
- bug_rejected.md: 追加 R008、R009 拒绝记录
- mes-pro-codex review: 追加 R008/R009 复核记录(@vue/compiler-dom 实测
  ifShow 经 $setup proxyRefs 解包为 boolean,详情态正确隐藏;product-bom
  入口不可达,与源 vue3 效果一致)

当前 42 个 finding: fixed 38、rejected 3、closed 1、open 1(仅余 R010)。
2026-05-31 16:40:38 +08:00
Saleri 40101911f0 style: format naive styles 2026-05-31 16:21:13 +08:00
xingyu 04fbb7a556
chore: 升级 shadcn-vue 组件到v4最新版 (#7972)
* fix: useStore is deprecated

* chore: update deps

* feat: 升级shadcn-ui v4

* fix: workbench style

* feat: 升级shadcn-ui v4 step2

* feat: 升级shadcn-ui v4 step3

* chore: 升级shadcn v4

* fix: pagination

* fix: dark style

* fix: doc import

* feat: 增加详情组件,参考 antdv-next

* docs: descriptions docs

* docs: Browser Support

* feat: add table action

* feat: icon use vbenIcon

* fix: type error

* fix: dropdown popConfirm

* feat: 使用默认的文字交互

* feat: 优化渲染性能
2026-05-31 15:18:46 +08:00
Saleri e5f9106caa feat(@core/form-ui): 新增 useVbenForm 数组编辑器 VbenFormFieldArray 2026-05-31 15:03:55 +08:00
YunaiV 2fc7390091 docs(mes): 登记 MES-B033~B036 修复并更新 review 索引
- INDEX.md: R014、R026、R031、R039 转 fixed,分别关联 MES-B033~B036
- bug_done.md: 追加 B033(client 销售记录详情入口)、B034(salesnotice
  选择弹窗筛选)、B035(高基数选择器恢复分页弹窗)、B036(RQC 保存后
  留在弹窗编辑子表)完整修复记录
- bug_rejected.md: 同步前序 B029 归档调整

剩余 open: R006、R010;disputed: R008、R009。
2026-05-31 13:17:21 +08:00
YunaiV a188c8245d fix(preview): adjust layout for code preview modal and tabs 2026-05-31 10:24:31 +08:00
YunaiV 61172b9a68 fix(mes): 修复 MES 迁移 review 发现的问题(B001-B032)
系统性修复 MES migration review(INDEX.md,MES-R001~R042)发现的迁移问题,
覆盖 web-antd 与 web-ele 两端,按严重级别从 P0 到 P3。

P0
- B001: DICT_TYPE/BarcodeBizTypeEnum 等常量从 'vue' 误导入致 TS2305/运行时崩溃,
  改从 @vben/constants 导入(20 个文件)。

P1
- B002 itemreceipt 入库单名称误必填;B003 条码工单选择补 CONFIRMED 过滤;
  B004 库存台账冻结开关补更新权限禁用;B005 returnsales 上架明细批次号误必填;
  B006 checkrecord/maintenrecord 计划/执行人误必填;B007 returnsales 退货行
  rqcCheckFlag 默认改回 false;B019 OQC 预填 checkQuantity 缺省取 outQuantity;
  B024 repair 完成维修态放开 finishDate 录入;B025 tool 编码管理类型库存数量锁定为 1;
  B027 详情态自动编码按钮隐藏/禁用(md/cal/dv/tm 13 模块)。

P2
- B008 IPQC 废品数量补 0 默认值;B009 共享选择器去掉 catch+console.error 吞错;
  B011 route 自定义 SFC 改 markRaw;B012 ele 自动编码按钮去 type:'default';
  B014 md 编辑态编码字段误禁用;B015 dv/subject 选择器仅展示启用项(保留历史回显);
  B016 盘点结果回填 batchId;B017 源 vue3 miscissue 业务类型字典误用 getStrDictOptions;
  B018 stocktaking/plan 盘点条件表单 schema 化;B020 清理 TODO @AI;
  B026 repair 验收信息字段按状态门控只读。

P3
- B010 QcIndicatorSelect 去吞错;B013/B019/B030/B031 componentProps、列对象多行化等
  code style;B021 自动编码循环方式列条件展示;B022 盘点结果选中清单行后字段禁用;
  B023 质检指标 resultSpecification 抽 ResultSpecificationInput 消除重复 fieldName;
  B032 barcode/batch/sn API 字段补注释。

风格统一
- getTitle 统一为「特殊态 if 提前 return + create/update 三元」(pro/card、
  stocktaking/task、repair);headerReadonly 抽 isHeaderReadonly 辅助函数对齐
  pro/workorder/transfer 写法;computed 解释注释移入 computed 内部。

验证:
- 两端 pnpm exec eslint 改动文件通过
- 两端 pnpm -F @vben/web-antd / @vben/web-ele exec vue-tsc 过滤 src/views/mes、
  api/mes 无报错
- git diff --check 通过

备注:R037(defectrecord 命名漂移)经复核为原 finding 前提有误(两端本就一致),
已 rejected,未占 MES-B 编号。R008/R009 为 disputed 待裁决。
本提交仅含 src/views/mes 与 src/api/mes 下文件,排除 .env.development、vite.config.ts、
infra/codegen、docs changelog 等无关旁支改动。
2026-05-31 10:21:23 +08:00
YunaiV 4dff39ddc5 fix(crm): 修复待办线索漏传归属场景 2026-05-31 09:37:36 +08:00
芋道源码 06f8b74790
!347 feat: 流程的报表页面支持多种表单类型
Merge pull request !347 from Jason/master
2026-05-31 01:33:45 +00:00
YunaiV b00a67deb9 fix(web-ele): 修复表单设计器自定义组件回显
- 移除 form-create 自定义组件错误的 modelField: 'model-value'
- 字典选择器、省市区选择器、iframe 组件改用默认 modelValue 绑定
- 修复 Element Plus 版选择后表单值更新但前端不回显的问题
2026-05-31 00:43:42 +08:00
YunaiV c25b631c10 fix(iot): 完善场景联动配置必填校验
- Vue3 抽取场景联动校验工具,统一触发器、附加条件和执行器校验
- Vben5 antd/ele 同步场景联动提交前兜底校验
- 补充 CRON 表达式、JSON 参数和动态字段必填校验
- 保留 deviceId=0 表示全部设备的业务语义
2026-05-31 00:36:41 +08:00
YunaiV 0fe9607302 fix(mes): 修复迁移 review 第三批 finding(B019-B023)+ schema/风格清理
修复 MES migration review 的 1 个 P1 + 多个 P2/P3 finding,覆盖 web-antd
和 web-ele 两端。

- MES-B019 (P1, R020): OQC 从待检任务预填时,checkQuantity 缺省取
  outQuantity,避免必填的检测数量为空被校验拦截。
- MES-B020 (P2, R012): 清理 pro/card、stocktaking/task 残留的 TODO @AI
  临时注释,taskId 补正式业务尾注释。
- MES-B021 (P2, R017): 自动编码分段"循环方式"列改 slot + DictTag,仅
  cycleFlag 为真才渲染(非循环行留空,对齐源 v-if 行为)。
- MES-B022 (P3, R035): 盘点结果选中盘点清单行后,物料/批次/仓储位置字段
  按 lineId 禁用,避免改成与清单不一致的值。
- MES-B023 (P3, R038): 抽出 QcIndicatorResultSpecificationInput 组件,
  schema 仅保留单个 resultSpecification 字段,组件内按 resultType 切
  RadioGroup(FILE)/Select(DICT),消除重复 fieldName 的双 FormField/重复 key。

附带代码风格对齐:
- pro/card、stocktaking/task 的 getTitle 改为「特殊态 if 提前 return +
  create/update 三元收尾」,对齐 oqc/returnvendor 等主流模块写法。

验证:
- pnpm exec eslint <本批改动文件>(antd + ele)通过
- pnpm -F @vben/web-antd / @vben/web-ele exec vue-tsc 过滤
  qc/indicator、qc/oqc、md/autocode、wm/stocktaking/task、pro/card 无报错

Ref: project_duibiao/mes/review_vben/INDEX.md (MES-R012/R017/R020/R035/R038)
2026-05-30 23:14:21 +08:00
YunaiV 26d07e2e28 feat(member): 会员增加 email 字段 2026-05-30 22:55:27 +08:00
YunaiV 1edaf023c2 refactor(mes): stocktaking/plan 盘点条件表单 schema 化(R034)
将盘点方案条件弹窗从手写 <Form> 模板重构为 useVbenForm + schema,提升
antd/ele 复用度,对齐 Vben5「schema 放 data.ts」约定。

- 新增 condition-value-input.vue(antd/ele 各一份):把「条件值」的 7 选 1
  (仓库/库区/库位级联、物料、批次、质量状态)+ 级联临时态 + valueCode/
  valueName 回写封装为单一 v-model 组件,经 valueChange 事件回填,避免
  schema 出现重复 fieldName 的渲染层风险。归 components/,与 pro/route
  的 RouteColorPicker 等同类自定义控件保持一致。
- useParamFormSchema 合并进同目录 data.ts,删除临时 param-data.ts;
  param-form.vue 改为 useVbenForm + setState(schema),onConfirm/onOpenChange
  结构与注释(// 提交表单、// 关闭并提示、// 加载数据、// 设置到 values)
  对齐 dv/subject 范式。
- 字典 options 用 getDictOptions(..., 'number') + NumberDictDataType 断言,
  移除冗余 .map() 转换。
- defineProps/defineEmits 内去掉非 vben 风格的 JSDoc 注释;去掉无谓的
  ParamTypeEnum alias,直接使用 MesWmStockTakingParamTypeEnum。
- 质量状态无实体 id,提交校验按 type 区分 valueCode / valueId。

验证:
- pnpm exec eslint <stocktaking/plan 改动文件>(antd + ele)通过
- pnpm -F @vben/web-antd / @vben/web-ele exec vue-tsc 过滤 stocktaking/plan 无报错

Ref: project_duibiao/mes/review_vben/INDEX.md (MES-R034)
2026-05-30 22:15:55 +08:00
YunaiV 7e62f9a5ef feat: 优化 IoT 告警模板选择
- 后端 mail/sms/notify 模板 simple-list 仅返回启用模板精简字段
- 前端补充 mail/sms/notify 模板 simple-list API 封装
- vue3 与 vben antd/ele 在各自 system 模块封装模板选择组件
- IoT 告警配置按接收类型动态选择短信、邮件、站内信模板
- 补充前端 IotAlertReceiveTypeEnum,替换表单内裸常量
2026-05-30 22:06:02 +08:00
YunaiV 3007539f0e refactor(mes): update comments and improve code readability in condition matchers 2026-05-30 20:38:05 +08:00
YunaiV 3f7134d3fc fix(mes): 修复迁移 review 第一批 5 个 bug(B001 vue 误导入 P0 + B002-B005 P1) 2026-05-30 19:36:16 +08:00
YunaiV 22e9081a45 refactor(mes): 统一 antd 和 ele 选择组件代码风格
- 规范 select 空值判断和回显逻辑
- 统一物料、供应商、客户选择弹窗的单选/多选行为
- 清理 components 内 TODO 并修复相关 DICT_TYPE 导入
2026-05-30 19:03:57 +08:00
YunaiV b3154ef87a feat(mes): 增加 componnents 评审的建议 2026-05-30 18:10:14 +08:00
芋道源码 70ca594a4c
!350 MES 迁移收尾 99%
Merge pull request !350 from 芋道源码/migration
2026-05-30 10:01:19 +00:00
YunaiV 51e633f6c9 refactor: 规范 MES/WMS 组件文件命名和导出引用 2026-05-30 17:29:05 +08:00
YunaiV c9a32ba780 ```text
refactor: 迁移模块 constants 到共享常量包

- 新增 MES/WMS 共享业务常量导出
- 将 Mall 客服、IoT 缺失常量合并到 @vben/constants
- 替换各模块本地 constants 引用
- 删除模块内重复 constants 文件
```
2026-05-30 16:51:13 +08:00
YunaiV 71cec9ac6a feat(mes): update chart options to use EChartsOption type and refactor imports 2026-05-30 16:34:12 +08:00
YunaiV c8deb9e91e feat(mes): 迁移 wm transfer 模块 2026-05-30 13:24:04 +08:00
YunaiV dd4b7e045a feat(mes): 迁移 home 首页(优化代码) 2026-05-30 13:23:41 +08:00
YunaiV 7d75ab8d8e feat(mes): 迁移 home 首页(优化代码) 2026-05-30 13:23:19 +08:00
YunaiV a237758516 feat(mes): 迁移 home 首页 2026-05-30 13:22:16 +08:00
YunaiV b325db0450 feat(mes): 迁移 home 首页 2026-05-30 13:21:55 +08:00
YunaiV 37b9db148f feat(mes): 添加 MES 转移单类型及状态枚举,更新相关表单字段禁用逻辑 2026-05-30 13:20:41 +08:00
YunaiV 83482781d6 feat(mes): 迁移 wm 里的 产品收货(wm_product_recpt)、、销售出库(wm_product_sales)、销售发货通知(wm_sales_notice)、领料出库(wm_production_issue)、采购入库(wm_item_recpt)、到货通知(wm_arrival_notice) 2026-05-30 11:09:48 +08:00
YunaiV f5fbd85e26 feat(mes): 迁移 wm 里的 return-* 系列(优化代码) 2026-05-30 11:08:37 +08:00
YunaiV 2fd44246f8 feat(mes): 迁移 wm 里的 return-* 系列 2026-05-30 10:58:56 +08:00
YunaiV 3ef3f246c2 feat(mes): update MES status enums and adjust visibility conditions for pro-card actions 2026-05-30 10:54:54 +08:00
YunaiV 60a423f44a feat(mes): pro-card 迁移 2026-05-30 10:46:21 +08:00
YunaiV be213b6b31 feat(mes): 迁移 work task 功能 2026-05-30 10:37:43 +08:00
YunaiV 7bf65041f9 feat(mes): 迁移 workorder 功能 2026-05-30 10:03:25 +08:00
YunaiV 753fd0e506 feat(mes): 迁移 SN 码并补齐条码业务选择器、修复库存台账
- 新增 wm/sn 模块(antd/ele):SN 码分组列表、生成弹窗、导出分组/明细、删除批次;
  api 补 generate/group-page/delete-batch/export 系列
- 补齐条码管理 USER/BATCH/PROCARD/PACKAGE 业务选择器并按源回填 bizCode/bizName
- 新增 wm/batch 选择器与详情:WmBatchSelect/Dialog(搜索补齐生产任务、模具、
  生产/有效/入库日期)、WmBatchDetail(useDescription);getBatchPage 收紧 PageParams
- 新增 pro/card 共享 API 与 ProCardSelect/Dialog
- 新增 system/user UserSelect/UserSelectDialog,部门树抽为 system/dept 共用
  DeptTreeSelect,user 列表页改用共享组件
- 修复 wm/materialstock 冻结开关 beforeChange(newFrozen, row) 签名 bug、
  批次号列可点开 WmBatchDetail、选择弹窗按 multiple 切 radio/checkbox
- 选择器 resolveItemById 去掉 try/catch+console.error,清理 TODO @AI
2026-05-30 09:59:50 +08:00
YunaiV e313de09c4 feat(mes): 优化 materialstock 的代码实现风格 2026-05-30 09:35:09 +08:00
YunaiV 79af870afe feat(mes): 提交 wm outsource 相关的迁移(代码优化) 2026-05-30 09:16:33 +08:00
YunaiV b6d1154b8f feat(mes): 提交 wm stocktaking 相关的迁移 2026-05-30 09:15:06 +08:00
YunaiV 990d0a78fb feat(mes): 提交 wm outsource 相关的迁移 2026-05-30 09:04:41 +08:00
YunaiV 4b38533c6e feat(mes): 添加采购入库单及行相关接口和功能 2026-05-30 00:57:13 +08:00
YunaiV 6b6d45132f feat(mes): 完善条码管理迁移并补齐业务选择器 2026-05-30 00:51:38 +08:00
YunaiV 7ee42b9888 feat(mes): 迁移(wm-packages)相关迁移(优化代码) 2026-05-29 23:50:48 +08:00
YunaiV f1523e417b feat(mes): 迁移(wm-packages)相关迁移 2026-05-29 23:39:32 +08:00
YunaiV 25bbe79cb2 feat(mes): 迁移(wm-misc)相关迁移 2026-05-29 23:37:05 +08:00
YunaiV e09db73f73 feat(mes): 更新条码相关功能,优化业务类型处理及描述字段 2026-05-29 23:31:51 +08:00
YunaiV 2a7051cceb feat(mes): 更新条码相关功能,优化业务类型处理及描述字段 2026-05-29 23:31:40 +08:00
YunaiV 93024d0061 feat(mes): 添加杂项出库单及入库单相关接口和状态枚举 2026-05-29 23:05:02 +08:00
YunaiV 05cf59b4bc refactor(index.vue): remove unused checkedIds and related comments 2026-05-29 22:34:47 +08:00
YunaiV 974527ed31 chore: gitignore 忽略 .playwright-cli 本地录制产物 2026-05-29 22:25:45 +08:00
YunaiV e91d30e899 refactor(mes/wm/barcode): 对齐 antd/ele componentProps 字母序与注释结构
审查 wm_barcode 时补齐:
- antd data.ts 的 componentProps 键统一为字母序(onChange 提到 options/
  placeholder 之前),与 ele 端保持一致
- antd index.vue 修正 checkedIds 的 JSDoc 错位(拆出「已选条码 ID」与
  「处理勾选变化」两段注释)
- ele config/data.ts 的「编辑时业务类型不允许变更」改为行尾注释,对齐 antd
2026-05-29 22:24:28 +08:00
YunaiV a8d60580be refactor(mes/wm/barcode): 清理 TODO @AI、简化 onBizChange、对齐勾选写法
- 删除 data.ts / config/data.ts / index.vue 里残留的 TODO @AI 注释
- applyBizSelected 改名 syncBizDetail(对齐 mes/qc/ipqc 的 syncUnqualified),
  函数内置 formApi 空判断,去掉中间变量 onBizChange,14 处 onChange 直接调用
- config/data.ts 的 dependencies 单行展开为多行
- index.vue 勾选写法对齐 system/user:records.map((item) => item.id!)
2026-05-29 22:13:57 +08:00
YunaiV b2ccdf80b2 feat(mes/qc): 迁移批次追溯(batchtrace)ele 端 + antd 改用 Vben Description
- ele: 新增 mes/wm/batch API、batchtrace 主页和向前/向后追溯子组件,
  与 antd 端实现保持一致
- antd: trace-detail 改用 useDescription({ schema }) 模式,schema
  抽到 data.ts 的 useDetailSchema();trace-list 的 pagerConfig /
  rowConfig / toolbarConfig 单行展开为多行
2026-05-29 22:09:12 +08:00
YunaiV 76e9df6e8e feat(mes/qc): 迁移待检任务(pendinginspect)
迁移待检任务列表页到 antd 和 ele。新增分页查询 API,列表展示
来源单据类型、检验类型、物料、数量、供应商/工单/客户等字段。
2026-05-29 22:08:51 +08:00
YunaiV b4e7573d10 feat(mes): 优化 generateAutoCode 的调用,减少 try catch 2026-05-29 21:22:14 +08:00
YunaiV f79dffcf2e feat(mes): 迁移 ipqc、oqc、rqc 功能(优化) 2026-05-29 21:10:18 +08:00
YunaiV eeff84b63f feat(mes): 优化 confirm 的代码风格 2026-05-29 19:32:43 +08:00
YunaiV 8028d8b6ef feat(mes): 迁移 batchtrace 2026-05-29 19:31:13 +08:00
YunaiV 8192bb4777 feat(mes): 迁移 materialstock 2026-05-29 19:26:04 +08:00
YunaiV f27942c8f9 feat(mes): 迁移 barcode 2026-05-29 19:24:52 +08:00
YunaiV d245eca60d feat(mes): 迁移 ipqc、oqc、rqc 功能 2026-05-29 19:09:19 +08:00
YunaiV 76260e67f3 feat(mes): 迁移一部分 api 2026-05-29 19:01:15 +08:00
YunaiV fe71f18d21 feat(mes-qc): 迁移 ele 来料检验及检测结果、缺陷记录组件 2026-05-29 16:52:03 +08:00
YunaiV cea628b1a1 feat(mes-qc): 迁移 antd 来料检验及检测结果、缺陷记录组件(代码优化) 2026-05-29 16:27:15 +08:00
YunaiV abc8789fe3 `feat(mes-qc): 迁移 antd 来料检验及检测结果、缺陷记录组件` 2026-05-29 15:54:58 +08:00
YunaiV d3233c4bb4 refactor: 统一表单 schema 挂载与 resetForm 处理 2026-05-29 11:40:28 +08:00
YunaiV 2d1325f11a feat(mes/wm): 迁移仓库基础到 vben5 antd/ele 2026-05-29 09:59:13 +08:00
YunaiV ec5b607171 feat(mes/qc): 迁移质检方案管理 2026-05-29 08:36:16 +08:00
YunaiV 16d6ab0722 feat(mes/qc): 迁移质检指标管理 2026-05-29 00:38:14 +08:00
YunaiV 0ec301cfb3 refactor: 统一确认弹窗调用并优化开发代理配置 2026-05-28 23:22:44 +08:00
YunaiV 177cf37c1f feat(mes/qc): 迁移缺陷类型管理 2026-05-28 21:59:11 +08:00
jason a1d6c8bdb3 Merge remote-tracking branch 'yudao/master' 2026-05-28 17:26:34 +08:00
jason 751af9b9af fix: [bpm] vben5+ele下面,修复部门负责人等加载不出数据问题 2026-05-28 17:25:28 +08:00
jason 7ad2d43121 fix: [bpm] web-ele版本 流程表单字典选择器下拉无法选中问题 2026-05-28 17:21:48 +08:00
afe1 108d7ff335
chore: add commitlint config declaration (#7968)
* fix: catelog

* fix: system

* chore: sync upstream changes

* types: add commitlint config declaration
2026-05-28 15:50:47 +08:00
leo 1d6842fa69
build: change runtime config asset naming strategy for PWA compatibility (#7963)
replace query-based config url (_app.config.js?v=...)
with deterministic hashed filename (_app-config-v{version}-{hash}.js)
ensure service worker precache matches runtime injected asset
2026-05-28 12:53:51 +08:00
Saleri d6a9eaf9e9
fix: 修复 web-naive 表单页 Input 输入 _ 不显示的问题 (#7962) (#7965)
* fix(@vben/web-naive): 修复 naive input 输入 _ 不显示的问题 (#7962)

* fix(@vben/web-naive): 限制 input 字体修复作用域,避免全局影响
2026-05-28 12:49:48 +08:00
boisduval f7540c119b
fix: 修复 useVbenModal useVbenDrawer 传入参数失效的问题 (#7964)
- 把provide的key值修改为与inject一致的options
2026-05-28 12:49:23 +08:00
芋道源码 08dad4ef5d
!349 mes 部分迁移
Merge pull request !349 from 芋道源码/migration
2026-05-28 04:34:22 +00:00
YunaiV e9cb162aea refactor: 统一确认弹窗调用并优化开发代理配置 2026-05-28 10:53:24 +08:00
YunaiV 59cc3bbd61 feat(mes): 新增 md workstation 的迁移 2026-05-28 01:08:05 +08:00
YunaiV 2a868b809f feat(mes): 新增 wm 等 api 迁移 2026-05-27 06:37:33 +08:00
YunaiV d1e2202e59 feat(mes): 迁移生产报工 antd/ele 并补齐任务选择器 2026-05-26 22:27:27 +08:00
YunaiV 5a1100aed4 feat(mes): 迁移“生产报工(pro_feedback)”的 ele 功能 2026-05-26 21:18:36 +08:00
YunaiV 44b62e14ac refactor: 统一 Vben 表单弹窗模式为 formType 并更新规范 2026-05-26 12:36:01 +08:00
YunaiV 3acc821de5 feat(mes): 迁移“生产报工(pro_feedback)”的 antd 功能 2026-05-26 08:42:49 +08:00
YunaiV 4a92762d44 fix(mes): 修正安灯迁移的配置角色显示和记录只读字段 2026-05-26 00:08:46 +08:00
YunaiV 9c7986d230 feat(mes):完成“安灯(pro_andon)”的 review 2026-05-25 23:29:41 +08:00
YunaiV f4e71137e0 feat(mes):新增“安灯(pro_andon)”的 review 2026-05-25 22:50:42 +08:00
YunaiV 6b6228bc9c feat(mes):新增“安灯(pro_andon)”的迁移 2026-05-25 22:28:23 +08:00
YunaiV be3d9eaed7 feat(mes):优化 review - 工序定义(pro_process)、工艺路线(pro_route) 2026-05-25 18:10:37 +08:00
YunaiV adb57ed364 feat(mes):优化 review - 工序定义(pro_process)、工艺路线(pro_route) 2026-05-25 18:10:29 +08:00
过冬 acf289381e
fix(@vben-core/popup-ui): modal 响应式适配,支持视口自适应 (#7951) 2026-05-25 13:27:17 +08:00
YunaiV 4949ed1c07 fix(iot):设备管理、产品管理的操作按钮,间隙过大问题 2026-05-25 12:31:09 +08:00
YunaiV 995666e4ce fix(iot):设备管理、产品管理的操作按钮,间隙过大问题 2026-05-25 09:32:57 +08:00
YunaiV 80a25ca767 feat(mes):review 工序定义(pro_process)、工艺路线(pro_route) 2026-05-25 09:25:01 +08:00
YunaiV 01a1d3e001 feat(mes):迁移工序定义(pro_process)、工艺路线(pro_route) 2026-05-25 09:09:14 +08:00
芋道源码 54d0459f07
!348 wms、iot 迁移最新
Merge pull request !348 from 芋道源码/migration
2026-05-25 00:23:33 +00:00
YunaiV 272757995e fix(iot): 修复产品、设备、规则与首页对标差异
- 对齐产品卡片默认图标和图片资源,修正产品导出文件名
- 对齐设备导入、属性历史、分组校验和物模型编辑行为
- 对齐首页统计空态、设备地图图例和快捷日期范围实现
- 对齐数据规则 source/sink 配置、Redis Stream 字段契约和场景联动选择器
- 补充空值判断工具测试,并将剩余 IoT 对标项迁入 done
2026-05-25 08:22:59 +08:00
YunaiV fab333fbb7 feat(mes):迁移【排班日历】 2026-05-25 01:07:52 +08:00
YunaiV d2763dc044 fix(iot): 修复 IoT 复评后续对齐问题
- 补齐设备详情子设备、Modbus 操作权限
- 修复属性搜索清空、模拟器空参数、告警处理备注校验
- 修复 HTTP 数据目的 URL 回显、Redis Stream 密码必填
- 优化固件上传读取时机,补充 isEmptyVal 并复用 JSON 参数校验
- 修正场景产品状态字典和 antd ValueInput 图标导入
2026-05-25 00:43:50 +08:00
YunaiV ab697925cf fix(iot): 修复 antd/ele 对齐评审问题
- 对齐场景联动、首页趋势、产品、设备、分组、物模型等行为
- 修复设备导入结果弹窗、分页、权限、校验规则等差异
- 收敛 antd 与 ele 的实现风格
2026-05-25 00:11:11 +08:00
YunaiV 3c592887b9 feat(mes):统一 dv、cal、md 的代码规范 2026-05-24 23:11:02 +08:00
jason 4ba9390f25 feat: 流程的报表页面支持多种表单类型 2026-05-24 22:29:17 +08:00
YunaiV 8ab0c53011 Merge remote-tracking branch 'origin/master' into migration
# Conflicts:
#	apps/web-antd/src/views/iot/home/modules/message-trend-card.vue
#	apps/web-antd/src/views/iot/rule/data/sink/config/redis-stream-config-form.vue
#	apps/web-antd/src/views/mes/md/client/components/md-client-select-dialog.vue
#	apps/web-ele/src/views/iot/home/modules/message-trend-card.vue
#	apps/web-ele/src/views/iot/rule/data/sink/config/redis-stream-config-form.vue
#	apps/web-ele/src/views/iot/thingmodel/modules/input-output-param.vue
#	pnpm-lock.yaml
#	pnpm-workspace.yaml
2026-05-24 22:20:36 +08:00
YunaiV 13561b933f feat(mes):优化 cal holiday 的界面,和 vue3 + ep 风格对齐 2026-05-24 22:12:02 +08:00
YunaiV 19911a19c0 feat(mes):统一代码规范,form.vue 的 2026-05-24 21:38:08 +08:00
YunaiV 1edf29abeb fix(iot): 修复设备模拟器属性值类型转换
- 按物模型 dataSpecsList 还原 enum/bool 属性原始值类型
- 保持设备消息筛选和卡片分页与 vue3 + ep 源项目一致
- 更新 IoT bug 状态,归档 B144 并清空剩余 todo
2026-05-24 21:36:33 +08:00
YunaiV 617d50f68f feat(mes):完成 dv 的整体迁移(需要评审) 2026-05-24 20:26:00 +08:00
YunaiV 53a00f6e15 feat(mes):完成 cal plan 【排班计划】的迁移 2026-05-24 20:16:26 +08:00
YunaiV 2bcd81dc94 feat(mes):完成 cal team 【班组】的迁移 2026-05-24 20:12:16 +08:00
YunaiV 858011bfab feat(mes):重构 tm-tool-type-tree.vue 为 list.vue 更合理 2026-05-24 20:00:22 +08:00
YunaiV 48547bc53b fix: 修复 IoT 迁移页面多处交互与契约问题
- 修复告警记录产品/设备筛选联动
- 清理设备详情延迟刷新 timer,避免卸载后触发查询
- 优化 OTA 固件编辑态只读展示与任务列表分页重置
- 修复场景联动值输入回显和布尔值类型
- 修复设备模拟器输入串台、数值类型提交和服务参数校验
- 更新 IoT bug 归档与迁移说明
2026-05-24 19:41:15 +08:00
YunaiV eb0f2a5ff2 feat(mes):tm tool 基本迁移完毕 2026-05-24 19:04:50 +08:00
YunaiV 51a05bfc39 feat(mes):tm tool 的 tm-tool-select.vue 组件 2026-05-24 18:36:20 +08:00
YunaiV 6fb45f1ded fix(iot): 修复场景联动动态列表 key 与校验问题
- 新增 getStableObjectKey,统一处理对象列表 v-for 稳定 key
- 场景联动触发器、执行器、条件组、条件项改用稳定对象 key
- 保持场景规则 API 类型不包含 UI 专用 _key 字段
- 修复场景联动触发器/执行器校验与地图详情跳转
2026-05-24 16:43:02 +08:00
YunaiV aeff25209d fix(iot): 修复 13 处 bug 并完成 codex 三轮收口
按 codex 两轮 review 分批处理 IoT 模块 13 处 bug,对第二轮反馈中
B42/B47 的类型/字段问题做最终收尾,所有修复 web-antd / web-ele 两端同步。

主要修复:
- B91  设备分组:删除前校验 deviceCount,分组下有设备时弹警告
- B40  物模型 array 数据规格:从 Radio.Group @change 事件正确取值(antd)
- B42  物模型属性历史:list 写入时按 idx 生成 _rowKey,模板 row-key="_rowKey"
       list 类型改 IotDeviceApi.DeviceProperty & { _rowKey: string }
       匹配后端 IotDevicePropertyMapper.xml 实际返回的字段
       (修掉 codex 指出的 antd row-key TS2322 与 ele 同毫秒撞键)
- B119 物模型表单:edit 模式禁用 identifier 编辑
- B47  场景规则主条件:产品/设备切换时清 deviceId/identifier/operator/value
       (修掉 codex 指出的 condition.value.param TS2339,Trigger 无 param)
- B44  数据目的数据库配置:SQL 复制按钮 setTimeout 在 onBeforeUnmount 中清理
- B51  场景规则首页统计:total 取接口 result.total,其余基于当前页
- B29  产品卡片视图:图标为 URL 时改用 <img> 渲染,复用 @vben/utils 的 isHttpUrl
- B43  首页设备地图:移除过度设计的 AbortController,回归 vue3 源项目同款
       InfoWindow 监听写法,querySelector 限定到 .BMap_bubble_content 子树
- B105 场景规则设备选择器:productId 变化后旧 deviceId 不在新列表则清空
- B45  通用 key-value 编辑器:v-for key 改用递增的 _uid,避免编辑/删除时 DOM 复用错乱
- B132 设备导入表单:beforeUpload 校验 .xls/.xlsx
- B126 设备详情:四个 tab 子组件 v-if 增加 device.id 守卫

附带工具收敛:
- @vben-core/shared/utils 新增 formatDayjs,统一 antd TimePicker/DatePicker
  value-format 后回传的 Dayjs|string 归一
- 场景规则首页 updateStatistics 补回 JSDoc,对齐文件内其他 function 风格

验证:
- 改动文件 pnpm exec eslint 0 error
- pnpm -F @vben/web-antd / @vben/web-ele exec vue-tsc --noEmit --skipLibCheck
  过滤 src/views/iot/|src/api/iot/ 均 0 hit
2026-05-24 10:11:43 +08:00
YunaiV 241cf76788 fix(iot): 修复 21 处 bug(P1×15 + P2×6)
经 codex 4 轮复评定稿,antd / ele 两端同步。

P1(场景规则 / 物模型 / Modbus / Redis sink / 路由):
- B7/B8 隐藏路由 path 与 activePath 对齐 vue3 源(产品 / OTA 固件详情)
- B9 移除后端不存在的 deleteSceneRuleList 封装
- B10 物模型 number specs 恢复 min/max/step/unit 校验
- B11 物模型新增枚举项补 dataType: ENUM
- B12 物模型 struct 非空校验绑 fieldPath,array 嵌套显式覆盖
       property.dataSpecs.dataSpecsList,确保父表单 validate 触发
- B13 struct 与 input-output-param 编辑回填 cloneDeep,取消不污染原对象
- B14 Modbus Client 模式 ip/port/timeout/retryInterval 改 dependencies 条件必填
- B19 Redis sink 补 dataStructure(默认 Stream)+ Hash/ZSet 条件字段
- B20 仅 ALERT_RECOVER 强校验 alertConfigId,ALERT_TRIGGER 放行
- B21 conditionGroups 递归校验
       · 设备状态/属性 param 必填
       · CURRENT_TIME 按 operator 区分:TODAY 免、BETWEEN_TIME 双段、其它单段
       · 触发器 / 条件 / 执行器 deviceId 改显式 null/undefined 判断,
         保留「全部设备 = 0」(后端 action 支持广播执行)
- B22 事件上报条件改回普通 Input,允许标量值或留空
- B23 antd 当前时间条件 :value / @update:value 绑定 + Dayjs 类型 normalize;
       归一逻辑抽到 @vben/utils.formatDayjs(packages/@core/base/shared/utils/date.ts),
       供所有 app 复用
- B24 设备控制动作切换无条件清依赖,去掉 isInitialized 冗余守卫
- B26 JSON 参数输入先全部校验通过后再写入父表单

P2(产品 / 设备 / 物模型展示 / 数据源):
- B28 产品 deviceType 去默认值,强制用户显式选择
- B30 设备列表 DeviceName 加点击详情 slot
- B31 设备卡片显示备注名称(nickname || deviceName)
- B32 设备详情 hasLocation 改用 != null,合法 0 坐标不再判空
- B41 物模型数据定义展示顺序改为 name-value
- B46 数据源 getData() 剔除仅 UI 用的 identifierLoading 临时字段
2026-05-24 00:32:35 +08:00
YunaiV ef57c96b2f fix(iot): 修复 6 处 bug(P1×5 + P3×1)
- product/product/data.ts: 网关子设备不显示联网方式
  show 条件由 != GATEWAY 改为 != GATEWAY_SUB(原写法漏判子设备)
- home/message-trend-card.vue: onMounted 兜底首次拉取
  ShortcutDateRangePicker 早期 emit 触发的请求落在 useEcharts
  isActiveRef=false 阶段会被静默丢弃;并加 isFirstMount guard 跳过
  子组件首次 emit,消除首次进入的双请求
- ota/firmware/data.ts: FileUpload accept 改回 ['bin','zip','pdf']
  并同步 helpText,对齐 vue3 源约定
- device/device/index.vue: 批量删除补 confirm 二次确认弹窗,
  与 system 模块批删风格一致,避免一键误删
- device/device/detail/modules/modbus-point-form.vue: 字节序仅在
  「为空 / 不属于新 rawDataType 合法选项」才重置,避免编辑回填时
  setValues 触发 handleValuesChange 把已保存字节序覆盖

antd + ele 两端同步。
2026-05-23 22:04:08 +08:00
YunaiV d646a23f7d fix(bpm): clean up BPMN viewer resize observer 2026-05-23 21:48:01 +08:00
xingyu4j fb2595ef90 Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin 2026-05-23 18:39:12 +08:00
芋道源码 eaaf55eafa
!346 fix(sms): 修复短信渠道列表展示不一致
Merge pull request !346 from 芋道源码/dev
2026-05-23 08:45:03 +00:00
YunaiV d910450426 fix(sms): 修复短信渠道列表展示不一致 2026-05-23 16:41:36 +08:00
PanFu f813245827
feat: 偏好设置的快捷键列表追加ESC快捷键的控制(关闭当前窗口) (#7947)
* feat: 快捷键追加ESC控制,关闭当前窗口

* feat: 偏好设置中,页面切换动画的颜色看不清的问题(使用当前主题色)

* feat: 三种弹出框支持快捷键ESC动作

* feat: 代码自动格式化(3个框架改动)

* feat: 代码自动格式化(3个框架改动)

* fix: 修正locale数据获取方式

* 单元测试问题修改

* 单元测试问题修改

* fix: 解决代码评论的问题

* fix: 解决代码评论的问题

* fix: 解决代码评论的问题

* fix: 解决代码评论的问题

* 单元测试问题修改

* fix: 解决评论问题

* fix: 解决代码格式导致pnpm run lint报错的问题

---------

Co-authored-by: PanFu <panfu@zhihuaai.com>
2026-05-23 09:50:35 +08:00
芋道源码 cfbd13289f
!345 迁移 wms + iot 部分
Merge pull request !345 from 芋道源码/migration
2026-05-23 01:42:47 +00:00
过冬 e98f0b7558
fix: 移动端禁用混合布局菜单拆分 (#7949) 2026-05-23 04:21:19 +08:00
Reese Wellin cd86de54e1
fix(preferences): 修复主题等个性化信息持久化被初始化配置覆盖 (#7948)
调整 initPreferences 中 merge 顺序,使用户缓存优先于 initialPreferences。

Fixes #7943
2026-05-23 04:17:46 +08:00
YunaiV 152964395d fix(iot): 修复场景联动动作类型切换 + 数据规则弹窗 4 处 bug
- B50 动作类型切换清理失效:updateActionType 先调 onActionTypeChange
  (此时 action.type 仍是旧值)再赋新值;onActionTypeChange 内恒真的
  type !== action.type 简化为 if (action.identifier)
- B16 新增弹窗不重置主表单:onOpenChange 关闭分支补 formApi.resetForm()
- B17 允许空数据源提交:source-config-form.validate() 补空数组校验
- B18 子表单校验 reject 未处理(弹窗关闭不掉):onConfirm 内 try/catch
  包子表单校验,失败 return 中止提交
2026-05-22 20:24:30 +08:00
Jin Mao 60eb1335f8 chore: vite 降级到8.0.10 2026-05-22 13:20:25 +08:00
xingyu f2b3b12553
chore: pnpm v11 (#7942)
* chore: remove rolldown dep

* fix: issues-helper and maintain-one-comment are temporarily disabled due to security issues

* chore: update deps

* fix: change error type to TypeError for non-browser environment check in LocalStorageDriver

* chore: update pnpm v11
2026-05-22 12:02:14 +08:00
layhuts c066889c37
Fix: 在isMobile=true时无法自定义Drawer的class问题 (#7941)
* fix: 在isMobile=true时无法自定义Drawer的class问题

* fix: 在ResizableHandle两边增加边距
2026-05-22 11:56:09 +08:00
YunaiV f8c869f1ff feat(mes):md client select 迁移 2026-05-22 08:41:54 +08:00
YunaiV 00779aacb3 feat(mes): 迁移 cal、dv、tm 的 api 2026-05-22 08:34:47 +08:00
928646789 6b81d1b0d5
fix: preferences-button click to show setting drawer (#7938) 2026-05-22 07:26:12 +08:00
afe1 126b33687a
chore: vite config tsconfig include (#7936)
* fix: catelog

* fix: system

* fix(vite-config): include tsdown config in tsconfig
2026-05-22 07:25:50 +08:00
YunaiV 9d665bd6b9 docs(iot): 新增 codex 评审入口 + 登记异步竞态不修决策
- review-for-codex.md:本轮修复背景 + 决策 + 文件清单 + 给 codex
  的 5 项重点关注。与 bug.md(待修源头) / bug_ignore.md(不修登记)
  形成三文件分工,后续 codex / 二次评审不会丢上下文
- bug_ignore.md/I-1:登记 scene 表单 3 处异步竞态(property-selector
  / device-selector / device-control-config 的 watch 异步加载)不修决策。
  评估理由:触发窗口极窄、低频操作、~40 行 epoch 模板代码成本不匹配、
  vue3 源也未做。复评条件:API 层接入 AbortController 时顺手补、
  用户实际反馈、改后端 push 模式
2026-05-21 21:26:36 +08:00
Jin Mao 5b67c2e740 chore: 更新pnpm-lock 2026-05-21 20:44:38 +08:00
Jin Mao 2d7c3c3072 chore: 更新pnpm-lock 2026-05-21 20:40:49 +08:00
Jin Mao 5cc68c9dd0 chore: 更新 vite 依赖版本
- 将 vite 版本从 ^8.0.13 降级到 ^8.0.10
- 保持其他依赖包版本不变
2026-05-21 20:22:28 +08:00
YunaiV df8e23542b fix(iot): 修复 scene 表单 vue-tsc 3 处类型错误
- ele device-control-config:
  - defaultParams 类型显式为 Record<string, any> ;
    param.identifier 可能为 undefined 时跳过赋值
  - ElOption :value="service.identifier" 改为非空断言 service.identifier!
- ele json-params-input:getParamTypeTag 用 as const 让 TS 自动推断字面值
  联合('primary' | 'success' | 'info' | 'warning' | 'danger'),传给
  ElTag.type 不再报错
- antd value-input:handleNumberChange 参数改为 any 内部 String 转换
  (AntD InputNumber @change 类型为 ValueType = string | number ,
   原 number | undefined 报错)
2026-05-21 19:58:33 +08:00
YunaiV e7361a60ec feat(iot):md 模块,支持生成 2026-05-21 18:48:57 +08:00
YunaiV 66843f2392 chore(iot): 数组回调缩写参数展开为完整业务命名
- products.find((p)) → ((product)),propertyList.find((p)) → ((property))
  等:把 .find / .filter / .map / .reduce 的单字母回调参数 (p / d / s / g / v
  / acc / val) 全部展开为 product / device / service / group / value /
  total 等完整命名
- 涉及 web-antd 与 web-ele 两侧 :device 列表 / 卡片 / 物模型属性历史 /
  ota 固件 / 场景执行器服务选择 / 属性选择器 / 产品选择组件
- 外层已绑定同名变量的场景,回调形参用 item 避免命名重复
2026-05-21 18:46:59 +08:00
YunaiV 83bf576daf feat(mes): rename field 'level' to 'configLevel' for clarity 2026-05-21 17:45:25 +08:00
YunaiV 2a97bed546 feat(mes): 移除多余 defineOptions 2026-05-21 17:36:30 +08:00
YunaiV c8ce1a8911 fix(iot): 设备配置详情统一 460px 高度 + 按钮加 8px 间距,卡片视图删除按钮改 !h-8 对齐其它按钮高度 2026-05-21 17:27:17 +08:00
YunaiV d1a2601b6c fix(iot): alert 模块对齐后端 VO + 搜索体验对齐 vben 实践(P1)
- alert/config API 删除多余字段 updateTime
- alert/record API 删除多余字段 deviceName / productName / processTime
- alert/record 搜索表单告警级别字段 configLevel → level ,
  对齐后端 IotAlertRecordPageReqVO.level(之前提交后端不会按级别筛选)
- alert/record 搜索表单设备字段改用 ApiSelect + getSimpleDeviceList 全量加载,
  showSearch / filterable 模糊搜索,对齐 vben 项目 13+ 处 ApiSelect 主流实践
- alert/config + alert/record 列表移除空跑 checkbox 列(无批量删除接口)
2026-05-21 16:39:30 +08:00
YunaiV d2587c17b0 fix: iot 固件的优化 2026-05-21 15:11:01 +08:00
YunaiV 33cdfcac3c feat(im): 修管理端 3 处:群消息 atUserNicknames 类型允许 null、移除前端无效的「消息内容」查询入口、表情包宽高加表单校验 2026-05-21 15:10:22 +08:00
YunaiV 58f2e23654 fix: iot 补齐 vue3 源缺失的表单校验(P1)
- 物模型功能定义「数据类型」字段补 required 必填校验
- 产品选择器(ProductSelect)补搜索能力:antd 加 show-search + option-filter-prop ,ele 加 filterable
- 设备表单 onConfirm 增加 advancedFormApi.validate() 调用,
  否则高级表单(含经纬度等字段)的 schema rules 不会触发
- 设备经纬度增加「成对填写」跨字段校验:仅填一项时给 warning 提示,
  与 vue3 源 DeviceForm.vue 行为对齐
2026-05-21 14:43:06 +08:00
YunaiV d207e3b82c feat(mes): 优化 md 基础模块的迁移 2026-05-21 13:23:33 +08:00
YunaiV 1afa70bb53 fix: iot 二次确认统一改用 popconfirm 模式(P1)
- 设备详情「配置推送」按钮包 Popconfirm / ElPopconfirm,防误下发
- 场景联动列表 TableAction 启用 / 停用项改用 popConfirm 配置
- 产品详情头部「发布 / 撤销发布 / 同步物模型表结构」三处按钮同步切换
- 移除命令式 Modal.confirm / ElMessageBox.confirm,与 system / iot 现有惯例一致
- 顺带消除 ele 端 ElMessageBox.confirm 取消未 catch 的未处理 promise
2026-05-21 12:44:12 +08:00
YunaiV 751ba2c782 feat(mes): 迁移工作站管理及设备、工具、人员关联 2026-05-21 11:10:21 +08:00
YunaiV 057ca0bfde refactor: 收敛 iot rule/scene API 的重复类型声明(P1)
- antd / ele api/iot/rule/scene,删除外层重复的 4 个 interface
- createSceneRule / updateSceneRule 入参改用 RuleSceneApi.SceneRule
- 业务文件 import 统一改用 RuleSceneApi.SceneRule / Trigger / TriggerCondition / Action
- 清理 2 处 TODO @haohao 残留注释

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 11:01:09 +08:00
YunaiV df720b2c1a style: 应用 lint 格式化到 ele scene 设备控制 / 属性选择器组件
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 10:44:32 +08:00
YunaiV 4b6e2de778 feat(mes): 迁移客户、供应商、车间管理到 vben 2026-05-21 10:36:07 +08:00
YunaiV e6e15ca4ef feat(mes): 迁移客户、供应商、车间管理到 vben 2026-05-21 10:35:54 +08:00
YunaiV 0d175cbe9c fix: 修复 iot 模块 ele 端迁移阻塞的类型 / 字段问题(P0)
- ele property-selector / device-control-config,改用 ThingModelApi 命名空间引用
- ele api/iot/thingmodel,补 ThingModelTSL 类型,收敛 getThingModelTSLByProductId 返回值
- ele api/iot/rule/scene,SceneRule 补 lastTriggeredTime 字段
- ele views/iot/rule/scene/data.ts,useGridColumns 对齐 antd 的 5 列结构
- ele views/iot/home/modules/message-trend-card,ElSelect 改用 ElOption 子节点
- ele / antd api/iot/rule/scene,Action.params 类型 Record<string, any> 改为 string

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 10:20:30 +08:00
YunaiV f02a5975b8 feat(wms): 优化 md unit 的迁移代码(优化代码) 2026-05-21 09:15:57 +08:00
YunaiV b35ce18c6e feat(wms): 优化 md unit 的迁移代码 2026-05-21 09:11:58 +08:00
Jin Mao 63a38dce49 refactor(workflow): 优化发布工作流配置
- 简化触发条件,移除冗余的推送事件配置
- 更新标签创建输入参数描述,明确格式要求
- 移除 Husky 环境变量配置
- 重命名构建作业为发布作业,提高语义清晰度
- 移除 Node.js 版本矩阵策略配置
- 优化版本提取逻辑,支持工作流调度和推送事件
- 统一标签前缀处理,确保版本格式一致性
- 移除注释掉的冗余步骤配置
- 简化发布配置,移除不必要的发布操作注释块
2026-05-21 09:07:59 +08:00
Jin Mao 629f747795 feat(workflow): 添加手动触发release标签工作流
- 添加 workflow_dispatch 触发器支持手动运行
- 新增 tag 输入参数用于指定创建的标签
- 设置默认标签值为 staging
- 保留原有的 push tags 自动触发功能
2026-05-21 08:54:51 +08:00
YunaiV c11db17376 feat(iot): 将 antd 的 rule scene 迁移到 ele 里。 2026-05-21 08:53:22 +08:00
YunaiV b3462c3286 feat(iot): 将 antd 的 rule scene 迁移到 ele 里。 2026-05-21 08:53:16 +08:00
YunaiV 9cc52f128c feat(wms): 优化 md item 的迁移代码(继续) 2026-05-21 08:45:48 +08:00
YunaiV 67997bd44d feat(wms): 优化 md item 的迁移代码 2026-05-21 08:09:29 +08:00
YunaiV 5790211897 feat(iot): 修复 antd Select 的 v-model 用法
将场景联动执行器配置、物模型数值单位的 Select 由 EP 风格的 `:model-value` 改为 antd 标准的 `:value`;前者不被 ant-design-vue 接收,导致下拉无法选中 / 回显失效。顺手把数值单位的 `getDictOptions` 提到 computed 缓存。
2026-05-21 01:09:55 +08:00
YunaiV 6b1425d541 feat(mes): 新增 md item 的迁移 2026-05-21 00:58:45 +08:00
YunaiV 13c3028ecc feat(iot): 修复 rule scene 的样式(覆盖)问题、间隙问题 2026-05-21 00:37:30 +08:00
YunaiV cb175e331f feat(iot): 优化代码,尽量使用 ProductStatusEnum 枚举 2026-05-21 00:17:56 +08:00
YunaiV 3f09fc1498 feat(iot): 优化 iot 的代码风格(迁移 constants.ts)地址 2026-05-20 23:11:02 +08:00
Jin Mao 8585008f79 chore: release v5.7.0 2026-05-20 17:45:44 +08:00
xingyu 00990d9453
Merge branch 'main' into fix/lint 2026-05-20 17:38:19 +08:00
PanFu 2a84b590b5
feat: 偏好设置按钮,支持在右上角用户的下拉框中展示;偏好设置中支持设置时区(多一个入口); (#7931)
* feat: 偏好设置按钮支持显示在用户下拉窗中的特性

* feat: 时区设置功能支持在偏好设置列表进行配置

* feat: 偏好设置按钮支持显示在用户下拉窗中的特性 - 完善示例代码

* feat: 时区设置功能支持在偏好设置列表进行配置

* feat: 时区设置功能支持在偏好设置列表进行配置-单元测试报错问题

* feat: 时区设置功能支持在偏好设置列表进行配置-修改代码QC问题

---------

Co-authored-by: PanFu <panfu@zhihuaai.com>
2026-05-20 17:24:53 +08:00
PanFu 769c970e08
fix: 修复三个问题:偏好配置项修改后重启不会生效;锁屏弹出框的按钮文字错误;右上角偏好设置按钮排序问题优化; (#7930)
* fix: 修正偏好设置加载缓存的偏好设置并与初始配置合并的顺序

* fix: 修正锁屏弹出框的按钮文字

* fix: 偏好设置按钮排序优化(取第三个占位的数字,若是第三个占位不是数字,则自动分配排序索引)

* fix: 修正偏好设置加载缓存的偏好设置并与初始配置合并的顺序 - 代码QC问题修改

---------

Co-authored-by: PanFu <panfu@zhihuaai.com>
2026-05-20 17:24:18 +08:00
xingyu4j 4d3c481a93 fix: 当lint检查出问题后,不能在终端终止 2026-05-20 16:39:03 +08:00
xingyu4j fda4b39c01 chore: update deps 2026-05-20 16:38:19 +08:00
xingyu4j 74d8942f39 chore: remove Unused deps 2026-05-20 16:24:59 +08:00
xingyu4j 9ec98f0846 refactor: replace depcheck with knip for dependency checking
Migrate vsh check-dep from depcheck to knip, reducing
315 transitive dependencies. Config is inlined in
DEFAULT_CONFIG, matching the check-circular pattern.
Also re-export CollapsibleParams from @vben/common-ui.
2026-05-20 16:14:21 +08:00
xingyu4j f71094e878 refactor: migrate json-viewer from vue-json-viewer to vue-json-pretty
- Replace vue-json-viewer with vue-json-pretty (actively maintained, Vue 3 native)
- Map original props to vue-json-pretty API in bindProps for backward compatibility
- Implement copy functionality via renderNodeActions slot with i18n support
- Update style.scss from .jv-* to .vjs-* class names
2026-05-20 14:39:17 +08:00
YunaiV e816288b82 feat(iot): 迁移 ele 的 alert、device、product、ota、home、thingmodel 的实现 2026-05-20 13:31:27 +08:00
YunaiV f1f8f4e64a feat(iot): 迁移 ele 的 map 组件 2026-05-20 13:09:26 +08:00
xingyu4j 9badda3d11 chore: update deps 2026-05-20 11:30:03 +08:00
YunaiV 250d3eb39f feat(iot): 迁移 iot 在 ele 的 api 2026-05-20 09:57:47 +08:00
YunaiV 5607f23322 feat(iot): 优化 rule scene 的代码风格 2026-05-20 09:57:05 +08:00
YunaiV 538d04a380 feat(iot): 优化 data rule,使用 vxe 简化表单,提升 antd、ele 的代码复用性 2026-05-20 09:54:33 +08:00
YunaiV b9d333f7ec feat(mes): 同步 api 的迁移 2026-05-20 09:52:20 +08:00
YunaiV dab9509ba0 feat(iot): 完善 rule/scene 的迁移 2026-05-20 09:01:57 +08:00
YunaiV b1bd32a89b fix(iot): 完善 thingmodel 的迁移 2026-05-20 08:46:28 +08:00
YunaiV ec796b8336 fix(iot): 完善 rule data 的迁移 2026-05-20 08:45:51 +08:00
YunaiV e7a61ce150 feat(iot): 优化 antd 里的整体代码风格。 2026-05-20 00:41:06 +08:00
YunaiV 1bdc0d992f feat(mes): 新增 md item type 的迁移 2026-05-19 22:20:13 +08:00
YunaiV 8bcfa20577 feat(iot):优化 ota 的代码风格(v6) 2026-05-19 16:52:27 +08:00
YunaiV ab15c884bf feat(wms): 优化 sku-form.vue 的 skuSeq 2026-05-19 16:31:41 +08:00
YunaiV 9c57ae07a6 feat(wms): update input components to disable controls and enhance user selection 2026-05-19 16:16:28 +08:00
xingyu4j 03fcecadcc fix: lefthook config 2026-05-19 16:13:00 +08:00
xingyu4j 3a88adb8a6 feat: test 2026-05-19 16:10:18 +08:00
xingyu4j c759cb2593 fix: lint config 2026-05-19 16:08:10 +08:00
xingyu4j f77166b3a2 chore: update deps 2026-05-19 15:59:43 +08:00
xingyu4j f7928b34b2 fix: lint 2026-05-19 15:58:34 +08:00
xingyu4j 454a5b54bd chore: lefthook config 2026-05-19 15:54:03 +08:00
YunaiV 09c19526bb feat(iot):优化 ota 的代码风格(v5) 2026-05-19 15:31:45 +08:00
YunaiV b9a7eddb72 feat(iot):优化 ota 的代码风格(v4) 2026-05-19 14:51:54 +08:00
YunaiV 0bc1981675 fix(wms): 优化 WMS 首页卡片样式和区块间距 2026-05-19 14:46:05 +08:00
Jin Mao a4dd9d30ce chore: release 5.7.0 2026-05-19 14:39:46 +08:00
YunaiV 9d54f60b10 feat(iot):优化 ota 的代码风格(v3) 2026-05-19 14:29:14 +08:00
Jin Mao 76cfcda2e9 Merge branch 'fork/xingyu4j/antdv-next' 2026-05-19 14:14:28 +08:00
橙子 7ec4df4995
fix: search-panel when ArrowUp and ArrowDown (#7922) 2026-05-19 13:40:50 +08:00
leo d71c81e8ff
style: apply vsh lint formatting (#7923) 2026-05-19 13:40:13 +08:00
YunaiV a70fcc9616 fix(wms): 对齐商品分类树筛选查询 2026-05-19 13:00:05 +08:00
YunaiV 4821d49017 feat(iot):优化 ota 的代码风格(v2) 2026-05-19 11:27:35 +08:00
YunaiV a1b66588ec fix(wms): 修复首页汇总卡展示跳转和库存选择跨页勾选 2026-05-19 10:59:14 +08:00
YunaiV a098c201e1 fix(wms): 修复库存选择器跨页选择
- 合并 VXE 当前页勾选与 reserve 跨页保留记录
- 关闭或重开弹窗时清理 checkbox reserve 状态
- 补回双击库存行直接选择确认
2026-05-19 10:08:01 +08:00
YunaiV 8da5c12dfc fix(wms): 修复库存统计商品维度合并字段
- 对齐商品维度列字段为 itemId、skuId、skuWarehouseId
- 同步 antd/ele 的 spanMethod 合并字段
- 补充 WMS 迁移验证记录
2026-05-19 08:58:54 +08:00
YunaiV 3d0917f1a9 feat(wms):完成 inventory index 的迁移 2026-05-18 23:15:34 +08:00
YunaiV 0280df114f feat(wms):完成 inventory history 的迁移 2026-05-18 22:55:37 +08:00
YunaiV 6b61004b6a feat(wms):完成 md item 的迁移(antd 优化,ele 全部) 2026-05-18 22:46:47 +08:00
YunaiV 8d69e4d9f0 feat(wms):完成 md item 的迁移 2026-05-18 22:35:58 +08:00
YunaiV cd42a653c5 feat(wms):修复 inventory-select.vue、item-sku-select.vue 重叠的问题 2026-05-18 22:35:22 +08:00
YunaiV 56de1f1412 feat(iot):清理 defineOptions 冗余的 2026-05-18 22:34:31 +08:00
YunaiV 80f071d57f feat(wms):完成 antd、ele 的 inventory-select.vue 的迁移 2026-05-18 22:09:49 +08:00
YunaiV 68800c96d7 feat(wms):完成 antd、ele 的 item-sku-select.vue 的迁移 2026-05-18 22:07:32 +08:00
YunaiV 2dfa863d68 feat(wms):完成 antd、ele 的 category 的迁移 2026-05-18 21:57:19 +08:00
YunaiV 4cded0a674 feat(wms):完成 antd、ele 的 check 的迁移 2026-05-18 21:56:44 +08:00
xingyu4j aac626da32 feat: add system user view 2026-05-18 21:45:17 +08:00
YunaiV 584370358e feat(iot):优化 ota 的代码风格 2026-05-18 21:14:20 +08:00
YunaiV 76bed17ed9 feat(iot):优化 alert 的代码实现(继续) 2026-05-18 20:56:13 +08:00
YunaiV e9e534018f feat(iot):优化 alert 的代码实现(继续) 2026-05-18 20:35:07 +08:00
xingyu4j 5db93a345a fix: doc build error 2026-05-18 20:17:35 +08:00
xingyu4j 7c943cc06b chore: disable oxc typeAware and add --threads option for oxlint
Type-aware linting was consuming excessive memory with nearly all
type-aware rules turned off. Add --threads CLI option to control
oxlint parallelism.
2026-05-18 18:46:13 +08:00
xingyu4j 5c8dd1a6da chore: docs config 2026-05-18 18:35:34 +08:00
xingyu4j 6592135cc5 chore: update vitepress v2 2026-05-18 18:23:10 +08:00
xingyu4j 2f16ee7cf5 docs: use antdv-next 2026-05-18 17:30:59 +08:00
xingyu4j 0c1b737325 fix: fix lint && typecheck 2026-05-18 16:50:14 +08:00
xingyu4j 5bbdcffb97 Merge branch 'main' into antdv-next 2026-05-18 16:38:56 +08:00
xingyu4j 1867015e97 Merge branch 'antdv-next' of https://github.com/xingyu4j/vue-vben-admin into antdv-next 2026-05-18 16:35:28 +08:00
xingyu b6aeadd9a2
Merge branch 'main' into antdv-next 2026-05-18 16:35:18 +08:00
xingyu4j 1e44b87359 refactor: migrate playground deprecated antdv-next APIs
- Modal: destroyOnClose → destroyOnHidden
- Card: body-style → styles.body
- Alert: message prop/slot → title
- Spin: tip → description, wrapper-class-name → classes.root
2026-05-18 16:35:06 +08:00
xingyu4j a1081bf7a6 fix: 修复 InputNumber 组件宽度在表单中不占满的问题 2026-05-18 16:28:19 +08:00
xingyu4j 9bb2026b4d fix: 修复 InputNumber 组件宽度在表单中不占满的问题 2026-05-18 16:25:49 +08:00
xingyu4j 4554cd016a fix: lint 2026-05-18 16:19:53 +08:00
xingyu4j 350d5ee60e refactor: playground use antdv-next 2026-05-18 16:18:46 +08:00
xingyu4j 1ec058cbe3 chore: update deps 2026-05-18 15:06:59 +08:00
xingyu 709951e6db
!344 fix(@vben/web-antdv-next): 更新 antdv-next 依赖版本至 1.3.0,修复相关兼容性问题
Merge pull request !344 from XuZhiqiang/feat-antdv-next
2026-05-18 06:19:34 +00:00
YunaiV fbc03a9713 feat(wms):完成 antd、ele 的 movement 的迁移 2026-05-18 13:29:26 +08:00
YunaiV 1bbb7eb1d5 feat(wms):完成 antd、ele 的 shipment 的迁移 2026-05-18 13:13:29 +08:00
YunaiV 88515705dc feat(iot):优化 alert 的代码实现。 2026-05-18 12:36:58 +08:00
YunaiV 81b4690998 feat(iot):优化 device 的权限校验 2026-05-18 12:28:21 +08:00
YunaiV cfb1f8401e feat(iot):优化 IoT 请求的代码风格(thingmodel 界面调整引入) 2026-05-18 12:27:37 +08:00
YunaiV 5182cdbffa feat(iot):优化 IoT 请求的代码风格(device 界面调整引入) 2026-05-18 12:26:58 +08:00
YunaiV d649a617ac feat(iot):优化 IoT 请求的代码风格 2026-05-18 12:26:06 +08:00
YunaiV 71a23487f7 feat(iot):优化首页的设备统计实现 2026-05-18 08:55:39 +08:00
YunaiV 89f75428d6 feat(iot):增加 product/product 模块的代码评审 2026-05-18 08:54:44 +08:00
YunaiV 179881bd3d feat(iot):补充产品分类的 auth 操作校验 2026-05-18 08:50:23 +08:00
YunaiV 58f8b7fb22 feat(iot):增加 alert 模块的代码评审 2026-05-18 08:48:25 +08:00
YunaiV 6740401f6c fix(wms):完善 ep 的 order receipt 迁移(表单、详情) 2026-05-18 08:34:35 +08:00
YunaiV b42e9b36e5 feat(wms):优化 antd、ele 的 order receipt 迁移 2026-05-18 01:02:09 +08:00
YunaiV f8c2d4b1ff feat(wms):优化 antd、ele 的 order receipt 迁移 2026-05-17 23:56:05 +08:00
YunaiV 41d5aa93d6 feat(wms):新增 ele 的 order receipt 迁移 2026-05-17 23:40:00 +08:00
YunaiV 3135b28211 feat(全局):增加 number-range-input 组件 2026-05-17 23:35:31 +08:00
YunaiV 08511191f7 feat(wms):修复 print 顶部白块的问题,对齐 vue3 + ep 的样式 2026-05-17 23:15:16 +08:00
YunaiV 0246fa1ebc feat(wms):优化 order receipt 的实现,对齐 vue3 + ep 版本 2026-05-17 23:09:18 +08:00
YunaiV 0e4012c623 feat(全局):增加 barcode 二维码组件 2026-05-17 23:07:56 +08:00
YunaiV 4933180560 feat(wms):增加 receipt 功能、评审 2026-05-17 21:39:15 +08:00
XuZhiqiang aa577d84e9 fix(@vben/web-antdv-next): 更新 antdv-next 依赖版本至 1.3.0,修复相关兼容性问题 2026-05-17 20:13:14 +08:00
YunaiV 8710da9383 feat(wms):增加 wms 工具类 2026-05-17 19:09:01 +08:00
YunaiV 5a1f4901da feat(iot):优化 iot 设备管理的样式 2026-05-17 19:07:50 +08:00
YunaiV 3da4a3f417 feat(wms):将首页的枚举值去掉,统一合并到 constants 里,更聚焦点 2026-05-17 18:17:30 +08:00
YunaiV 84b91c6795 feat(iot):优化 iot 产品管理的样式 2026-05-17 18:11:31 +08:00
YunaiV 735ff018be feat(wms):增加 home 统计的迁移 2026-05-17 17:48:53 +08:00
YunaiV 0163794e3f feat(wms):增加 category 模块的迁移 2026-05-17 16:47:27 +08:00
YunaiV bb63ca9541 feat(wms):增加 brand 模块的迁移 2026-05-17 16:35:51 +08:00
YunaiV 6b28518165 feat(wms):迁移 api 接口 2026-05-17 16:30:50 +08:00
XuZhiqiang 0d7d7aea73 fix(@vben/web-antdv-next): 补充废弃 API 修复,补充缺失的组件导入
- 补充 TabPane 组件导入(约 48 个文件)
- 补充 TimelineItem 组件导入(3 个文件)
- Tabs tab-position → tab-placement,left → start
- Steps.Step 子组件 → items 数组模式
- TimelineItem #dot slot → #icon slot
- adapter Modal destroyOnClose → destroyOnHidden
- adapter visibleEvent onVisibleChange → onOpenChange
2026-05-17 11:03:47 +08:00
YunaiV 4adce844d3 feat(wms):增加 merchant 模块的迁移 2026-05-17 10:50:34 +08:00
YunaiV 19b5f38e23 feat(wms):增加 warehouse 模块的迁移 2026-05-16 23:12:33 +08:00
YunaiV 80fa8b74e8 feat:补齐 antd 的 component: 'InputNumber', 的 class full 样式 2026-05-16 22:46:16 +08:00
YunaiV 5710761dbe feat(wms):调整 README.md 2026-05-16 15:09:05 +08:00
YunaiV 877ba2727f feat(wms):调整 README.md 2026-05-16 14:56:01 +08:00
YunaiV 70a639967c feat:更新 README.md
- 提交时不再用节点表单值覆盖 data.variables;与预览阶段使用同一份合并变量
- onChange 加 useDebounceFn(300ms) + 请求序号去重,handleAudit 提交前 await 最新一轮重算
- 切换任务时重置请求序号与 pending 重算
- 改用 form-create 官方 formData() 取节点表单当前值
- 节点表单初始化等 fApi 就绪后再计算下一节点(until + 1s 兜底)

同步至 web-antd / web-ele 两端
2026-05-16 14:44:01 +08:00
XuZhiqiang 6cbbe88902 fix(@vben/web-antdv-next): 修复 antdv-next 废弃 API,迁移至新版本接口
将 ant-design-vue 旧版 API 统一迁移为 antdv-next 新版规范:
- Modal: destroy-on-close → destroy-on-hidden
- Card: :bordered="false" → variant="borderless",bodyStyle/headStyle → styles
- Popover: overlay-style → styles.root
- Divider: type → orientation
- Space: direction → orientation
- Alert: message → title
- Spin: tip → description
- Table: customRender → render
- notification: message → title
- Image preview: visible/onVisibleChange → open/onOpenChange
- adapter: visibleEvent onVisibleChange → onOpenChange
2026-05-16 13:35:20 +08:00
xingyu4j eb9cdbab9b fix: lint 2026-05-16 12:55:19 +08:00
xingyu4j 4907f281af chore: 更新 pnpm-workspace.yaml 配置,添加 publicHoistPattern 和 allowBuilds 设置 2026-05-16 11:56:39 +08:00
xingyu4j aadf9b6e39 chore: update deps 2026-05-16 11:52:20 +08:00
Jin Mao 84e77f64ea Merge remote-tracking branch 'origin/main' 2026-05-16 11:18:52 +08:00
guoqiangui 3e89077d46
fix(deploy): use IMAGE_NAME variable in remove_image instead of hardcoded name (#7907)
The `remove_image` function was using a hardcoded image name `vben-admin-pro`
instead of the `$IMAGE_NAME` variable (`vben-admin-local`), so the old local
image was never actually cleaned up before each build.

Co-authored-by: guoqiangui <guoqiangui@zhongshitech.cn>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 11:18:09 +08:00
Jin Mao c8c425538f Merge branch 'fork/xueyitt/main' 2026-05-16 10:49:33 +08:00
Jin Mao b04c10aab6 Merge branch 'fork/LayHuts/feature/vxe-table-viewed' 2026-05-16 10:48:00 +08:00
JyQAQ b5f79db321
fix(@vben/plugins): 修复 tiptap 重复注册扩展警告 (#7917)
StarterKit v3.22.0 已默认包含 Document、Link、Underline 扩展,
与单独导入产生重复注册,导致控制台警告:
[tiptap warn]: Duplicate extension names found: ['link', 'doc', 'underline']

- 移除 Document 单独导入和使用,StarterKit 已内置
- 移除 Underline 单独导入和使用,StarterKit 已内置
- StarterKit 配置中添加 link: false,禁用内置 Link,
  保留自定义配置的 Link.configure({...})
2026-05-16 10:45:30 +08:00
PanFu 42d82875ce
feat: 1、完善tree组件的全选状态不正确、全选没有label、item内容超长导致复选框对齐错乱、item内容超长没有tips无法看到完整内容的问题 (#7915)
Co-authored-by: PanFu <panfu@zhihuaai.com>
2026-05-16 10:44:55 +08:00
Akuria 4d8d2de6ad
fix: guard svg icon loading during docs SSR (#7912) 2026-05-16 10:43:47 +08:00
Akuria 294700a247
fix: skip fixed footer height in auto-content-height calculation (#7910)
* fix: skip fixed footer height in auto-content-height calculation

When the Page component's footer has position: fixed, it is removed
from the normal document flow and should not be subtracted from the
available content height. Previously, the footer's offsetHeight was
always subtracted, causing incorrect height calculation for fixed
footers.

Also reset shouldAutoHeight before recalculating to prevent stale
state on hot reload.

Fixes #4576

* fix: replace getComputedStyle footer height check with footerFixed prop

Use an explicit `footerFixed` boolean prop instead of runtime
getComputedStyle detection to determine whether the footer height
should be excluded from content height calculation. This avoids
unreliable style queries and makes the behavior deterministic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 10:43:10 +08:00
Akuria f55b18ffd7
fix: update primary color when toggling dark/light mode with custom theme (#7909)
When a custom theme is selected and the user toggles between dark and
light mode, the primary color was not being recalculated. This was caused
by a guard condition in the builtin theme watcher that skipped updating
themeColorPrimary for custom themes during mode changes.

Remove the guard so that the primary color is always recalculated from
the theme preset when the mode changes, ensuring Element Plus CSS
variables stay in sync.

Fixes #6615
2026-05-16 10:42:35 +08:00
Akuria ca5931e8c4
fix: preserve tree default value when treeData starts empty (#7908)
When treeData is initially an empty array (e.g. before async data
arrives), updateTreeValue() would clear the modelValue because no
matching items could be found in the empty flattened data. This caused
default values to be lost.

Only call updateTreeValue() when flattenData has items, so that
modelValue is preserved until the actual tree data arrives.

Fixes #6522
2026-05-16 10:41:42 +08:00
XuZhiqiang ccfc122eae fix(@vben/web-antdv-next): 将依赖从 @form-create/ant-design-vue 改为 @form-create/antdv-next 2026-05-15 18:05:31 +08:00
xingyu 59183029b6
!341 fix: 修复禁用的删除按钮仍然可以点击的问题
Merge pull request !341 from li_shifeng/fix-dept-delete
2026-05-14 08:29:04 +00:00
xingyu e81ca2c13f
!343 fix(@vben/web-antdv-next): 修复 InputNumber 组件宽度在表单中不占满的问题
Merge pull request !343 from XuZhiqiang/feat-antdv-next
2026-05-14 08:03:20 +00:00
XuZhiqiang dcccef1c02 fix(@vben/web-antdv-next): 修复 InputNumber 组件宽度在表单中不占满的问题 2026-05-13 15:47:52 +08:00
XuZhiqiang 9a5bee4dce fix(@vben/web-antdv-next): adapter修正组件名称TextArea一致的大小写格式 2026-05-13 15:20:15 +08:00
xingyu 29665f02bf
!342 feat(@vben/web-antdv-next): migrate ant-design-vue to antdv-next
Merge pull request !342 from XuZhiqiang/feat-antdv-next
2026-05-12 13:46:18 +00:00
XuZhiqiang 06f776d1ef feat(@vben/web-antdv-next): 替换 antdv-next 中不可用的 List 组件,手动迁移为 div 结构,后续组件库新增 Listy 组件在进行替换 2026-05-12 16:37:42 +08:00
XuZhiqiang 40f0ba71f5 feat(@vben/web-antdv-next): migrate ant-design-vue to antdv-next
Migration Summary: ant-design-vue → antdv-next
Core Changes
package.json - Replaced "ant-design-vue": "catalog:" with "antdv-next": "catalog:"

bootstrap.ts - Changed @vben/styles/antd to @vben/styles/antdv-next

adapter/component/index.ts - Major rewrite:

Removed dynamic defineAsyncComponent imports from ant-design-vue/es/...
Added static imports from antdv-next main entry
Renamed RangePicker → DateRangePicker, Textarea → TextArea
Defined local types for Rule, Locale, UploadRequestOption, FileType, Key
Bulk Import Replacements (100+ files)
from ant-design-vue → from antdv-next
from ant-design-vue/es/locale/... → from antdv-next/locale/...
from ant-design-vue/es/... → removed (use main entry)
from ant-design-vue/lib/... → removed (use main entry)
Component API Differences Handled
ant-design-vue	antdv-next	Files affected
Form.Item	FormItem	475 references
Tabs.TabPane	TabPane	240 references
Select.Option	SelectOption	151 references
Descriptions.Item	DescriptionsItem	2 references
Timeline.Item	TimelineItem	2 references
Radio.Group	RadioGroup	20 references
Collapse.Panel	CollapsePanel	9 references
Layout.Content/Sider/Header/Footer	LayoutContent/LayoutSider/...	14 references
Dropdown#overlay slot	Dropdown#popupRender	6 references
RangePicker	DateRangePicker	15+ references
Textarea	TextArea	37 references
ButtonGroup	Space (fallback)	12 references
Known Issues (requires manual attention)
List component - Not available in antdv-next. 4 files have TODO comments where List/List.Item/List.Item.Meta are used
@form-create/ant-design-vue - Kept as-is (compatible with antdv-next at runtime)
Type errors - ~366 type errors remain (vs 189 in web-antd), mostly pre-existing business logic issues and minor API differences
2026-05-12 15:30:08 +08:00
XuZhiqiang 0fced45a9c refactor(@vben/web-antdv-next): 根据web-antd初始化web-antdv-next 2026-05-12 12:14:32 +08:00
li_shifeng 2ea7da06c5 fix: 修复禁用的删除任然可以点击的问题 2026-05-11 14:13:23 +08:00
JyQAQ aac4e88353
docs(@vben/docs): 添加 VCropper 图片裁剪组件文档 (#7904)
* docs(@vben/docs): 添加 VCropper 图片裁剪组件文档

- 新增中文文档 docs/src/components/common-ui/vben-cropper.md
- 新增英文文档 docs/src/en/components/common-ui/vben-cropper.md
- 新增基础用法示例 demos/vben-cropper/basic
- 新增固定比例裁剪示例 demos/vben-cropper/aspect-ratio
- 更新侧边栏配置添加 Cropper 入口

* fix: 更正跨域图片描述并修复 demo 内存泄漏

- 文档更正:网络图片导出裁剪结果需服务端 CORS 支持
- 修复 URL.createObjectURL 内存泄漏:添加 revokeObjectURL 释放
2026-05-11 12:50:44 +08:00
xueyitt 30356a24e6
fix: 修正vxtable不存在formConfig时,直接变更data失效问题
修正vxtable不存在formConfig时,直接变更data失效问题
2026-05-11 10:09:47 +08:00
MistyMoon ba60bc3c14
fix(@vben/layouts): correct logo theme in semi-dark sidebar (#7785) (#7902) 2026-05-10 10:41:43 +08:00
JyQAQ f5feddc6c7
feat(@vben/plugins): tiptap 组件新增 maxHeight 属性支持及文档 (#7897)
* feat(@vben/plugins): tiptap 组件新增 maxHeight 属性支持

- 新增 maxHeight prop 支持限制编辑器最大高度
- 编辑器内容区超出最大高度时自动滚动
- 移除 style.css 中未使用的 CSS 规则

* docs(@vben/plugins): 添加 tiptap 富文本编辑器组件文档

- 新增中文文档 docs/src/components/common-ui/vben-tiptap.md
- 新增英文文档 docs/src/en/components/common-ui/vben-tiptap.md
- 新增基础用法示例 demos/vben-tiptap/basic
- 新增图片上传示例 demos/vben-tiptap/image-upload
- 更新文档侧边栏配置

* fix(@vben/plugins): extract URL from response in image upload callback

The upload callback was incorrectly passing the AxiosResponse object
to resolve() instead of extracting the actual image URL string.
This caused the editor to insert [object Object] as image src,
resulting in broken images.

* chore: add changeset for tiptap maxHeight feature

* Revert "chore: add changeset for tiptap maxHeight feature"

This reverts commit a28fc4441f14641f6af6c1a143aa6959591315b2.
2026-05-10 10:38:21 +08:00
Yanghai.Lin 0868deb82b
fix: 修复 Input 组件 focus 边框被裁剪问题 (#7894)
* fix(other): 修复 oxlint ignorePatterns 导致 pre-commit hook 失败

* fix(@vben-core/shadcn-ui): 修复 Input 组件 focus 时边框被父容器 overflow hidden 裁剪

* fix(@vben-core/shadcn-ui): 修复 SelectTrigger 组件 focus 时边框被父容器 overflow hidden 裁剪
2026-05-10 10:37:39 +08:00
layhuts 1299acd8f9 fix: 获取已存在的 key,避免重复写入刷新过期时间 2026-05-09 23:27:25 +08:00
layhuts 43717807a4 style: reformat code 2026-05-09 23:18:44 +08:00
layhuts 1b4e126128 fix: 处理localStorageDriver在某些受限浏览器环境下报错导致无法使用 2026-05-09 23:10:05 +08:00
layhuts d23b246aee fix: 处理localStorage prefix === ''时提醒用户可能会全部删除数据 2026-05-09 23:04:38 +08:00
layhuts 71f2e5f504 fix: 去除onConfirm中的setTimeout 2026-05-09 22:51:39 +08:00
layhuts 4bbd34fab9 fix: 修复 labelField 和 nameField 2026-05-09 22:28:03 +08:00
layhuts 08e4bb40b4 style: reformat code 2026-05-09 18:28:23 +08:00
layhuts 9c49f4bb1e refactor: 优化viewed实例初始化,rowStyle rowClassName 从最新的配置中读取 2026-05-09 18:27:09 +08:00
layhuts 28905b0bec style: reformat code 2026-05-09 14:08:19 +08:00
layhuts bbcad709ca style: 修改注释 2026-05-09 14:07:30 +08:00
layhuts a5f0537cb0 fix: 处理viewedKeys由于 FIFO 顺序,显式提供的值可能会被异步存储恢复静默地移除。 2026-05-09 13:38:50 +08:00
layhuts c78d89f549 fix: 处理非原子性的先清除后写入操作会setKeys带来永久性数据丢失的风险 2026-05-09 13:16:50 +08:00
layhuts f2a17cbe78 fix: 处理getViewedKeys()返回对内部可变对象的直接引用问题 2026-05-09 13:10:41 +08:00
layhuts 9667232684 fix: 加上 - 分隔符来避免跨前缀误匹配 2026-05-09 12:56:50 +08:00
layhuts 1f584ff0c9 fix: 处理window不可用时降级使用Memory 2026-05-09 12:49:21 +08:00
layhuts 75ed17a1f9 docs: 更正saveToCache所属组件 2026-05-09 12:41:10 +08:00
layhuts cc6ccaab38 docs: 为符合 Markdown lint 规范,指定代码块语言。 2026-05-09 12:38:13 +08:00
layhuts 0be4b51eaa fix: 解决window在构造函数中进行访问破坏SSR/Node环境。 2026-05-09 12:33:15 +08:00
layhuts b40822e3ed fix: 解决indexedDB的getDB在失败重试时永远返回错误Promise问题 2026-05-09 12:02:41 +08:00
layhuts df5cb426d1 fix: 解决indexedDB的setItem、,removeItem以及clear在请求成功时而不是事务完成时触发resolve问题 2026-05-09 11:54:11 +08:00
layhuts 2d36d6b510 style: reformat code 2026-05-09 11:03:47 +08:00
layhuts 88d5661e0c refactor: 重构ViewedRowPersistOptions处理扁平化问题
改成按 type 字段区分的联合类型
2026-05-09 11:02:16 +08:00
layhuts 8ce773f264 feat: 在storage-manager添加keys方法 2026-05-09 10:58:41 +08:00
layhuts 329fa68207 fix: 手动操作行标记示例时动态获取列表前两行 2026-05-09 09:23:10 +08:00
layhuts e1f6449073 feat: 表格已读行操作标记 2026-05-08 20:03:05 +08:00
layhuts 51e8b27d4c style(@vben-core/shared): formatting 2026-05-08 17:36:47 +08:00
layhuts e555ee065e feat(@vben-core/shared): 新增indexedDB
在cache下新增indexedDB缓存
2026-05-08 17:34:54 +08:00
YunaiV c164904a14 chore: 合并 github/master,引入 PR #259 BPMN 流程设计器审批节点自定义配置编辑后丢失修复 2026-05-04 00:36:22 +08:00
芋道源码 a0ceb45df9
Merge pull request #259 from lb1565387341/fix_bpmn_custom_user_config
fix: [bpm][antd&ele] 修复流程设计器自定义配置编辑后丢失的问题
2026-05-04 00:26:29 +08:00
YunaiV c641542c71 fix(bpm):修正 BPM 流程实例审批弹窗网关分支重算的并发与提交问题
- 提交时不再用节点表单值覆盖 data.variables;与预览阶段使用同一份合并变量
- onChange 加 useDebounceFn(300ms) + 请求序号去重,handleAudit 提交前 await 最新一轮重算
- 切换任务时重置请求序号与 pending 重算
- 改用 form-create 官方 formData() 取节点表单当前值
- 节点表单初始化等 fApi 就绪后再计算下一节点(until + 1s 兜底)

同步至 web-antd / web-ele 两端
2026-05-03 16:35:03 +08:00
Lin b5dacd992f
feat: add time zone option to preference settings (#7871) 2026-05-03 12:16:58 +08:00
YunaiV a3d8e4bfc1 feat: 添加包含和不包含条件选项到常量定义 2026-05-03 11:04:58 +08:00
YunaiV e385823d46 fix: 修复 Vben5.0 form-create 多图上传校验拒绝 png/jpeg/gif,isImage 兼容 MIME 与扩展名两种 accept 写法 2026-05-02 22:56:38 +08:00
YunaiV 897220e19a fix: 修复 Vben5.0 download 接口 token 过期不触发刷新,导出/下载文件变成「账号未登录」JSON;web-antd / web-ele / web-naive / web-tdesign 加 Blob 业务错误嗅探拦截器 2026-05-02 20:36:00 +08:00
YunaiV b293e112c6 fix: 修复 MALL 商品保存时 SKU 价格被反复 *100 的漂移 2026-05-02 20:23:43 +08:00
YunaiV 627e31f1b0 fix: 修复 Vben5.0 CRM 合同配置 / 客户公海规则配置表单 label 错用 `labelClass: 'w-100'`,Tailwind v4 动态间距下被解析为 400px 撑爆 `w-1/4` 容器,挤掉 RadioGroup 输入区,改用 `labelWidth: 120` 2026-05-02 19:44:21 +08:00
YunaiV 8020b4b743 fix: 修复 MALL 商品列表/选择器「价格」列展示原始的「分」(web-antd / web-ele)
商品列表 [mall/product/spu/data.ts] 与商品选择器 [mall/product/spu/components/spu-select-data.ts]
的「价格」列原先 formatter: 'formatAmount2',只做了小数格式化、漏了「分转元」,导致
19900 直接显示成 19900.00(应为 199.00 元)。同文件的 marketPrice / costPrice 已正确使用
fenToYuan,唯独 price 漏了。

顺手将 spu/data.ts 的 price / marketPrice / costPrice 三列从手写闭包统一切到已注册的
formatFenToYuanAmount formatter,单位「元」从 cell 后缀挪进列标题(如「价格(元)」),
减少 8 处闭包并复用平台统一的 null/NaN 处理。
2026-05-02 19:38:50 +08:00
YunaiV 228c5463da fix: 修复 IoT 物模型表单 Form.Item 嵌套字段 name 误用点号字符串,事件类型等校验始终失败 / resetFields 写错路径 2026-05-02 19:27:35 +08:00
YunaiV 50ee691191 fix: 修复 web-ele 下 ApiSelect / ApiTreeSelect 误用 antd 的 fieldNames 写法导致下拉无内容
element-plus 适配器走 ApiComponent,识别的是 labelField / valueField / childrenField;
而 fieldNames 是 antd 风格写法,从 web-antd 复制过来未做适配,导致内部数据无法被映射成
{ label, value, children },下拉树/列表显示为空。

涉及:
- CRM 客户 / 联系人 / 线索 新增表单的「地址」树
- CRM 商机状态「应用部门」、产品「产品类型」树
- ERP 销售出库的 客户 / 销售人员 / 结算账户 / 产品 / 创建人 下拉
2026-05-02 18:55:48 +08:00
YunaiV eda6ffaf1e fix: 修复 web-ele 下 ApiSelect / ApiTreeSelect 误用 antd 的 fieldNames 写法导致下拉无内容
element-plus 适配器走 ApiComponent,识别的是 labelField / valueField / childrenField;
而 fieldNames 是 antd 风格写法,从 web-antd 复制过来未做适配,导致内部数据无法被映射成
{ label, value, children },下拉树/列表显示为空。

涉及:
- CRM 客户 / 联系人 / 线索 新增表单的「地址」树
- CRM 商机状态「应用部门」、产品「产品类型」树
- ERP 销售出库的 客户 / 销售人员 / 结算账户 / 产品 / 创建人 下拉
2026-05-02 18:53:11 +08:00
Jin Mao d55f17670a chore: 更新依赖包版本
- 更新 pkg-types 从 2.3.0 到 2.3.1
- 更新 rolldown 从 1.0.0-rc.15 到 1.0.0-rc.17
- 更新 typescript 从 6.0.2 到 6.0.3
- 更新 vite 从 8.0.8 到 8.0.10
2026-05-01 06:55:42 +08:00
Jin Mao 9f20d52b4e chore: 更新 FTP 部署操作版本
- 将 SamKirkland/FTP-Deploy-Action 从 v4.3.6 升级到 v4.4.0
- 所有部署任务中的 FTP 操作均已更新到新版本
- 保持了所有现有配置和凭据不变
2026-05-01 06:53:06 +08:00
Jin Mao 86445a38e4 Merge branch 'fork/jyqwq/feature/富文本支持图片上传' 2026-05-01 06:49:48 +08:00
leo 9a73e961fc
fix(@vben/stores): respect base URL when opening route in new window (#7837)
* fix(@vben/stores): respect base URL when opening route in new window

* fix(@vben/stores): respect base URL when opening route in new window
2026-05-01 06:49:05 +08:00
boisduval c0b2ef980e
fix: 修复 IconPicker 在手动输入时表单值不更新的问题 (#7869)
- 修复 IconPicker.vue 在 updateCurrentSelect 时未同步更新 modelValue 的 Bug
- 优化 IconPicker 适配器配置,使其兼容 Element Plus 的 ElInput 组件
2026-04-30 15:46:07 +08:00
mew e8dc464e79
fix: issue in tab bar chrome height is not full due to wrapper element `div` (#7867)
Caused by PR #7858
2026-04-30 15:45:44 +08:00
mew 99c38c93c8
feat: refactor context menu to capture native events (#7858)
* feat: refactor context menu to capture native events

prevent context-menu to show in html input fields

* fix: refactor context-menu.vue for improved structure

* chore: fix format

* chore: remove dead code

* chore: fix lint

* fix: update contenteditable selector in context menu

proposed fixed by coderabitai
2026-04-28 13:36:13 +08:00
yuan.ji 244c0a5884 fix(@vben/plugins): 根据代码审查意见修复 tiptap 图片上传
- 提取 findPlaceholderPos 辅助函数,消除重复的 descendants 查找
- 添加 editor.isDestroyed 守卫,防止操作已销毁编辑器
- renderHTML 不输出上传状态属性,防止 blob URL 泄露到序列化 HTML
- uploadImage 命令返回 boolean,添加 Commands 类型增强,移除 as any
- 拖拽/粘贴多图时仅处理第一张并提示仅支持单图上传
- 自定义 extensions 时不传 imageUpload 给工具栏,toolbar action 加运行时守卫
2026-04-27 14:33:30 +08:00
yuan.ji c6fd599784 feat(@vben/plugins): 补充 tiptap 图片上传类型、工具栏和示例
- 新增 ImageUploadOptions 类型定义和 imageUpload 属性
- 工具栏图片按钮支持上传/URL 双模式
- playground 添加图片上传 mock 示例
2026-04-27 13:42:56 +08:00
yuan.ji 4ca2f1c6e8 feat(@vben/plugins): tiptap 支持图片上传功能
- 新增 imageUpload 配置项,支持自定义上传接口
- 支持文件选择、拖拽、粘贴三种上传方式
- 上传中显示 blob 预览图 + loading spinner / 进度条
- 支持 accept 和 maxSize 文件校验
- 支持 onUploadError 自定义错误处理
- 未配置 imageUpload 时保持原有 URL 插入行为不变
- 使用 NodeView 实现实时 DOM 控制的进度展示
2026-04-27 13:42:36 +08:00
Jin Mao 36d7dc23fa Merge branch 'fork/zilvya/ta1' 2026-04-26 16:26:30 +08:00
Lgf 42317ddf41 feat(watermark): 添加暗黑模式水印颜色适配
为水印功能添加暗黑模式适配,根据当前主题自动切换水印颜色。在暗黑模式下使用浅色水印,在亮色模式下使用深色水印,提升视觉体验。
2026-04-24 15:42:07 +08:00
boisduval c7fd6ffb0e feat: 添加日期格式化函数的空值处理
- 当传入的时间参数为 undefined、null 或空字符串时,直接返回空字符串而不是继续执行格式化逻辑,避免无效的时间值导致程序错误。
2026-04-23 17:25:10 +08:00
AxiosLeo 3a83fb0c3e
fix: ensure trigger function is awaited in useDependencies (#7830) 2026-04-22 07:09:09 +08:00
AxiosLeo 5907c04e00
fix: update selector for active menu item in useMenuScroll hook (#7829) 2026-04-22 07:08:40 +08:00
Jin Mao 6885927441 chore: fix actions error 2026-04-15 18:49:07 +08:00
2ylllll c8c589ae7e
fix: type check (#7818) 2026-04-15 18:11:06 +08:00
Jin Mao d0889b5cc4 chore: 更新依赖包版本
- 更新 @tsdown/css 从 0.21.7 到 0.21.8
- 更新 @vitejs/plugin-vue 从 6.0.5 到 6.0.6
- 更新 dotenv 从 17.4.1 到 17.4.2
- 更新 globals 从 17.4.0 到 17.5.0
- 更新 happy-dom 从 20.8.9 到 20.9.0
- 更新 oxlint 从 1.59.0 到 1.60.0
- 更新 tsdown 从 0.21.7 到 0.21.8
2026-04-15 17:28:17 +08:00
Jin Mao 2f1a866cb4 chore: 更新 pnpm action 版本
- 将 .github/actions/setup-node/action.yml 中的 pnpm/action-setup 从 v4 升级到 v6
- 将 .github/workflows/ci.yml 中的 pnpm/action-setup 从 v5 升级到 v6
- 移除重复的 pnpm 安装步骤配置
- 统一使用最新的 pnpm action 版本以获得更好的兼容性
- 保持 run_install 配置为 false 以跳过自动安装依赖
2026-04-15 17:27:57 +08:00
Jin Mao fee32c1d12 chore: 优化通知组件逻辑
- 移除冗余的空值检查,简化数组长度判断条件
- 统一导入语句的引号格式为双引号
- 优化 VbenScrollbar 组件的显示条件逻辑
- 更新清除按钮的禁用状态判断逻辑
2026-04-15 17:22:39 +08:00
Jin Mao f2652833a1 Merge branch 'fork/xueyitt/main' 2026-04-15 17:20:10 +08:00
allen c3aa63982f fix: devtools warning 2026-04-15 16:44:13 +08:00
allen 4a968d9379 fix: devtools warning 2026-04-15 16:39:56 +08:00
allen ec9b323195 docs: demo注释修改 2026-04-15 14:54:40 +08:00
allen d69455e8ef fix: dependencies访问extendApi 2026-04-15 14:42:21 +08:00
allen 33e2582f60 fix: fix lint and add new form-ui features
feat(form-ui): 在 dependencies 里提供访问extendApi的能力
2026-04-15 14:21:39 +08:00
allen 991408b451 fix: default precision error 2026-04-13 21:08:03 +08:00
allen a096073a8e fix: lint 2026-04-13 20:43:29 +08:00
allen f30157fa59 fix: class 2026-04-13 20:41:43 +08:00
allen 12a81a7a7d fix: demo validator usage & types import 2026-04-13 20:15:47 +08:00
allen e808fe74c1 Merge branch 'feature-collapsible-component' of https://github.com/2yllll/vue-vben-admin into feature-collapsible-component 2026-04-13 19:44:45 +08:00
allen 4665a787a0 fix: collapsible component css fix 2026-04-13 19:44:21 +08:00
2ylllll b7774fc9d9
Merge branch 'main' into feature-collapsible-component 2026-04-13 19:26:23 +08:00
allen 6f18718c87 feat: add collapsible 组件,form表单增加单项可折叠,支持schema配置默认关闭/开启
feat: add collapsible 组件,form表单增加单项可折叠,支持schema配置默认关闭/开启
- shadcn-ui 增加 collapsible组件,collapsible-params组件
- form新增支持单项折叠
- collapsible-params组件在Form表单应用
2026-04-13 19:20:01 +08:00
Caisin 2a32715c99 feat: enable project-scoped preferences extension tabs (#7803)
* feat: enable project-scoped preferences extension tabs

Add a typed extension schema so subprojects can define extra settings,
render them in the shared preferences drawer only when configured, and
consume them in playground as a real feature demo. Extension labels now
follow locale keys instead of hardcoded app-specific strings.

Constraint: Reuse the shared preferences drawer and field blocks
Rejected: Add app-specific fields to core preferences | too tightly coupled
Rejected: Inline localized label objects | breaks existing locale-key flow
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep extension labels as locale keys rendered via $t in UI
Tested: Vitest preferences tests
Tested: Turbo typecheck for preferences, layouts, web-antd, and playground
Tested: ESLint for touched preferences and playground files
Not-tested: Manual browser interaction in playground preferences drawer

* fix: satisfy lint formatting for preferences extension demo

Adjust the playground preferences extension demo template so formatter and
Vue template lint rules agree on the rendered markup. This keeps CI green
without changing runtime behavior.

Constraint: Must preserve the existing demo behavior while fixing CI only
Rejected: Disable the Vue newline rule | would weaken shared lint guarantees
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Prefer computed/template structures that avoid formatter-vs-lint conflicts
Tested: pnpm run lint
Not-tested: Manual browser interaction in playground preferences extension demo

* fix: harden custom preferences validation and i18n labels

Tighten custom preferences handling so numeric extension fields respect
min, max, and step constraints. Number inputs now ignore NaN values,
and web-antd extension metadata uses locale keys instead of raw strings.
Also align tip-based hover guards in shared preference inputs/selects.

Constraint: Keep fixes scoped to verified findings only
Rejected: Broader refactor of preferences field components | not needed for these fixes
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Reuse the same validation path for updates and cache hydration
Tested: Vitest preferences tests
Tested: ESLint for touched preferences and widget files
Tested: Typecheck for web-antd, layouts, and core preferences
Not-tested: Manual browser interaction for all preference field variants

* fix: remove localized default from playground extension config

Drop the hardcoded Chinese default value from the playground extension
report title field and fall back to an empty string instead. This keeps
extension config locale-neutral while preserving localized labels and
placeholders through translation keys.

Constraint: Keep the fix limited to the verified localized default issue
Rejected: Compute the default from runtime locale in config | unnecessary for this finding
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Avoid embedding localized literals in extension default values
Tested: ESLint for playground/src/preferences.ts
Tested: Oxfmt check for playground/src/preferences.ts
Not-tested: Manual playground preferences interaction

* docs: document project-scoped preferences extension workflow

Add Chinese and English guide sections explaining how to define,
initialize, read, and update project-scoped preferences extensions.
Also document numeric field validation and point readers to the
playground demo for a complete example.

Constraint: Keep this docs-only and aligned with the shipped API
Rejected: Update only Chinese docs | would leave English docs inconsistent
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep zh/en examples and playground demo paths synchronized
Tested: git diff --check; pnpm build:docs
Not-tested: Manual browser review of the rendered docs site

* fix: harden custom preferences defaults and baselines

Use a locale-neutral default for the web-antd report title.
Also stop preference getters from exposing mutable baseline
or extension schema objects, and add a regression test for
external mutation attempts.

Constraint: Keep behavior compatible with the shipped preferences API
Rejected: Return raw refs with readonly typing only | callers could still mutate internals
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep defensive copies for baseline and schema getters unless storage semantics change
Tested: eslint, oxlint, targeted vitest, filtered typecheck, git diff --check
Not-tested: Full monorepo typecheck and test suite

* test: relax custom preference cache key matching

Avoid coupling the custom-number cache test to one exact
localStorage key string. Match the intended cache lookup
more loosely so the test still verifies filtering behavior
without depending on the full namespaced cache key.

Constraint: Focus the test on cache filtering behavior
Rejected: Assert one exact key | brittle with namespace changes
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Prefer behavior tests over literal storage keys
Tested: targeted vitest, eslint, git diff --check
Not-tested: Full monorepo test suite

---------

Co-authored-by: caisin <caisin@caisins-Mac-mini.local>
2026-04-13 17:52:17 +08:00
Caisin 46f323431c feat(form-ui): support schema valueFormat for getValues payload shaping (#7804)
* feat(@vben-core/form-ui): support schema valueFormat on getValues

Some form fields emit UI-friendly structures such as time-range arrays,
while consumers and backend APIs often need a different payload shape.
This adds schema-level `valueFormat` hooks so `getValues()` can
normalize field output at read time without forcing callers to
post-process every submission path.

Constraint: Must preserve existing range-time mapping and nested field behavior
Constraint: Must not mutate live vee-validate form state while formatting output
Rejected: Global formatter config | too coarse for per-field payload shaping
Rejected: Post-submit-only transform | misses reset/query/change handlers
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep `getValues()` output derivation side-effect free
Directive: Clone raw form values before formatting derived payloads
Tested: vitest form-api test for valueFormat and existing getValues paths
Tested: oxlint on changed form-ui source and test files
Not-tested: Full repo typecheck baseline has unrelated .vue module resolution errors

* fix(@vben-core/form-ui): restore mount compatibility and share field path parsing

Follow-up review found two real regressions and one missing assertion in the
new value formatting flow. `FormApi.mount()` had become breaking by requiring
`componentRefMap`, and delete path resolution duplicated field-name parsing
instead of sharing the reader grammar. This patch restores backward
compatibility, centralizes field-name path parsing, and extends the test to
prove formatting does not mutate live form values.

Constraint: Must preserve current valueFormat behavior and nested field support
Constraint: Must not reintroduce mutation of live vee-validate values
Rejected: Keep duplicated delete parsing | risks grammar drift from read path
Rejected: Only loosen mount tests | would leave consumer-facing API breakage
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Reuse shared field-name parsing for read/delete semantics in form-ui
Tested: vitest form-api test suite
Tested: oxlint on changed form-ui files
Not-tested: Full repo typecheck baseline has unrelated .vue module resolution errors
EOF && git push hekx feature-form-value-format

* fix(@vben-core/form-ui): clear stale component refs on unmount

A follow-up review found that `unmount()` left the private component ref map
populated. Because `mount()` now accepts an optional `componentRefMap`, a later
mount without a new map could silently reuse stale refs from a prior form
instance. This change clears the ref map on unmount and adds a regression test
covering remount behavior without a new ref map.

Constraint: Must preserve backward-compatible optional `mount()` ref map behavior
Constraint: Focus and field-ref lookups must not observe stale refs after unmount
Rejected: Clear refs only during next mount | stale state would still leak between lifecycle calls
Rejected: Remove mount fallback entirely | would undo the compatibility fix
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When mount falls back to internal refs, unmount must always reset that cache
Tested: vitest form-api test suite
Tested: oxlint on changed form-api source and test files
Not-tested: Full repo typecheck baseline has unrelated .vue module resolution errors

* refactor(@vben-core/form-ui): trim redundant valueFormat plumbing

Review feedback identified a few small cleanups in the value formatting path.
This removes an unnecessary shallow clone in `getValues()`, reuses the
already-parsed `rawKey` from `resolveFieldNamePath()` instead of re-resolving
it in multiple helpers, and clarifies the `FormValueFormat` contract for
undefined-as-delete decomposition behavior.

Constraint: Must not change runtime valueFormat behavior or payload shape
Constraint: Documentation and helper cleanup should stay behavior-preserving
Rejected: Leave duplicate raw-key resolution in place | adds needless parsing churn
Rejected: Expand the formatter API further | outside the scope of this cleanup
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep read/format helper plumbing lean and avoid duplicate field-name parsing
Tested: vitest form-api test suite
Tested: oxlint on changed form-ui source and test files
Not-tested: Full repo typecheck baseline has unrelated .vue module resolution errors

* feat(@vben-core/form-ui): document valueFormat with live examples

The new `valueFormat` feature needed a concrete usage path in both the
playground and the docs so users can understand how raw component values differ
from the final payload returned by `getValues()`. This adds a dedicated form
example, wires it into the playground menu, and documents the API with an
interactive docs demo. The preview panels now stay in sync when values are set,
reset, or submitted.

Constraint: Must demonstrate both return-value and setValue decomposition flows
Constraint: Example previews must react to setValues, reset, and manual edits
Rejected: Only document via markdown snippet | insufficient for verifying live payload behavior
Rejected: Reuse an existing basic form page | would bury feature-specific behavior
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep playground and docs demos behaviorally aligned when extending valueFormat examples
Tested: eslint on playground/docs valueFormat demo files and route module
Tested: oxlint on playground route module
Not-tested: Full docs/playground app runtime was not launched in this session

* chore(@vben-core/form-ui): normalize valueFormat demo formatting

The previous feature/docs commit left a few formatter-only adjustments unstaged
after hooks rewrote line wrapping in the new demo and docs pages. This commit
captures those final non-behavioral formatting updates so the branch matches the
current working tree.

Constraint: Must not change runtime behavior or docs meaning
Rejected: Leave post-hook diffs unstaged | branch would not reflect local state
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: After hook-driven rewrites, verify the working tree is clean before final push
Tested: Git diff inspection of remaining changes
Not-tested: No additional runtime verification needed; formatting-only follow-up
EOF && git push hekx feature-form-value-format

* fix(@vben-core/form-ui): remove docs demo dayjs dependency

The docs valueFormat demo imported `dayjs` directly even though the docs
package does not declare it as a dependency. That caused `@vben/docs:build`
to fail in CI during VitePress bundling. This change removes the direct
import, keeps the preview formatter generic for day-like values, and drops
the docs-only preset button that required constructing dayjs instances.

Constraint: Docs build must succeed without adding new package dependencies
Constraint: Playground example should remain unchanged and fully interactive
Rejected: Add dayjs to docs dependencies | unnecessary for a small display demo
Rejected: Externalize dayjs in VitePress build | hides a package boundary issue
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Docs demos should avoid imports only available through transitive deps
Tested: pnpm exec eslint docs/src/demos/vben-form/value-format/index.vue
Tested: pnpm --dir docs run build
Not-tested: No browser-side manual verification of the docs demo in this session

---------

Co-authored-by: caisin <caisin@caisins-Mac-mini.local>
2026-04-13 17:52:17 +08:00
Caisin 2b1fcb038b feat(common-ui): add labelFn support to ApiComponent (#7801)
* feat: allow api-component labels to be derived from option data

ApiComponent already normalizes option records into the label/value shape used by
consuming controls, but label text could only come from a single field. Add
labelFn so callers can build labels from the full option record while keeping
labelField as the fallback path.

This keeps the change inside the existing component instead of introducing a
wrapper, and it also normalizes direct options through the same transform path
as API-loaded options for consistent behavior.

Constraint: Must extend the existing ApiComponent API instead of adding a second
Constraint: wrapper component
Rejected: Add a separate ApiLabelComponent wrapper |
Rejected: extra surface area for one option-mapping concern
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep labelFn as a presentation transform and preserve labelField
Directive: fallback for existing callers
Tested: pnpm exec eslint api-component.vue index.ts types.ts
Tested: pnpm exec vue-tsc --noEmit -p packages/effects/common-ui/tsconfig.json
Not-tested: runtime integration in consuming select/tree-select components

* Update packages/effects/common-ui/src/components/api-component/api-component.vue

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-04-13 17:52:17 +08:00
过冬 d779a39862 fix: antdv-next message/notification 跟随暗色主题 (#7799) 2026-04-13 17:52:17 +08:00
Jin Mao 0c8db0f6be fix: 修复VITE_APP_TITLE变量替换语法
- 将index.html中的<%= VITE_APP_TITLE %>替换为%VITE_APP_TITLE%
- 更新web-antd、web-antdv-next、web-ele、web-naive、web-tdesign应用
- 修改文档中loading组件的VITE_APP_TITLE引用方式
- 修复vite-config插件中默认加载模板的变量语法
- 统一所有应用和模板中的环境变量引用格式
2026-04-13 17:52:17 +08:00
Jin Mao 37393e1820 chore: fix actions error 2026-04-13 17:52:16 +08:00
xingyu4j 93e23c6b05 chore: update deps 2026-04-13 17:52:16 +08:00
xingyu4j e023a0852a fix: tailwindcss lint config 2026-04-13 17:52:16 +08:00
xingyu4j 306739cabb fix: lint 2026-04-13 17:52:16 +08:00
xingyu4j 093479bb33 chore: remove vite-plugin-html 2026-04-13 17:52:16 +08:00
xingyu4j bd369df3bc fix: check deps 2026-04-13 17:52:16 +08:00
xingyu4j 4f7b396ebb chore: update deps 2026-04-13 17:52:16 +08:00
xingyu4j d700b04841 fix: tailwindcss lint 2026-04-13 17:52:16 +08:00
xingyu4j 243456d928 fix: ts config 2026-04-13 17:52:16 +08:00
Jin Mao 7e8b9c2368 fix: 配置 TypeScript 构建根目录
- 添加 rootDir 编译选项指向 ./src 目录
- 保持现有编译配置不变
- 排除测试文件和 node_modules 目录
2026-04-13 17:52:15 +08:00
Jin Mao 92298bac2b chore: update deps 2026-04-13 17:52:15 +08:00
dullathanol 436a865bef chore: 修正注释 2026-04-13 17:52:15 +08:00
dullathanol 185011ee21 fix: tailwindcss config 2026-04-13 17:52:15 +08:00
过冬 feca01484b Merge branch 'vbenjs:main' into main 2026-04-13 17:52:15 +08:00
Jin Mao 35e1166b9f chore: fix lint 2026-04-13 17:52:15 +08:00
dullathanol d0c17090ef fix: 修正 Modal/Drawer 中 loading 属性注释 2026-04-13 17:52:15 +08:00
dullathanol cc32ebeb12 feat: 支持 overflow 配置以允许拖拽超出可视区 2026-04-13 17:52:15 +08:00
dullathanol 02372f12ba fix: 弹窗组件拖拽后全屏位置异常 2026-04-13 17:52:15 +08:00
Jin Mao e9bdbb610a chore: fix lint
- 关闭 vitest/require-mock-type-parameters 规则
2026-04-13 17:52:15 +08:00
dullathanol 2013ba4de4 fix: 补全 ComponentPropsMap 与 Vxe 表格表单链路的类型 2026-04-13 17:52:15 +08:00
dullathanol e417a2c209 fix: 修复 FormField 在 SFC 中的运行时异常 2026-04-13 17:52:14 +08:00
dullathanol f1273571c7 fix: 修复部分情况 component 类型丢失问题 2026-04-13 17:52:14 +08:00
dullathanol 064a6a20f0 feat: 表单 Schema 支持组件 Props 映射泛型,同步适配VxeGrid 2026-04-13 17:52:14 +08:00
dullathanol cb5e7e00f1 refactor: 简化 componentProps 回调的类型写法 2026-04-13 17:52:14 +08:00
dullathanol 5ed39c03a4 fix: 函数式 componentProps 按已注册 component 的 Props 校验返回值 2026-04-13 17:52:14 +08:00
dullathanol 794b103aa9 feat: Schema 中 componentProps 随注册组件联动类型提示 2026-04-13 17:52:14 +08:00
墨苒孤 c7b1bb3492 fix(form): 修复表单示例中 switch 组件无法切换的问题 (#7636) (#7763) 2026-04-13 17:52:14 +08:00
橙子 89349f8d91 fix: interface DropdownMenuProps don‘t have key prop (#7757) 2026-04-13 17:52:14 +08:00
HaroldZhangCode91 8e0b65a0e1 feat: fix oxlint error for oxlint upgrade (#7756)
1. remove unknown rule out of oxlint
2. add the corresponding back to eslint-config
3. fixed the eslint error for package.json
2026-04-13 17:52:13 +08:00
墨苒孤 b096e83f93 fix: make search case-insensitive (#7689) (#7755) 2026-04-13 17:52:13 +08:00
橙子 4a69c9e665 perf: replace `onUnMounted` to `tryOnScopeDispose` (#7747)
* perf: replace `onUnMounted` to `tryOnScopeDispose`

* perf: replace `onUnMounted` to `tryOnScopeDispose`
2026-04-13 17:52:13 +08:00
Jin Mao 7a60a081a2 chore: update deps 2026-04-13 17:52:13 +08:00
xingyu4j c693c854a7 fix: extension-document 2026-04-13 17:52:13 +08:00
xingyu4j 5eca357a5c feat(@vben/plugins): add tiptap rich text editor 2026-04-13 17:52:13 +08:00
xingyu4j 2930dcd78e chore: typescript config is expired‌ 2026-04-13 17:52:13 +08:00
xingyu4j e421d9d99b chore: update deps 2026-04-13 17:52:12 +08:00
xueyitt 6c029bfa32
Merge branch 'main' into main 2026-04-13 16:10:29 +08:00
雪忆天堂 fe77bc8bc9 feat: 通知模块自定义加强 2026-04-13 16:05:42 +08:00
liubei e136679934 fix: [bpm][antd&ele] 修复流程设计器自定义配置编辑后丢失的问题 2026-02-09 15:35:53 +08:00
4648 changed files with 556306 additions and 19213 deletions

View File

@ -0,0 +1,3 @@
{
"singleQuote": true
}

View File

@ -0,0 +1,7 @@
---
'@vben/styles': patch
'@vben-core/form-ui': patch
'@vben/web-naive': patch
---
feat(@core/form-ui): 新增 useVbenForm 数组编辑器 VbenFormFieldArray

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -6,7 +6,7 @@ runs:
using: 'composite'
steps:
- name: Install pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@v6
- name: Install Node.js
uses: actions/setup-node@v6

View File

@ -33,7 +33,7 @@ jobs:
fetch-depth: 0
- name: Install pnpm
uses: pnpm/action-setup@v5
uses: pnpm/action-setup@v6
with:
run_install: false

View File

@ -61,7 +61,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@ -89,6 +89,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: '/language:${{matrix.language}}'

View File

@ -30,7 +30,7 @@ jobs:
run: pnpm build:play
- name: Sync Playground files
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
uses: SamKirkland/FTP-Deploy-Action@v4.4.0
with:
server: ${{ secrets.PRO_FTP_HOST }}
username: ${{ secrets.WEB_PLAYGROUND_FTP_ACCOUNT }}
@ -54,7 +54,7 @@ jobs:
run: pnpm build:docs
- name: Sync Docs files
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
uses: SamKirkland/FTP-Deploy-Action@v4.4.0
with:
server: ${{ secrets.PRO_FTP_HOST }}
username: ${{ secrets.WEBSITE_FTP_ACCOUNT }}
@ -85,7 +85,7 @@ jobs:
run: pnpm run build:antd
- name: Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
uses: SamKirkland/FTP-Deploy-Action@v4.4.0
with:
server: ${{ secrets.PRO_FTP_HOST }}
username: ${{ secrets.WEB_ANTD_FTP_ACCOUNT }}
@ -116,7 +116,7 @@ jobs:
run: pnpm run build:ele
- name: Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
uses: SamKirkland/FTP-Deploy-Action@v4.4.0
with:
server: ${{ secrets.PRO_FTP_HOST }}
username: ${{ secrets.WEB_ELE_FTP_ACCOUNT }}
@ -147,7 +147,7 @@ jobs:
run: pnpm run build:naive
- name: Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
uses: SamKirkland/FTP-Deploy-Action@v4.4.0
with:
server: ${{ secrets.PRO_FTP_HOST }}
username: ${{ secrets.WEB_NAIVE_FTP_ACCOUNT }}

View File

@ -19,7 +19,7 @@ jobs:
steps:
# 关闭未活动的 Issues
- name: Close Inactive Issues
uses: actions/stale@v9
uses: actions/stale@v10
with:
days-before-stale: -1 # Issues and PR will never be flagged stale automatically.
stale-issue-label: needs-reproduction # Label that flags an issue as stale.

View File

@ -18,7 +18,7 @@ jobs:
steps:
- name: remove enhancement pending
if: github.event.label.name == 'enhancement'
uses: actions-cool/issues-helper@v3
uses: actions-cool/issues-helper-backup@d65454423c6fbbd20026b9b499d403f79422ac69
with:
actions: 'remove-labels'
token: ${{ secrets.GITHUB_TOKEN }}
@ -27,7 +27,7 @@ jobs:
- name: remove bug pending
if: github.event.label.name == 'bug'
uses: actions-cool/issues-helper@v3
uses: actions-cool/issues-helper-backup@d65454423c6fbbd20026b9b499d403f79422ac69
with:
actions: 'remove-labels'
token: ${{ secrets.GITHUB_TOKEN }}
@ -36,7 +36,7 @@ jobs:
- name: needs reproduction
if: github.event.label.name == 'needs reproduction'
uses: actions-cool/issues-helper@v3
uses: actions-cool/issues-helper-backup@d65454423c6fbbd20026b9b499d403f79422ac69
with:
actions: 'create-comment, remove-labels'
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -14,7 +14,7 @@ jobs:
if: github.repository == 'vbenjs/vue-vben-admin'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
- uses: dessant/lock-threads@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-inactive-days: '14'

View File

@ -3,60 +3,44 @@ name: Create Release Tag
on:
push:
tags:
- 'v*.*.*' # Push events to matching v*, i.e. v1.0, v20.15.10
env:
HUSKY: '0'
- 'v*.*.*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to create (e.g. v1.2.3)'
required: true
type: string
permissions:
pull-requests: write
contents: write
jobs:
build:
release:
name: Create Release
if: github.repository == 'vbenjs/vue-vben-admin'
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [22]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
# - name: Checkout code
# uses: actions/checkout@v6
# with:
# fetch-depth: 0
# - name: Install pnpm
# uses: pnpm/action-setup@v4
# - name: Use Node.js ${{ matrix.node-version }}
# uses: actions/setup-node@v4
# with:
# node-version: ${{ matrix.node-version }}
# cache: "pnpm"
# - name: Install dependencies
# run: pnpm install --frozen-lockfile
# - name: Test and Build
# run: |
# pnpm run test
# pnpm run build
- name: version
- name: Extract version
id: version
run: |
tag=${GITHUB_REF/refs\/tags\//}
version=${tag#v}
major=${version%%.*}
echo "tag=${tag}" >> $GITHUB_OUTPUT
echo "version=${version}" >> $GITHUB_OUTPUT
echo "major=${major}" >> $GITHUB_OUTPUT
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
raw_tag="${{ inputs.tag }}"
else
raw_tag="${GITHUB_REF_NAME}"
fi
# Normalize: ensure v prefix
tag="${raw_tag}"
[[ "${tag:0:1}" != "v" ]] && tag="v${tag}"
version="${tag#v}"
major="${version%%.*}"
echo "tag=${tag}" >> "${GITHUB_OUTPUT}"
echo "version=${version}" >> "${GITHUB_OUTPUT}"
echo "major=${major}" >> "${GITHUB_OUTPUT}"
- uses: release-drafter/release-drafter@v7
with:
@ -64,17 +48,3 @@ jobs:
publish: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: force update major tag
# run: |
# git tag v${{ steps.version.outputs.major }} ${{ steps.version.outputs.tag }} -f
# git push origin refs/tags/v${{ steps.version.outputs.major }} -f
# - name: Create Release for Tag
# id: release_tag
# uses: ncipollo/release-action@v1
# with:
# token: ${{ secrets.GITHUB_TOKEN }}
# generateReleaseNotes: "true"
# body: |
# > Please refer to [CHANGELOG.md](https://github.com/vbenjs/vue-vben-admin/blob/main/CHANGELOG.md) for details.

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Validate PR title
uses: amannn/action-semantic-pull-request@v5
uses: amannn/action-semantic-pull-request@v6
with:
wip: true
subjectPattern: ^(?![A-Z]).+$

View File

@ -9,7 +9,7 @@ jobs:
if: github.repository == 'vbenjs/vue-vben-admin'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'

6
.gitignore vendored
View File

@ -23,6 +23,7 @@ package-lock.json
.VSCodeCounter
**/backend-mock/data
.omx
.pnpm-store
# local env files
.env.local
.env.*.local
@ -57,3 +58,8 @@ vite.config.ts.*
.claude
.codex
skills-lock.json
.atomcode
datalog
# Playwright CLI 录制产物(本地调试,不入库)
.playwright-cli

View File

@ -1 +1 @@
22.22.0
24.16.0

12
.npmrc
View File

@ -1,13 +1 @@
registry=https://registry.npmmirror.com
public-hoist-pattern[]=lefthook
public-hoist-pattern[]=eslint
public-hoist-pattern[]=oxfmt
public-hoist-pattern[]=oxlint
public-hoist-pattern[]=stylelint
public-hoist-pattern[]=*postcss*
public-hoist-pattern[]=@commitlint/*
public-hoist-pattern[]=czg
strict-peer-dependencies=false
auto-install-peers=true
dedupe-peer-dependents=true

9
.vscode/launch.json vendored
View File

@ -2,6 +2,15 @@
"$schema": "https://json.schemastore.org/launchsettings.json",
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"name": "vben admin antd dev",
"request": "launch",
"url": "http://localhost:5999",
"env": { "NODE_ENV": "development" },
"sourceMaps": true,
"webRoot": "${workspaceFolder}/apps/web-antdv-next"
},
{
"type": "chrome",
"name": "vben admin antd dev",

View File

@ -38,7 +38,7 @@
// lint && format
"oxc.enable": true,
"oxc.typeAware": true,
"oxc.typeAware": false,
"oxc.configPath": "oxlint.config.ts",
"oxc.fmt.configPath": "oxfmt.config.ts",
"eslint.useFlatConfig": true,

View File

@ -9,7 +9,7 @@
## 🐶 新手必读
- nodejs >= v20.19.0(推荐 v22 / v24 && pnpm >= 10.32.1(强制使用 pnpm
- nodejs >= v22.18.0推荐v24 && pnpm >= 11.0.0(强制使用 pnpm
- 演示地址【Vue3 + element-plus】<http://dashboard-vue3.yudao.iocoder.cn>
- 演示地址【Vue3 + vben5(ant-design-vue)】:<http://dashboard-vben.yudao.iocoder.cn>
- 演示地址【Vue2 + element-ui】<http://dashboard.yudao.iocoder.cn>
@ -41,24 +41,24 @@
| 框架 | 说明 | 版本 |
| --- | --- | --- |
| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.30 |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 8.0.0 |
| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.35 |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 8.0.10 |
| [Ant Design Vue](https://www.antdv.com/) | Ant Design Vue | 4.2.6 |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.13.5 |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.14.1 |
| [Naive UI](https://www.naiveui.com/) | Naive UI | 2.44.1 |
| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.18.5 |
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 5.9.3 |
| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.20.0 |
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 6.0.3 |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库替代 vuex5 | 3.0.4 |
| [vueuse](https://vueuse.org/) | 常用工具集 | 14.2.1 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.3.0 |
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 5.0.3 |
| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 4.2.1 |
| [Iconify](https://iconify.design/) | 图标组件 | 5.0.0 |
| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.449 |
| [vueuse](https://vueuse.org/) | 常用工具集 | 14.3.0 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.4.4 |
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 5.1.0 |
| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 4.3.0 |
| [Iconify](https://iconify.design/) | 图标组件 | 5.0.1 |
| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.481 |
| [TinyMCE](https://www.tiny.cloud/) | 富文本编辑器 | 7.3.0 |
| [Echarts](https://echarts.apache.org/) | 图表库 | 6.0.0 |
| [axios](https://axios-http.com/) | http客户端 | 1.13.6 |
| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.20 |
| [Echarts](https://echarts.apache.org/) | 图表库 | 6.1.0 |
| [axios](https://axios-http.com/) | http客户端 | 1.16.1 |
| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.21 |
| [vee-validate](https://vee-validate.logaretm.com/) | 表单验证 | 4.15.1 |
| [zod](https://zod.dev/) | 数据验证 | 3.25.76 |
@ -82,9 +82,9 @@
![功能分层](/.gitee/image/common/ruoyi-vue-pro-biz.png)
* 通用模块(必选):系统功能、基础设施
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
* 业务系统按需ERP 系统、CRM 系统、MES 系统、商城系统、微信公众号、AI 大模型、IoT 物联网
- 通用模块(必选):系统功能、基础设施
- 通用模块(可选):工作流程、支付系统、数据报表、会员中心
- 业务系统按需Mall 电子商城、OA 办公自动化、ERP 企业资源计划系统、WMS 仓库管理系统、CRM 客户关系管理、CMS 内容管理系统、MES 执行制造系统、AI 大模型平台、IoT 物联网系统、IM 即时通讯系统、Mobile 手机移动端、Report 数据大屏
### 系统功能
@ -221,13 +221,13 @@
### 会员中心
| | 功能 | 描述 |
|-----|------|----------------------------------|
| 🚀 | 会员管理 | 会员是 C 端的消费者,该功能用于会员的搜索与管理 |
| 🚀 | 会员标签 | 对会员的标签进行创建、查询、修改、删除等操作 |
| 🚀 | 会员等级 | 对会员的等级、成长值进行管理,可用于订单折扣等会员权益 |
| 🚀 | 会员分组 | 对会员进行分组,用于用户画像、内容推送等运营手段 |
| 🚀 | 积分签到 | 回馈给签到、消费等行为的积分,会员可订单抵现、积分兑换等途径消耗 |
| | 功能 | 描述 |
| --- | --- | --- |
| 🚀 | 会员管理 | 会员是 C 端的消费者,该功能用于会员的搜索与管理 |
| 🚀 | 会员标签 | 对会员的标签进行创建、查询、修改、删除等操作 |
| 🚀 | 会员等级 | 对会员的等级、成长值进行管理,可用于订单折扣等会员权益 |
| 🚀 | 会员分组 | 对会员进行分组,用于用户画像、内容推送等运营手段 |
| 🚀 | 积分签到 | 回馈给签到、消费等行为的积分,会员可订单抵现、积分兑换等途径消耗 |
### ERP 系统
@ -235,6 +235,14 @@
![功能图](/.gitee/image/common/erp-feature.png)
### WMS 系统
演示地址:<https://doc.iocoder.cn/wms-preview/>
![功能图](/.gitee/image/common/wms-feature.png)
![预览图](/.gitee/image/common/wms-preview.png)
### CRM 系统
演示地址:<https://doc.iocoder.cn/crm-preview/>
@ -264,3 +272,15 @@
![功能图](/.gitee/image/common/iot-feature.png)
![预览图](/.gitee/image/common/iot-preview.png)
### IM 即时通讯
演示地址Vue3 + Vben5<http://dashboard-vben.yudao.iocoder.cn>
使用文档:<https://doc.iocoder.cn/im-preview/>
![功能图](/.gitee/image/common/im-feature.png)
| 聊天界面 | 聊天管理 |
| --- | --- |
| ![聊天界面](/.gitee/image/common/im-preview-home.png) | ![聊天管理](/.gitee/image/common/im-preview-manager.png) |

View File

@ -54,12 +54,14 @@
"camunda-bpmn-moddle": "catalog:",
"cropperjs": "catalog:",
"dayjs": "catalog:",
"dhtmlx-gantt": "catalog:",
"diagram-js": "catalog:",
"fast-xml-parser": "catalog:",
"highlight.js": "catalog:",
"pinia": "catalog:",
"steady-xml": "catalog:",
"tinymce": "catalog:",
"tyme4ts": "catalog:",
"video.js": "catalog:",
"vue": "catalog:",
"vue-dompurify-html": "catalog:",

View File

@ -136,8 +136,8 @@ const PreviewGroup = defineAsyncComponent(() =>
import('ant-design-vue/es/image').then((res) => res.ImagePreviewGroup),
);
const withDefaultPlaceholder = <T extends Component>(
component: T,
const withDefaultPlaceholder = (
component: Component,
type: 'input' | 'select',
componentProps: Recordable<any> = {},
) => {
@ -711,7 +711,9 @@ async function initComponentAdapter() {
modelValueProp: 'value',
}),
Input: withDefaultPlaceholder(Input, 'input'),
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
InputNumber: withDefaultPlaceholder(InputNumber, 'input', {
style: { width: '100%' },
}),
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
Mentions: withDefaultPlaceholder(Mentions, 'input'),
// 自定义主要按钮

View File

@ -65,5 +65,6 @@ const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
export { initSetupVbenForm, useVbenForm, z };
export type VbenFormApi = ReturnType<typeof useVbenForm>[1]; // add by 芋艿:用于 data.ts 表单 schema 内调用 setFieldValue
export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

View File

@ -21,11 +21,6 @@ export async function createLeave(data: BpmOALeaveApi.Leave) {
return requestClient.post('/bpm/oa/leave/create', data);
}
/** 更新请假申请 */
export async function updateLeave(data: BpmOALeaveApi.Leave) {
return requestClient.post('/bpm/oa/leave/update', data);
}
/** 获得请假申请 */
export async function getLeave(id: number) {
return requestClient.get<BpmOALeaveApi.Leave>(`/bpm/oa/leave/get?id=${id}`);

View File

@ -29,6 +29,10 @@ export namespace CrmReceivablePlanApi {
returnTime: Date;
};
}
export interface PlanPageParam extends PageParam {
customerId?: number;
contractId?: number;
}
}
/** 查询回款计划列表 */

View File

@ -3,37 +3,24 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace AlertConfigApi {
/** IoT 告警配置 VO */
/** IoT 告警配置 */
export interface AlertConfig {
id?: number;
name: string;
name?: string;
description?: string;
level?: number;
status?: number;
sceneRuleIds?: number[];
receiveUserIds?: number[];
receiveUserNames?: string;
receiveUserNames?: string[];
receiveTypes?: number[];
smsTemplateCode?: string;
mailTemplateCode?: string;
notifyTemplateCode?: string;
createTime?: Date;
updateTime?: Date;
}
}
/** IoT 告警配置 */
export interface AlertConfig {
id?: number;
name?: string;
description?: string;
level?: number;
status?: number;
sceneRuleIds?: number[];
receiveUserIds?: number[];
receiveUserNames?: string;
receiveTypes?: number[];
createTime?: Date;
updateTime?: Date;
}
/** 查询告警配置分页 */
export function getAlertConfigPage(params: PageParam) {
return requestClient.get<PageResult<AlertConfigApi.AlertConfig>>(
@ -49,20 +36,20 @@ export function getAlertConfig(id: number) {
);
}
/** 查询所有告警配置列表 */
export function getAlertConfigList() {
/** 获取告警配置简单列表 */
export function getSimpleAlertConfigList() {
return requestClient.get<AlertConfigApi.AlertConfig[]>(
'/iot/alert-config/list',
'/iot/alert-config/simple-list',
);
}
/** 新增告警配置 */
export function createAlertConfig(data: AlertConfig) {
export function createAlertConfig(data: AlertConfigApi.AlertConfig) {
return requestClient.post('/iot/alert-config/create', data);
}
/** 修改告警配置 */
export function updateAlertConfig(data: AlertConfig) {
export function updateAlertConfig(data: AlertConfigApi.AlertConfig) {
return requestClient.put('/iot/alert-config/update', data);
}
@ -70,25 +57,3 @@ export function updateAlertConfig(data: AlertConfig) {
export function deleteAlertConfig(id: number) {
return requestClient.delete(`/iot/alert-config/delete?id=${id}`);
}
/** 批量删除告警配置 */
export function deleteAlertConfigList(ids: number[]) {
return requestClient.delete('/iot/alert-config/delete-list', {
params: { ids: ids.join(',') },
});
}
/** 启用/禁用告警配置 */
export function toggleAlertConfig(id: number, enabled: boolean) {
return requestClient.put(`/iot/alert-config/toggle`, {
id,
enabled,
});
}
/** 获取告警配置简单列表 */
export function getSimpleAlertConfigList() {
return requestClient.get<AlertConfigApi.AlertConfig[]>(
'/iot/alert-config/simple-list',
);
}

View File

@ -3,41 +3,21 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace AlertRecordApi {
/** IoT 告警记录 VO */
/** IoT 告警记录 */
export interface AlertRecord {
id?: number;
configId?: number;
configName?: string;
configLevel?: number;
deviceId?: number;
deviceName?: string;
productId?: number;
productName?: string;
deviceMessage?: string;
deviceMessage?: any;
processStatus?: boolean;
processRemark?: string;
processTime?: Date;
createTime?: Date;
}
}
/** IoT 告警记录 */
export interface AlertRecord {
id?: number;
configId?: number;
configName?: string;
configLevel?: number;
deviceId?: number;
deviceName?: string;
productId?: number;
productName?: string;
deviceMessage?: string;
processStatus?: boolean;
processRemark?: string;
processTime?: Date;
createTime?: Date;
}
/** 查询告警记录分页 */
export function getAlertRecordPage(params: PageParam) {
return requestClient.get<PageResult<AlertRecordApi.AlertRecord>>(
@ -54,29 +34,9 @@ export function getAlertRecord(id: number) {
}
/** 处理告警记录 */
export function processAlertRecord(id: number, remark?: string) {
export function processAlertRecord(id: number, processRemark?: string) {
return requestClient.put('/iot/alert-record/process', {
id,
remark,
});
}
/** 批量处理告警记录 */
export function batchProcessAlertRecord(ids: number[], remark?: string) {
return requestClient.put('/iot/alert-record/batch-process', {
ids,
remark,
});
}
/** 删除告警记录 */
export function deleteAlertRecord(id: number) {
return requestClient.delete(`/iot/alert-record/delete?id=${id}`);
}
/** 批量删除告警记录 */
export function deleteAlertRecordList(ids: number[]) {
return requestClient.delete('/iot/alert-record/delete-list', {
params: { ids: ids.join(',') },
processRemark,
});
}

View File

@ -150,11 +150,8 @@ export function importDeviceTemplate() {
/** 导入设备 */
export function importDevice(file: File, updateSupport: boolean) {
return requestClient.upload<IotDeviceApi.DeviceImportRespVO>(
'/iot/device/import',
{
file,
updateSupport,
},
`/iot/device/import?updateSupport=${updateSupport}`,
{ file },
);
}
@ -168,7 +165,7 @@ export function getLatestDeviceProperties(params: any) {
/** 获取设备属性历史数据 */
export function getHistoryDevicePropertyList(params: any) {
return requestClient.get<PageResult<IotDeviceApi.DeviceProperty>>(
return requestClient.get<IotDeviceApi.DeviceProperty[]>(
'/iot/device/property/history-list',
{ params },
);

View File

@ -3,39 +3,22 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace IoTOtaFirmwareApi {
/** IoT OTA 固件 VO */
/** IoT OTA 固件信息 */
export interface Firmware {
id?: number;
name: string;
version: string;
productId: number;
productName?: string;
name?: string;
description?: string;
version?: string;
productId?: number;
productName?: string;
fileUrl?: string;
fileMd5?: string;
fileSize?: number;
status?: number;
fileDigestAlgorithm?: string;
fileDigestValue?: string;
createTime?: Date;
updateTime?: Date;
}
}
/** IoT OTA 固件 */
export interface IoTOtaFirmware {
id?: number;
name?: string;
version?: string;
productId?: number;
productName?: string;
description?: string;
fileUrl?: string;
fileMd5?: string;
fileSize?: number;
status?: number;
createTime?: Date;
updateTime?: Date;
}
/** 查询 OTA 固件分页 */
export function getOtaFirmwarePage(params: PageParam) {
return requestClient.get<PageResult<IoTOtaFirmwareApi.Firmware>>(
@ -52,12 +35,12 @@ export function getOtaFirmware(id: number) {
}
/** 新增 OTA 固件 */
export function createOtaFirmware(data: IoTOtaFirmware) {
export function createOtaFirmware(data: IoTOtaFirmwareApi.Firmware) {
return requestClient.post('/iot/ota/firmware/create', data);
}
/** 修改 OTA 固件 */
export function updateOtaFirmware(data: IoTOtaFirmware) {
export function updateOtaFirmware(data: IoTOtaFirmwareApi.Firmware) {
return requestClient.put('/iot/ota/firmware/update', data);
}
@ -65,26 +48,3 @@ export function updateOtaFirmware(data: IoTOtaFirmware) {
export function deleteOtaFirmware(id: number) {
return requestClient.delete(`/iot/ota/firmware/delete?id=${id}`);
}
/** 批量删除 OTA 固件 */
export function deleteOtaFirmwareList(ids: number[]) {
return requestClient.delete('/iot/ota/firmware/delete-list', {
params: { ids: ids.join(',') },
});
}
/** 更新 OTA 固件状态 */
export function updateOtaFirmwareStatus(id: number, status: number) {
return requestClient.put(`/iot/ota/firmware/update-status`, {
id,
status,
});
}
/** 根据产品 ID 查询固件列表 */
export function getOtaFirmwareListByProductId(productId: number) {
return requestClient.get<IoTOtaFirmwareApi.Firmware[]>(
'/iot/ota/firmware/list-by-product-id',
{ params: { productId } },
);
}

View File

@ -3,45 +3,21 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace IoTOtaTaskApi {
/** IoT OTA 升级任务 VO */
/** IoT OTA 升级任务 */
export interface Task {
id?: number;
name: string;
name?: string;
description?: string;
firmwareId: number;
firmwareName?: string;
productId?: number;
productName?: string;
firmwareId?: number;
status?: number;
deviceScope?: number;
deviceIds?: number[];
status?: number;
successCount?: number;
failureCount?: number;
pendingCount?: number;
deviceTotalCount?: number;
deviceSuccessCount?: number;
createTime?: Date;
updateTime?: Date;
}
}
/** IoT OTA 升级任务 */
export interface OtaTask {
id?: number;
name?: string;
description?: string;
firmwareId?: number;
firmwareName?: string;
productId?: number;
productName?: string;
deviceScope?: number;
deviceIds?: number[];
status?: number;
successCount?: number;
failureCount?: number;
pendingCount?: number;
createTime?: Date;
updateTime?: Date;
}
/** 查询 OTA 升级任务分页 */
export function getOtaTaskPage(params: PageParam) {
return requestClient.get<PageResult<IoTOtaTaskApi.Task>>(
@ -56,43 +32,11 @@ export function getOtaTask(id: number) {
}
/** 新增 OTA 升级任务 */
export function createOtaTask(data: OtaTask) {
export function createOtaTask(data: IoTOtaTaskApi.Task) {
return requestClient.post('/iot/ota/task/create', data);
}
/** 修改 OTA 升级任务 */
export function updateOtaTask(data: OtaTask) {
return requestClient.put('/iot/ota/task/update', data);
}
/** 删除 OTA 升级任务 */
export function deleteOtaTask(id: number) {
return requestClient.delete(`/iot/ota/task/delete?id=${id}`);
}
/** 批量删除 OTA 升级任务 */
export function deleteOtaTaskList(ids: number[]) {
return requestClient.delete('/iot/ota/task/delete-list', {
params: { ids: ids.join(',') },
});
}
/** 取消 OTA 升级任务 */
export function cancelOtaTask(id: number) {
return requestClient.put(`/iot/ota/task/cancel?id=${id}`);
}
/** 启动 OTA 升级任务 */
export function startOtaTask(id: number) {
return requestClient.put(`/iot/ota/task/start?id=${id}`);
}
/** 暂停 OTA 升级任务 */
export function pauseOtaTask(id: number) {
return requestClient.put(`/iot/ota/task/pause?id=${id}`);
}
/** 恢复 OTA 升级任务 */
export function resumeOtaTask(id: number) {
return requestClient.put(`/iot/ota/task/resume?id=${id}`);
return requestClient.post(`/iot/ota/task/cancel?id=${id}`);
}

View File

@ -3,44 +3,24 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace IoTOtaTaskRecordApi {
/** IoT OTA 升级任务记录 VO */
/** IoT OTA 升级任务记录 */
export interface TaskRecord {
id?: number;
taskId: number;
taskName?: string;
deviceId: number;
deviceName?: string;
firmwareId?: number;
firmwareName?: string;
firmwareVersion?: string;
taskId?: number;
deviceId?: string;
deviceName?: string;
currentVersion?: string;
fromFirmwareId?: number;
fromFirmwareVersion?: string;
status?: number;
progress?: number;
errorMessage?: string;
startTime?: Date;
endTime?: Date;
createTime?: Date;
description?: string;
updateTime?: Date;
}
}
// TODO @AI这里应该拿到 IoTOtaTaskRecordApi 里
/** IoT OTA 升级任务记录 */
export interface OtaTaskRecord {
id?: number;
taskId?: number;
taskName?: string;
deviceId?: number;
deviceName?: string;
firmwareId?: number;
firmwareName?: string;
firmwareVersion?: string;
status?: number;
progress?: number;
errorMessage?: string;
startTime?: Date;
endTime?: Date;
createTime?: Date;
}
/** 查询 OTA 升级任务记录分页 */
export function getOtaTaskRecordPage(params: PageParam) {
return requestClient.get<PageResult<IoTOtaTaskRecordApi.TaskRecord>>(
@ -49,48 +29,12 @@ export function getOtaTaskRecordPage(params: PageParam) {
);
}
/** 查询 OTA 升级任务记录详情 */
export function getOtaTaskRecord(id: number) {
return requestClient.get<IoTOtaTaskRecordApi.TaskRecord>(
`/iot/ota/task/record/get?id=${id}`,
);
}
/** 根据任务 ID 查询记录列表 */
export function getOtaTaskRecordListByTaskId(taskId: number) {
return requestClient.get<IoTOtaTaskRecordApi.TaskRecord[]>(
'/iot/ota/task/record/list-by-task-id',
{ params: { taskId } },
);
}
/** 根据设备 ID 查询记录列表 */
export function getOtaTaskRecordListByDeviceId(deviceId: number) {
return requestClient.get<IoTOtaTaskRecordApi.TaskRecord[]>(
'/iot/ota/task/record/list-by-device-id',
{ params: { deviceId } },
);
}
/** 根据固件 ID 查询记录列表 */
export function getOtaTaskRecordListByFirmwareId(firmwareId: number) {
return requestClient.get<IoTOtaTaskRecordApi.TaskRecord[]>(
'/iot/ota/task/record/list-by-firmware-id',
{ params: { firmwareId } },
);
}
/** 重试升级任务记录 */
export function retryOtaTaskRecord(id: number) {
return requestClient.put(`/iot/ota/task/record/retry?id=${id}`);
}
/** 取消升级任务记录 */
/** 取消 OTA 升级任务记录 */
export function cancelOtaTaskRecord(id: number) {
return requestClient.put(`/iot/ota/task/record/cancel?id=${id}`);
}
/** 获取升级任务记录状态统计 */
/** 获取 OTA 升级任务记录状态统计 */
export function getOtaTaskRecordStatusStatistics(
firmwareId?: number,
taskId?: number,

View File

@ -7,11 +7,10 @@ export namespace IotProductCategoryApi {
export interface ProductCategory {
id?: number; // 分类 ID
name: string; // 分类名称
parentId?: number; // 父级分类 ID
sort?: number; // 分类排序
status?: number; // 分类状态
description?: string; // 分类描述
createTime?: string; // 创建时间
createTime?: Date; // 创建时间
}
}

View File

@ -20,8 +20,6 @@ export namespace IotProductApi {
deviceType?: number; // 设备类型
netType?: number; // 联网方式
serializeType?: string; // 序列化类型
dataFormat?: number; // 数据格式
validateType?: number; // 认证方式
registerEnabled?: boolean; // 是否开启动态注册
deviceCount?: number; // 设备数量
createTime?: Date; // 创建时间
@ -103,3 +101,10 @@ export function getProductByKey(productKey: string) {
params: { productKey },
});
}
/** 同步产品物模型 TDengine 超级表结构 */
export function syncProductPropertyTable(productId: number) {
return requestClient.post(
`/iot/product/sync-property-table?productId=${productId}`,
);
}

View File

@ -3,45 +3,21 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace DataRuleApi {
/** IoT 数据流转规则 VO */
export interface Rule {
/** IoT 数据流转规则 */
export interface DataRule {
id?: number;
name: string;
name?: string;
description?: string;
status?: number;
productId?: number;
productKey?: string;
sourceConfigs?: SourceConfig[];
sourceConfigs?: any[];
sinkIds?: number[];
createTime?: Date;
}
/** IoT 数据源配置 */
export interface SourceConfig {
productId?: number;
productKey?: string;
deviceId?: number;
type?: string;
topic?: string;
}
}
/** IoT 数据流转规则 */
export interface DataRule {
id?: number;
name?: string;
description?: string;
status?: number;
productId?: number;
productKey?: string;
sourceConfigs?: any[];
sinkIds?: number[];
createTime?: Date;
}
/** 查询数据流转规则分页 */
export function getDataRulePage(params: PageParam) {
return requestClient.get<PageResult<DataRuleApi.Rule>>(
return requestClient.get<PageResult<DataRuleApi.DataRule>>(
'/iot/data-rule/page',
{ params },
);
@ -49,16 +25,16 @@ export function getDataRulePage(params: PageParam) {
/** 查询数据流转规则详情 */
export function getDataRule(id: number) {
return requestClient.get<DataRuleApi.Rule>(`/iot/data-rule/get?id=${id}`);
return requestClient.get<DataRuleApi.DataRule>(`/iot/data-rule/get?id=${id}`);
}
/** 新增数据流转规则 */
export function createDataRule(data: DataRule) {
export function createDataRule(data: DataRuleApi.DataRule) {
return requestClient.post('/iot/data-rule/create', data);
}
/** 修改数据流转规则 */
export function updateDataRule(data: DataRule) {
export function updateDataRule(data: DataRuleApi.DataRule) {
return requestClient.put('/iot/data-rule/update', data);
}
@ -66,18 +42,3 @@ export function updateDataRule(data: DataRule) {
export function deleteDataRule(id: number) {
return requestClient.delete(`/iot/data-rule/delete?id=${id}`);
}
/** 批量删除数据流转规则 */
export function deleteDataRuleList(ids: number[]) {
return requestClient.delete('/iot/data-rule/delete-list', {
params: { ids: ids.join(',') },
});
}
/** 更新数据流转规则状态 */
export function updateDataRuleStatus(id: number, status: number) {
return requestClient.put(`/iot/data-rule/update-status`, {
id,
status,
});
}

View File

@ -2,101 +2,147 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
interface BaseConfig {
type: string;
}
export namespace DataSinkApi {
/** IoT 数据流转目的 VO */
export interface Sink {
export interface DataSink {
id?: number;
name: string;
name?: string;
description?: string;
status?: number;
type: string;
config?: any;
direction?: number;
type?: number;
config?:
| DatabaseConfig
| HttpConfig
| KafkaMQConfig
| MqttConfig
| RabbitMQConfig
| RedisStreamMQConfig
| RocketMQConfig
| TcpConfig
| WebSocketConfig;
createTime?: Date;
}
/** HTTP 配置 */
export interface HttpConfig extends BaseConfig {
url: string;
method: string;
headers: Record<string, string>;
query: Record<string, string>;
body: string;
}
/** TCP 配置 */
export interface TcpConfig extends BaseConfig {
host: string;
port: number;
connectTimeoutMs: number;
readTimeoutMs: number;
ssl: boolean;
sslCertPath: string;
dataFormat: string;
heartbeatIntervalMs: number;
reconnectIntervalMs: number;
maxReconnectAttempts: number;
}
/** WebSocket 配置 */
export interface WebSocketConfig extends BaseConfig {
serverUrl: string;
connectTimeoutMs: number;
sendTimeoutMs: number;
heartbeatIntervalMs: number;
heartbeatMessage: string;
subprotocols: string;
customHeaders: string;
verifySslCert: boolean;
dataFormat: string;
reconnectIntervalMs: number;
maxReconnectAttempts: number;
enableCompression: boolean;
sendRetryCount: number;
sendRetryIntervalMs: number;
}
/** MQTT 配置 */
export interface MqttConfig extends BaseConfig {
url: string;
username: string;
password: string;
clientId: string;
topic: string;
}
/** Database 配置 */
export interface DatabaseConfig extends BaseConfig {
jdbcUrl: string;
username: string;
password: string;
tableName: string;
}
/** RocketMQ 配置 */
export interface RocketMQConfig extends BaseConfig {
nameServer: string;
accessKey: string;
secretKey: string;
group: string;
topic: string;
tags: string;
}
/** Kafka 配置 */
export interface KafkaMQConfig extends BaseConfig {
bootstrapServers: string;
username: string;
password: string;
ssl: boolean;
topic: string;
}
/** RabbitMQ 配置 */
export interface RabbitMQConfig extends BaseConfig {
host: string;
port: number;
virtualHost: string;
username: string;
password: string;
exchange: string;
routingKey: string;
queue: string;
}
/** Redis Stream MQ 配置 */
export interface RedisStreamMQConfig extends BaseConfig {
host: string;
port: number;
password: string;
database: number;
topic: string;
}
}
/** IoT 数据流转目的 */
export interface DataSinkVO {
id?: number;
name?: string;
description?: string;
status?: number;
type?: string;
config?: any;
createTime?: Date;
}
/** IoT 数据目的类型枚举 */
export enum IotDataSinkTypeEnum {
HTTP = 'HTTP',
KAFKA = 'KAFKA',
MQTT = 'MQTT',
RABBITMQ = 'RABBITMQ',
REDIS_STREAM = 'REDIS_STREAM',
ROCKETMQ = 'ROCKETMQ',
}
/** HTTP 配置 */
export interface HttpConfig {
url?: string;
method?: string;
headers?: Record<string, string>;
timeout?: number;
}
/** MQTT 配置 */
export interface MqttConfig {
broker?: string;
port?: number;
topic?: string;
username?: string;
password?: string;
clientId?: string;
qos?: number;
}
/** Kafka 配置 */
export interface KafkaMQConfig {
bootstrapServers?: string;
topic?: string;
acks?: string;
retries?: number;
batchSize?: number;
}
/** RabbitMQ 配置 */
export interface RabbitMQConfig {
host?: string;
port?: number;
virtualHost?: string;
username?: string;
password?: string;
exchange?: string;
routingKey?: string;
queue?: string;
}
/** RocketMQ 配置 */
export interface RocketMQConfig {
nameServer?: string;
topic?: string;
tag?: string;
producerGroup?: string;
}
/** Redis Stream 配置 */
export interface RedisStreamMQConfig {
host?: string;
port?: number;
password?: string;
database?: number;
streamKey?: string;
maxLen?: number;
}
/** 数据流转目的类型 */
export const IotDataSinkTypeEnum = {
HTTP: 1,
TCP: 2,
WEBSOCKET: 3,
MQTT: 10,
DATABASE: 20,
REDIS_STREAM: 21,
ROCKETMQ: 30,
RABBITMQ: 31,
KAFKA: 32,
} as const;
/** 查询数据流转目的分页 */
export function getDataSinkPage(params: PageParam) {
return requestClient.get<PageResult<DataSinkApi.Sink>>(
return requestClient.get<PageResult<DataSinkApi.DataSink>>(
'/iot/data-sink/page',
{ params },
);
@ -104,26 +150,23 @@ export function getDataSinkPage(params: PageParam) {
/** 查询数据流转目的详情 */
export function getDataSink(id: number) {
return requestClient.get<DataSinkApi.Sink>(`/iot/data-sink/get?id=${id}`);
return requestClient.get<DataSinkApi.DataSink>(`/iot/data-sink/get?id=${id}`);
}
/** 查询所有数据流转目的列表 */
export function getDataSinkList() {
return requestClient.get<DataSinkApi.Sink[]>('/iot/data-sink/list');
}
/** 查询数据流转目的简单列表 */
/** 查询数据流转目的(精简)列表 */
export function getDataSinkSimpleList() {
return requestClient.get<DataSinkApi.Sink[]>('/iot/data-sink/simple-list');
return requestClient.get<DataSinkApi.DataSink[]>(
'/iot/data-sink/simple-list',
);
}
/** 新增数据流转目的 */
export function createDataSink(data: DataSinkVO) {
export function createDataSink(data: DataSinkApi.DataSink) {
return requestClient.post('/iot/data-sink/create', data);
}
/** 修改数据流转目的 */
export function updateDataSink(data: DataSinkVO) {
export function updateDataSink(data: DataSinkApi.DataSink) {
return requestClient.put('/iot/data-sink/update', data);
}
@ -131,18 +174,3 @@ export function updateDataSink(data: DataSinkVO) {
export function deleteDataSink(id: number) {
return requestClient.delete(`/iot/data-sink/delete?id=${id}`);
}
/** 批量删除数据流转目的 */
export function deleteDataSinkList(ids: number[]) {
return requestClient.delete('/iot/data-sink/delete-list', {
params: { ids: ids.join(',') },
});
}
/** 更新数据流转目的状态 */
export function updateDataSinkStatus(id: number, status: number) {
return requestClient.put(`/iot/data-sink/update-status`, {
id,
status,
});
}

View File

@ -11,25 +11,20 @@ export namespace RuleSceneApi {
status?: number;
triggers?: Trigger[];
actions?: Action[];
lastTriggerTime?: Date;
createTime?: Date;
}
/** 场景联动规则的触发器 */
export interface Trigger {
type?: string;
type?: number;
productId?: number;
deviceId?: number;
identifier?: string;
operator?: string;
value?: any;
cronExpression?: string;
conditionGroups?: TriggerConditionGroup[];
}
/** 场景联动规则的触发条件组 */
export interface TriggerConditionGroup {
conditions?: TriggerCondition[];
operator?: string;
conditionGroups?: TriggerCondition[][]; // 后端结构List<List<TriggerCondition>>;外层「或」、组内「且」
}
/** 场景联动规则的触发条件 */
@ -39,72 +34,22 @@ export namespace RuleSceneApi {
identifier?: string;
operator?: string;
value?: any;
type?: string;
type?: number;
param?: string;
}
/** 场景联动规则的动作 */
export interface Action {
type?: string;
type?: number;
productId?: number;
deviceId?: number;
identifier?: string;
value?: any;
alertConfigId?: number;
params?: string;
}
}
// TODO @haohao貌似下面的和 RuleSceneApi 重复了。
/** IoT 场景联动规则 */
export interface IotSceneRule {
id?: number;
name?: string;
description?: string;
status?: number;
triggers?: Trigger[];
actions?: Action[];
createTime?: Date;
}
/** IoT 场景联动规则触发器 */
export interface Trigger {
type?: string;
productId?: number;
deviceId?: number;
identifier?: string;
operator?: string;
value?: any;
cronExpression?: string;
conditionGroups?: TriggerConditionGroup[];
}
/** IoT 场景联动规则触发条件组 */
export interface TriggerConditionGroup {
conditions?: TriggerCondition[];
operator?: string;
}
/** IoT 场景联动规则触发条件 */
export interface TriggerCondition {
productId?: number;
deviceId?: number;
identifier?: string;
operator?: string;
value?: any;
type?: string;
param?: string;
}
/** IoT 场景联动规则动作 */
export interface Action {
type?: string;
productId?: number;
deviceId?: number;
identifier?: string;
value?: any;
alertConfigId?: number;
params?: string;
}
/** 查询场景联动规则分页 */
export function getSceneRulePage(params: PageParam) {
return requestClient.get<PageResult<RuleSceneApi.SceneRule>>(
@ -121,12 +66,12 @@ export function getSceneRule(id: number) {
}
/** 新增场景联动规则 */
export function createSceneRule(data: IotSceneRule) {
export function createSceneRule(data: RuleSceneApi.SceneRule) {
return requestClient.post('/iot/scene-rule/create', data);
}
/** 修改场景联动规则 */
export function updateSceneRule(data: IotSceneRule) {
export function updateSceneRule(data: RuleSceneApi.SceneRule) {
return requestClient.put('/iot/scene-rule/update', data);
}
@ -135,14 +80,6 @@ export function deleteSceneRule(id: number) {
return requestClient.delete(`/iot/scene-rule/delete?id=${id}`);
}
/** 批量删除场景联动规则 */
// TODO @haohao貌似用上。
export function deleteSceneRuleList(ids: number[]) {
return requestClient.delete('/iot/scene-rule/delete-list', {
params: { ids: ids.join(',') },
});
}
/** 更新场景联动规则状态 */
export function updateSceneRuleStatus(id: number, status: number) {
return requestClient.put(`/iot/scene-rule/update-status`, {

View File

@ -17,18 +17,6 @@ export namespace IotStatisticsApi {
productCategoryDeviceCounts: Record<string, number>; // 按品类统计的设备数量
}
/** 时间戳-数值的键值对类型 */
export interface TimeValueItem {
[key: string]: number;
}
/** 消息统计数据类型 */
export interface DeviceMessageSummary {
statType: number;
upstreamCounts: TimeValueItem[];
downstreamCounts: TimeValueItem[];
}
/** 设备消息数量统计(按日期) */
export interface DeviceMessageSummaryByDateRespVO {
time: string; // 时间轴

View File

@ -1,126 +1,209 @@
import type { Rule } from 'ant-design-vue/es/form';
import type { PageParam, PageResult } from '@vben/request';
import { isEmpty } from '@vben/utils';
import { requestClient } from '#/api/request';
export namespace ThingModelApi {
/** IoT 物模型数据 VO */
/** IoT 物模型数据 */
export interface ThingModel {
id?: number;
productId?: number;
productKey?: string;
identifier: string;
name: string;
desc?: string;
type: string;
property?: ThingModelProperty;
event?: ThingModelEvent;
service?: ThingModelService;
identifier?: string;
name?: string;
description?: string;
dataType?: string;
type?: number; // 参见 IoTThingModelTypeEnum 枚举类
property?: Property;
event?: Event;
service?: Service;
}
/** IoT 物模型属性 */
export interface Property {
identifier: string;
name: string;
accessMode: string;
dataType: string;
identifier?: string;
name?: string;
accessMode?: string;
required?: boolean;
dataType?: string;
description?: string;
dataSpecs?: any;
dataSpecsList?: any[];
desc?: string;
}
/** IoT 物模型服务 */
export interface Service {
identifier: string;
name: string;
callType: string;
inputData?: any[];
outputData?: any[];
desc?: string;
identifier?: string;
name?: string;
required?: boolean;
callType?: string;
description?: string;
inputParams?: Param[];
outputParams?: Param[];
method?: string;
}
/** IoT 物模型事件 */
export interface Event {
identifier: string;
identifier?: string;
name?: string;
required?: boolean;
type?: string;
description?: string;
outputParams?: Param[];
method?: string;
}
/** IoT 物模型参数 */
export interface Param {
identifier?: string;
name?: string;
direction?: string;
paraOrder?: number;
dataType?: string;
dataSpecs?: any;
dataSpecsList?: any[];
}
/** IoT 物模型 TSL树形响应 */
export interface ThingModelTSL {
productId?: number;
productKey?: string;
properties?: Property[];
events?: Event[];
services?: Service[];
}
/** IoT 数据定义(数值型) */
export interface DataSpecsNumberData {
min?: number | string;
max?: number | string;
step?: number | string;
unit?: string;
unitName?: string;
}
/** IoT 数据定义(枚举/布尔型) */
export interface DataSpecsEnumOrBoolData {
value: number | string;
name: string;
type: string;
outputData?: any[];
desc?: string;
}
}
/** IoT 物模型数据 */
export interface ThingModelData {
id?: number;
productId?: number;
productKey?: string;
identifier?: string;
name?: string;
desc?: string;
type?: string;
dataType?: string;
property?: ThingModelProperty;
event?: ThingModelEvent;
service?: ThingModelService;
/** 生成「必填 + 数字」类校验器:拼到 size / length / 枚举值上 */
function buildRequiredNumberValidator(label: string) {
return (_rule: any, value: any, callback: any) => {
if (isEmpty(value)) {
callback(new Error(`${label}不能为空`));
return;
}
if (Number.isNaN(Number(value))) {
callback(new Error(`${label}必须是数字`));
return;
}
callback();
};
}
/** IoT 物模型属性 */
export interface ThingModelProperty {
identifier?: string;
name?: string;
accessMode?: string;
dataType?: string;
dataSpecs?: any;
dataSpecsList?: any[];
desc?: string;
}
/** IoT 物模型服务 */
export interface ThingModelService {
identifier?: string;
name?: string;
callType?: string;
inputData?: any[];
outputData?: any[];
desc?: string;
}
/** IoT 物模型事件 */
export interface ThingModelEvent {
identifier?: string;
name?: string;
type?: string;
outputData?: any[];
desc?: string;
}
/** IoT 数据定义(数值型) */
export interface DataSpecsNumberData {
min?: number | string;
max?: number | string;
step?: number | string;
unit?: string;
unitName?: string;
}
/** IoT 数据定义(枚举/布尔型) */
export interface DataSpecsEnumOrBoolData {
value: number | string;
name: string;
/** 生成「标识符样式」名称校验器:开头需为中文 / 英文 / 数字,整体仅允许中文、英文、数字、下划线、短划线,长度 ≤ 20 */
export function buildIdentifierLikeNameValidator(label: string) {
return (_rule: any, value: string, callback: any) => {
if (isEmpty(value)) {
callback(new Error(`${label}不能为空`));
return;
}
if (!/^[一-龥A-Za-z0-9]/.test(value)) {
callback(new Error(`${label}必须以中文、英文字母或数字开头`));
return;
}
if (!/^[一-龥A-Za-z0-9][\w一-龥-]*$/.test(value)) {
callback(
new Error(`${label}只能包含中文、英文字母、数字、下划线和短划线`),
);
return;
}
if (value.length > 20) {
callback(new Error(`${label}长度不能超过 20 个字符`));
return;
}
callback();
};
}
/** IoT 物模型表单校验规则 */
export interface ThingModelFormRules {
[key: string]: any;
}
export const ThingModelFormRules: Record<string, Rule[]> = {
name: [
{ required: true, message: '功能名称不能为空', trigger: 'blur' },
{
pattern: /^[一-龥A-Za-z0-9][一-龥A-Za-z0-9\-_/.]{0,29}$/,
message:
'支持中文、大小写字母、日文、数字、短划线、下划线、斜杠和小数点,必须以中文、英文或数字开头,不超过 30 个字符',
trigger: 'blur',
},
],
type: [{ required: true, message: '功能类型不能为空', trigger: 'blur' }],
identifier: [
{ required: true, message: '标识符不能为空', trigger: 'blur' },
{
pattern: /^[a-zA-Z][a-zA-Z0-9_]{0,31}$/,
message: '支持大小写字母、数字和下划线,必须以字母开头,不超过 32 个字符',
trigger: 'blur',
},
{
validator: (_rule: any, value: string, callback: any) => {
const reservedKeywords = [
'set',
'get',
'post',
'property',
'event',
'time',
'value',
];
if (reservedKeywords.includes(value)) {
callback(
new Error(
'set, get, post, property, event, time, value 是系统保留字段,不能用于标识符定义',
),
);
return;
}
if (/^\d+$/.test(value)) {
callback(new Error('标识符不能是纯数字'));
return;
}
callback();
},
trigger: 'blur',
},
],
childDataType: [{ required: true, message: '元素类型不能为空' }],
size: [
{
required: true,
validator: buildRequiredNumberValidator('元素个数'),
trigger: 'blur',
},
],
length: [
{
required: true,
validator: buildRequiredNumberValidator('文本长度'),
trigger: 'blur',
},
],
accessMode: [
{ required: true, message: '请选择读写类型', trigger: 'change' },
],
callType: [{ required: true, message: '请选择调用方式', trigger: 'change' }],
eventType: [{ required: true, message: '请选择事件类型', trigger: 'change' }],
};
/** 验证布尔型名称 */
export function validateBoolName(_rule: any, value: any, callback: any) {
if (value) {
callback();
} else {
callback(new Error('枚举描述不能为空'));
}
}
/** 校验布尔值名称 */
export const validateBoolName = buildIdentifierLikeNameValidator('布尔值名称');
/** 查询产品物模型分页 */
export function getThingModelPage(params: PageParam) {
@ -141,17 +224,19 @@ export function getThingModel(id: number) {
export function getThingModelListByProductId(productId: number) {
return requestClient.get<ThingModelApi.ThingModel[]>(
'/iot/thing-model/list',
{ params: { productId } },
{
params: { productId },
},
);
}
/** 新增物模型 */
export function createThingModel(data: ThingModelData) {
export function createThingModel(data: ThingModelApi.ThingModel) {
return requestClient.post('/iot/thing-model/create', data);
}
/** 修改物模型 */
export function updateThingModel(data: ThingModelData) {
export function updateThingModel(data: ThingModelApi.ThingModel) {
return requestClient.put('/iot/thing-model/update', data);
}
@ -161,26 +246,11 @@ export function deleteThingModel(id: number) {
}
/** 获取物模型 TSL */
export function getThingModelTSL(productId: number) {
return requestClient.get<ThingModelApi.ThingModel[]>(
export function getThingModelTSLByProductId(productId: number) {
return requestClient.get<ThingModelApi.ThingModelTSL>(
'/iot/thing-model/get-tsl',
{ params: { productId } },
{
params: { productId },
},
);
}
/** TSL
export function importThingModelTSL(productId: number, tslData: any) {
return requestClient.post('/iot/thing-model/import-tsl', {
productId,
tslData,
});
}
*/
/** TSL
export function exportThingModelTSL(productId: number) {
return requestClient.get<any>('/iot/thing-model/export-tsl', {
params: { productId },
});
}
*/

View File

@ -7,7 +7,7 @@ import { requestClient } from '#/api/request';
export namespace MallTradeStatisticsApi {
/** 交易状况 Request */
export interface TradeTrendReqVO {
times: [Date, Date];
times?: string[];
}
/** 交易统计 Response */

View File

@ -13,6 +13,7 @@ export namespace MemberUserApi {
loginIp: string;
mark: string;
mobile: string;
email?: string;
name?: string;
nickname?: string;
registerIp: string;

View File

@ -0,0 +1,27 @@
import { requestClient } from '#/api/request';
export namespace MesCalCalendarApi {
/** 排班日历班组排班项 */
export interface CalendarTeamShiftItem {
teamId?: number; // 班组编号
teamName?: string; // 班组名称
shiftId?: number; // 班次编号
shiftName?: string; // 班次名称
sort?: number; // 排序
}
/** 排班日历天 */
export interface CalendarDay {
day?: string; // 日期
shiftType?: number; // 轮班方式
teamShifts?: CalendarTeamShiftItem[]; // 班组班次
}
}
/** 查询排班日历列表 */
export function getCalendarList(params: any) {
return requestClient.get<MesCalCalendarApi.CalendarDay[]>(
'/mes/cal/calendar/list',
{ params },
);
}

View File

@ -0,0 +1,39 @@
import { requestClient } from '#/api/request';
export namespace MesCalHolidayApi {
/** MES 假期设置 */
export interface Holiday {
id?: number; // 编号
day?: number | string; // 日期
type?: number; // 日期类型
remark?: string; // 备注
createTime?: Date; // 创建时间
}
/** 假期查询参数 */
export interface HolidayQuery {
startDay?: string;
endDay?: string;
}
}
/** 查询假期设置列表 */
export function getHolidayList(params?: MesCalHolidayApi.HolidayQuery) {
return requestClient.get<MesCalHolidayApi.Holiday[]>(
'/mes/cal/holiday/list',
{ params },
);
}
/** 根据日期查询假期设置 */
export function getHolidayByDay(day: string) {
return requestClient.get<MesCalHolidayApi.Holiday>(
'/mes/cal/holiday/get-by-day',
{ params: { day } },
);
}
/** 保存假期设置 */
export function saveHoliday(data: MesCalHolidayApi.Holiday) {
return requestClient.post('/mes/cal/holiday/save', data);
}

View File

@ -0,0 +1,59 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesCalPlanApi {
/** MES 排班计划 */
export interface Plan {
id?: number; // 计划编号
code?: string; // 计划编码
name?: string; // 计划名称
calendarType?: number; // 班组类型
startDate?: number; // 开始日期
endDate?: number; // 结束日期
shiftType?: number; // 轮班方式
shiftMethod?: number; // 倒班方式
shiftCount?: number; // 倒班天数
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询排班计划分页 */
export function getPlanPage(params: PageParam) {
return requestClient.get<PageResult<MesCalPlanApi.Plan>>(
'/mes/cal/plan/page',
{ params },
);
}
/** 查询排班计划详情 */
export function getPlan(id: number) {
return requestClient.get<MesCalPlanApi.Plan>(`/mes/cal/plan/get?id=${id}`);
}
/** 新增排班计划 */
export function createPlan(data: MesCalPlanApi.Plan) {
return requestClient.post<number>('/mes/cal/plan/create', data);
}
/** 修改排班计划 */
export function updatePlan(data: MesCalPlanApi.Plan) {
return requestClient.put('/mes/cal/plan/update', data);
}
/** 确认排班计划 */
export function confirmPlan(id: number) {
return requestClient.put(`/mes/cal/plan/confirm?id=${id}`);
}
/** 删除排班计划 */
export function deletePlan(id: number) {
return requestClient.delete(`/mes/cal/plan/delete?id=${id}`);
}
/** 导出排班计划 */
export function exportPlan(params: any) {
return requestClient.download('/mes/cal/plan/export-excel', { params });
}

View File

@ -0,0 +1,36 @@
import { requestClient } from '#/api/request';
export namespace MesCalPlanShiftApi {
/** MES 计划班次 */
export interface PlanShift {
id?: number; // 班次编号
planId?: number; // 排班计划编号
sort?: number; // 显示顺序
name?: string; // 班次名称
startTime?: string; // 开始时间
endTime?: string; // 结束时间
remark?: string; // 备注
}
}
/** 查询指定排班计划的班次列表 */
export function getPlanShiftListByPlan(planId: number) {
return requestClient.get<MesCalPlanShiftApi.PlanShift[]>(
`/mes/cal/plan-shift/list-by-plan?planId=${planId}`,
);
}
/** 新增计划班次 */
export function createPlanShift(data: MesCalPlanShiftApi.PlanShift) {
return requestClient.post('/mes/cal/plan-shift/create', data);
}
/** 修改计划班次 */
export function updatePlanShift(data: MesCalPlanShiftApi.PlanShift) {
return requestClient.put('/mes/cal/plan-shift/update', data);
}
/** 删除计划班次 */
export function deletePlanShift(id: number) {
return requestClient.delete(`/mes/cal/plan-shift/delete?id=${id}`);
}

View File

@ -0,0 +1,30 @@
import { requestClient } from '#/api/request';
export namespace MesCalPlanTeamApi {
/** MES 计划班组关联 */
export interface PlanTeam {
id?: number; // 关联编号
planId?: number; // 排班计划编号
teamId?: number; // 班组编号
teamCode?: string; // 班组编码
teamName?: string; // 班组名称
remark?: string; // 备注
}
}
/** 查询指定排班计划的班组列表 */
export function getPlanTeamListByPlan(planId: number) {
return requestClient.get<MesCalPlanTeamApi.PlanTeam[]>(
`/mes/cal/plan-team/list-by-plan?planId=${planId}`,
);
}
/** 新增计划班组关联 */
export function createPlanTeam(data: MesCalPlanTeamApi.PlanTeam) {
return requestClient.post('/mes/cal/plan-team/create', data);
}
/** 删除计划班组关联 */
export function deletePlanTeam(id: number) {
return requestClient.delete(`/mes/cal/plan-team/delete?id=${id}`);
}

View File

@ -0,0 +1,53 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesCalTeamApi {
/** MES 班组 */
export interface Team {
id?: number; // 班组编号
code?: string; // 班组编码
name?: string; // 班组名称
calendarType?: number; // 班组类型
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询班组分页 */
export function getTeamPage(params: PageParam) {
return requestClient.get<PageResult<MesCalTeamApi.Team>>(
'/mes/cal/team/page',
{ params },
);
}
/** 查询班组列表 */
export function getTeamList() {
return requestClient.get<MesCalTeamApi.Team[]>('/mes/cal/team/list');
}
/** 查询班组详情 */
export function getTeam(id: number) {
return requestClient.get<MesCalTeamApi.Team>(`/mes/cal/team/get?id=${id}`);
}
/** 新增班组 */
export function createTeam(data: MesCalTeamApi.Team) {
return requestClient.post('/mes/cal/team/create', data);
}
/** 修改班组 */
export function updateTeam(data: MesCalTeamApi.Team) {
return requestClient.put('/mes/cal/team/update', data);
}
/** 删除班组 */
export function deleteTeam(id: number) {
return requestClient.delete(`/mes/cal/team/delete?id=${id}`);
}
/** 导出班组 */
export function exportTeam(params: any) {
return requestClient.download('/mes/cal/team/export-excel', { params });
}

View File

@ -0,0 +1,51 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesCalTeamMemberApi {
/** MES 班组成员 */
export interface TeamMember {
id?: number; // 成员编号
teamId?: number; // 班组编号
userId?: number; // 用户编号
nickname?: string; // 用户昵称
telephone?: string; // 用户手机号
remark?: string; // 备注
}
}
/** 创建班组成员 */
export function createTeamMember(data: MesCalTeamMemberApi.TeamMember) {
return requestClient.post('/mes/cal/team-member/create', data);
}
/** 删除班组成员 */
export function deleteTeamMember(id: number) {
return requestClient.delete(`/mes/cal/team-member/delete?id=${id}`);
}
/** 查询班组成员分页 */
export function getTeamMemberPage(params: PageParam) {
return requestClient.get<PageResult<MesCalTeamMemberApi.TeamMember>>(
'/mes/cal/team-member/page',
{ params },
);
}
/** 查询指定班组的成员列表 */
export function getTeamMemberListByTeam(teamId: number) {
return requestClient.get<MesCalTeamMemberApi.TeamMember[]>(
'/mes/cal/team-member/list-by-team',
{ params: { teamId } },
);
}
/** 查询多个班组的成员列表 */
export function getTeamMemberListByTeamIds(teamIds: number[]) {
return requestClient.get<MesCalTeamMemberApi.TeamMember[]>(
'/mes/cal/team-member/list-by-team',
{
params: { teamIds: teamIds.join(',') },
},
);
}

View File

@ -0,0 +1,65 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvCheckPlanApi {
/** MES 点检保养方案 */
export interface CheckPlan {
id?: number; // 方案编号
code?: string; // 方案编码
name?: string; // 方案名称
type?: number; // 方案类型
startDate?: Date | number; // 开始日期
endDate?: Date | number; // 结束日期
cycleType?: number; // 周期类型
cycleCount?: number; // 周期数量
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询点检保养方案分页 */
export function getCheckPlanPage(params: PageParam) {
return requestClient.get<PageResult<MesDvCheckPlanApi.CheckPlan>>(
'/mes/dv/check-plan/page',
{ params },
);
}
/** 查询点检保养方案详情 */
export function getCheckPlan(id: number) {
return requestClient.get<MesDvCheckPlanApi.CheckPlan>(
`/mes/dv/check-plan/get?id=${id}`,
);
}
/** 新增点检保养方案 */
export function createCheckPlan(data: MesDvCheckPlanApi.CheckPlan) {
return requestClient.post<number>('/mes/dv/check-plan/create', data);
}
/** 修改点检保养方案 */
export function updateCheckPlan(data: MesDvCheckPlanApi.CheckPlan) {
return requestClient.put('/mes/dv/check-plan/update', data);
}
/** 启用点检保养方案 */
export function enableCheckPlan(id: number) {
return requestClient.put(`/mes/dv/check-plan/enable?id=${id}`);
}
/** 停用点检保养方案 */
export function disableCheckPlan(id: number) {
return requestClient.put(`/mes/dv/check-plan/disable?id=${id}`);
}
/** 删除点检保养方案 */
export function deleteCheckPlan(id: number) {
return requestClient.delete(`/mes/dv/check-plan/delete?id=${id}`);
}
/** 导出点检保养方案 */
export function exportCheckPlan(params: any) {
return requestClient.download('/mes/dv/check-plan/export-excel', { params });
}

View File

@ -0,0 +1,34 @@
import { requestClient } from '#/api/request';
export namespace MesDvCheckPlanMachineryApi {
/** MES 点检保养方案设备 */
export interface CheckPlanMachinery {
id?: number; // 关联编号
planId?: number; // 方案编号
machineryId?: number; // 设备编号
machineryCode?: string; // 设备编码
machineryName?: string; // 设备名称
machineryBrand?: string; // 品牌
machinerySpecification?: string; // 规格型号
remark?: string; // 备注
}
}
/** 查询指定方案的设备列表 */
export function getCheckPlanMachineryListByPlan(planId: number) {
return requestClient.get<MesDvCheckPlanMachineryApi.CheckPlanMachinery[]>(
`/mes/dv/check-plan-machinery/list-by-plan?planId=${planId}`,
);
}
/** 新增方案设备关联 */
export function createCheckPlanMachinery(
data: MesDvCheckPlanMachineryApi.CheckPlanMachinery,
) {
return requestClient.post('/mes/dv/check-plan-machinery/create', data);
}
/** 删除方案设备关联 */
export function deleteCheckPlanMachinery(id: number) {
return requestClient.delete(`/mes/dv/check-plan-machinery/delete?id=${id}`);
}

View File

@ -0,0 +1,35 @@
import { requestClient } from '#/api/request';
export namespace MesDvCheckPlanSubjectApi {
/** MES 点检保养方案项目 */
export interface CheckPlanSubject {
id?: number; // 关联编号
planId?: number; // 方案编号
subjectId?: number; // 项目编号
subjectCode?: string; // 项目编码
subjectName?: string; // 项目名称
subjectType?: number; // 项目类型
subjectContent?: string; // 项目内容
subjectStandard?: string; // 标准
remark?: string; // 备注
}
}
/** 查询指定方案的项目列表 */
export function getCheckPlanSubjectListByPlan(planId: number) {
return requestClient.get<MesDvCheckPlanSubjectApi.CheckPlanSubject[]>(
`/mes/dv/check-plan-subject/list-by-plan?planId=${planId}`,
);
}
/** 新增方案项目关联 */
export function createCheckPlanSubject(
data: MesDvCheckPlanSubjectApi.CheckPlanSubject,
) {
return requestClient.post('/mes/dv/check-plan-subject/create', data);
}
/** 删除方案项目关联 */
export function deleteCheckPlanSubject(id: number) {
return requestClient.delete(`/mes/dv/check-plan-subject/delete?id=${id}`);
}

View File

@ -0,0 +1,65 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvCheckRecordApi {
/** MES 设备点检记录 */
export interface CheckRecord {
id?: number; // 记录编号
planId?: number; // 点检计划编号
planName?: string; // 计划名称
machineryId?: number; // 设备编号
machineryCode?: string; // 设备编码
machineryName?: string; // 设备名称
machineryBrand?: string; // 品牌
machinerySpecification?: string; // 规格型号
checkTime?: Date | number; // 点检时间
userId?: number; // 点检人编号
nickname?: string; // 点检人名称
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询设备点检记录分页 */
export function getCheckRecordPage(params: PageParam) {
return requestClient.get<PageResult<MesDvCheckRecordApi.CheckRecord>>(
'/mes/dv/check-record/page',
{ params },
);
}
/** 查询设备点检记录详情 */
export function getCheckRecord(id: number) {
return requestClient.get<MesDvCheckRecordApi.CheckRecord>(
`/mes/dv/check-record/get?id=${id}`,
);
}
/** 新增设备点检记录 */
export function createCheckRecord(data: MesDvCheckRecordApi.CheckRecord) {
return requestClient.post<number>('/mes/dv/check-record/create', data);
}
/** 修改设备点检记录 */
export function updateCheckRecord(data: MesDvCheckRecordApi.CheckRecord) {
return requestClient.put('/mes/dv/check-record/update', data);
}
/** 提交设备点检记录 */
export function submitCheckRecord(id: number) {
return requestClient.put(`/mes/dv/check-record/submit?id=${id}`);
}
/** 删除设备点检记录 */
export function deleteCheckRecord(id: number) {
return requestClient.delete(`/mes/dv/check-record/delete?id=${id}`);
}
/** 导出设备点检记录 */
export function exportCheckRecord(params: any) {
return requestClient.download('/mes/dv/check-record/export-excel', {
params,
});
}

View File

@ -0,0 +1,53 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvCheckRecordLineApi {
/** MES 设备点检记录明细 */
export interface CheckRecordLine {
id?: number; // 明细编号
recordId?: number; // 点检记录编号
subjectId?: number; // 点检项目编号
subjectCode?: string; // 项目编码
subjectName?: string; // 项目名称
subjectContent?: string; // 检查内容
subjectStandard?: string; // 检查标准
checkStatus?: number; // 点检结果
checkResult?: string; // 异常描述
remark?: string; // 备注
}
}
/** 查询设备点检记录明细分页 */
export function getCheckRecordLinePage(params: PageParam) {
return requestClient.get<PageResult<MesDvCheckRecordLineApi.CheckRecordLine>>(
'/mes/dv/check-record-line/page',
{ params },
);
}
/** 查询设备点检记录明细详情 */
export function getCheckRecordLine(id: number) {
return requestClient.get<MesDvCheckRecordLineApi.CheckRecordLine>(
`/mes/dv/check-record-line/get?id=${id}`,
);
}
/** 新增设备点检记录明细 */
export function createCheckRecordLine(
data: MesDvCheckRecordLineApi.CheckRecordLine,
) {
return requestClient.post('/mes/dv/check-record-line/create', data);
}
/** 修改设备点检记录明细 */
export function updateCheckRecordLine(
data: MesDvCheckRecordLineApi.CheckRecordLine,
) {
return requestClient.put('/mes/dv/check-record-line/update', data);
}
/** 删除设备点检记录明细 */
export function deleteCheckRecordLine(id: number) {
return requestClient.delete(`/mes/dv/check-record-line/delete?id=${id}`);
}

View File

@ -0,0 +1,85 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvMachineryApi {
/** MES 设备台账 */
export interface Machinery {
id?: number; // 设备编号
code?: string; // 设备编码
name?: string; // 设备名称
brand?: string; // 品牌
specification?: string; // 规格型号
machineryTypeId?: number; // 设备类型编号
machineryTypeName?: string; // 设备类型名称
workshopId?: number; // 所属车间编号
workshopName?: string; // 所属车间名称
status?: number; // 设备状态
lastMaintenTime?: Date; // 最近保养时间
lastCheckTime?: Date; // 最近点检时间
remark?: string; // 备注
createTime?: Date; // 创建时间
}
/** 设备导入结果 */
export interface MachineryImportRespVO {
createCodes?: string[]; // 新增成功的设备编码
updateCodes?: string[]; // 更新成功的设备编码
failureCodes?: Record<string, string>; // 导入失败的设备编码及原因
}
}
/** 查询设备分页 */
export function getMachineryPage(params: PageParam) {
return requestClient.get<PageResult<MesDvMachineryApi.Machinery>>(
'/mes/dv/machinery/page',
{ params },
);
}
/** 查询设备精简列表 */
export function getMachinerySimpleList() {
return requestClient.get<MesDvMachineryApi.Machinery[]>(
'/mes/dv/machinery/simple-list',
);
}
/** 查询设备详情 */
export function getMachinery(id: number) {
return requestClient.get<MesDvMachineryApi.Machinery>(
`/mes/dv/machinery/get?id=${id}`,
);
}
/** 新增设备 */
export function createMachinery(data: MesDvMachineryApi.Machinery) {
return requestClient.post('/mes/dv/machinery/create', data);
}
/** 修改设备 */
export function updateMachinery(data: MesDvMachineryApi.Machinery) {
return requestClient.put('/mes/dv/machinery/update', data);
}
/** 删除设备 */
export function deleteMachinery(id: number) {
return requestClient.delete(`/mes/dv/machinery/delete?id=${id}`);
}
/** 导出设备 */
export function exportMachinery(params: any) {
return requestClient.download('/mes/dv/machinery/export-excel', { params });
}
/** 下载设备导入模板 */
export function importMachineryTemplate() {
return requestClient.download('/mes/dv/machinery/get-import-template');
}
/** 导入设备 */
export function importMachinery(file: File, updateSupport: boolean) {
return requestClient.upload<MesDvMachineryApi.MachineryImportRespVO>(
`/mes/dv/machinery/import?updateSupport=${updateSupport}`,
{ file },
);
}

View File

@ -0,0 +1,53 @@
import { requestClient } from '#/api/request';
export namespace MesDvMachineryTypeApi {
/** MES 设备类型 */
export interface MachineryType {
id?: number; // 设备类型编号
parentId?: number; // 父类型编号
code?: string; // 类型编码
name?: string; // 类型名称
sort?: number; // 显示排序
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
children?: MachineryType[]; // 子类型
}
}
/** 查询设备类型列表 */
export function getMachineryTypeList(params?: any) {
return requestClient.get<MesDvMachineryTypeApi.MachineryType[]>(
'/mes/dv/machinery-type/list',
{ params },
);
}
/** 查询设备类型精简列表 */
export function getMachineryTypeSimpleList() {
return requestClient.get<MesDvMachineryTypeApi.MachineryType[]>(
'/mes/dv/machinery-type/simple-list',
);
}
/** 查询设备类型详情 */
export function getMachineryType(id: number) {
return requestClient.get<MesDvMachineryTypeApi.MachineryType>(
`/mes/dv/machinery-type/get?id=${id}`,
);
}
/** 新增设备类型 */
export function createMachineryType(data: MesDvMachineryTypeApi.MachineryType) {
return requestClient.post('/mes/dv/machinery-type/create', data);
}
/** 修改设备类型 */
export function updateMachineryType(data: MesDvMachineryTypeApi.MachineryType) {
return requestClient.put('/mes/dv/machinery-type/update', data);
}
/** 删除设备类型 */
export function deleteMachineryType(id: number) {
return requestClient.delete(`/mes/dv/machinery-type/delete?id=${id}`);
}

View File

@ -0,0 +1,65 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvMaintenRecordApi {
/** MES 设备保养记录 */
export interface MaintenRecord {
id?: number; // 记录编号
planId?: number; // 计划编号
planName?: string; // 计划名称
machineryId?: number; // 设备编号
machineryCode?: string; // 设备编码
machineryName?: string; // 设备名称
machineryBrand?: string; // 品牌
machinerySpecification?: string; // 规格型号
maintenTime?: Date | number; // 保养时间
userId?: number; // 用户编号
nickname?: string; // 保养人名称
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询设备保养记录分页 */
export function getMaintenRecordPage(params: PageParam) {
return requestClient.get<PageResult<MesDvMaintenRecordApi.MaintenRecord>>(
'/mes/dv/mainten-record/page',
{ params },
);
}
/** 查询设备保养记录详情 */
export function getMaintenRecord(id: number) {
return requestClient.get<MesDvMaintenRecordApi.MaintenRecord>(
`/mes/dv/mainten-record/get?id=${id}`,
);
}
/** 新增设备保养记录 */
export function createMaintenRecord(data: MesDvMaintenRecordApi.MaintenRecord) {
return requestClient.post<number>('/mes/dv/mainten-record/create', data);
}
/** 修改设备保养记录 */
export function updateMaintenRecord(data: MesDvMaintenRecordApi.MaintenRecord) {
return requestClient.put('/mes/dv/mainten-record/update', data);
}
/** 提交设备保养记录 */
export function submitMaintenRecord(id: number) {
return requestClient.put(`/mes/dv/mainten-record/submit?id=${id}`);
}
/** 删除设备保养记录 */
export function deleteMaintenRecord(id: number) {
return requestClient.delete(`/mes/dv/mainten-record/delete?id=${id}`);
}
/** 导出设备保养记录 */
export function exportMaintenRecord(params: any) {
return requestClient.download('/mes/dv/mainten-record/export-excel', {
params,
});
}

View File

@ -0,0 +1,51 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvMaintenRecordLineApi {
/** MES 设备保养记录明细 */
export interface MaintenRecordLine {
id?: number; // 明细编号
recordId?: number; // 保养记录编号
subjectId?: number; // 项目编号
subjectName?: string; // 项目名称
subjectContent?: string; // 项目内容
subjectStandard?: string; // 项目标准
status?: number; // 保养结果
result?: string; // 异常描述
remark?: string; // 备注
}
}
/** 查询设备保养记录明细分页 */
export function getMaintenRecordLinePage(params: PageParam) {
return requestClient.get<
PageResult<MesDvMaintenRecordLineApi.MaintenRecordLine>
>('/mes/dv/mainten-record-line/page', { params });
}
/** 查询设备保养记录明细详情 */
export function getMaintenRecordLine(id: number) {
return requestClient.get<MesDvMaintenRecordLineApi.MaintenRecordLine>(
`/mes/dv/mainten-record-line/get?id=${id}`,
);
}
/** 新增设备保养记录明细 */
export function createMaintenRecordLine(
data: MesDvMaintenRecordLineApi.MaintenRecordLine,
) {
return requestClient.post('/mes/dv/mainten-record-line/create', data);
}
/** 修改设备保养记录明细 */
export function updateMaintenRecordLine(
data: MesDvMaintenRecordLineApi.MaintenRecordLine,
) {
return requestClient.put('/mes/dv/mainten-record-line/update', data);
}
/** 删除设备保养记录明细 */
export function deleteMaintenRecordLine(id: number) {
return requestClient.delete(`/mes/dv/mainten-record-line/delete?id=${id}`);
}

View File

@ -0,0 +1,81 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvRepairApi {
/** MES 维修工单 */
export interface Repair {
id?: number; // 工单编号
code?: string; // 维修工单编码
name?: string; // 维修工单名称
machineryId?: number; // 设备编号
machineryCode?: string; // 设备编码
machineryName?: string; // 设备名称
machineryBrand?: string; // 品牌
machinerySpecification?: string; // 规格型号
requireDate?: Date | number; // 报修日期
finishDate?: Date | number; // 维修完成日期
confirmDate?: Date | number; // 验收日期
result?: number; // 维修结果
acceptedUserId?: number; // 维修人编号
acceptedUserNickname?: string; // 维修人名称
confirmUserId?: number; // 验收人编号
confirmUserNickname?: string; // 验收人名称
sourceDocType?: number; // 来源单据类型
sourceDocId?: number; // 来源单据编号
sourceDocCode?: string; // 来源单据编码
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询维修工单分页 */
export function getRepairPage(params: PageParam) {
return requestClient.get<PageResult<MesDvRepairApi.Repair>>(
'/mes/dv/repair/page',
{ params },
);
}
/** 查询维修工单详情 */
export function getRepair(id: number) {
return requestClient.get<MesDvRepairApi.Repair>(
`/mes/dv/repair/get?id=${id}`,
);
}
/** 新增维修工单 */
export function createRepair(data: MesDvRepairApi.Repair) {
return requestClient.post<number>('/mes/dv/repair/create', data);
}
/** 修改维修工单 */
export function updateRepair(data: MesDvRepairApi.Repair) {
return requestClient.put('/mes/dv/repair/update', data);
}
/** 删除维修工单 */
export function deleteRepair(id: number) {
return requestClient.delete(`/mes/dv/repair/delete?id=${id}`);
}
/** 导出维修工单 */
export function exportRepair(params: any) {
return requestClient.download('/mes/dv/repair/export-excel', { params });
}
/** 提交维修工单 */
export function submitRepair(id: number) {
return requestClient.put(`/mes/dv/repair/submit?id=${id}`);
}
/** 确认维修完成 */
export function confirmRepair(data: MesDvRepairApi.Repair) {
return requestClient.put('/mes/dv/repair/confirm', data);
}
/** 完成验收 */
export function finishRepair(id: number, result: number) {
return requestClient.put(`/mes/dv/repair/finish?id=${id}&result=${result}`);
}

View File

@ -0,0 +1,49 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvRepairLineApi {
/** MES 维修工单行 */
export interface RepairLine {
id?: number; // 明细编号
repairId?: number; // 维修工单编号
subjectId?: number; // 项目编号
subjectName?: string; // 项目名称
subjectContent?: string; // 项目内容
subjectStandard?: string; // 项目标准
malfunction?: string; // 故障描述
malfunctionUrl?: string; // 故障图片 URL
description?: string; // 维修描述
remark?: string; // 备注
}
}
/** 查询维修工单行分页 */
export function getRepairLinePage(params: PageParam) {
return requestClient.get<PageResult<MesDvRepairLineApi.RepairLine>>(
'/mes/dv/repair-line/page',
{ params },
);
}
/** 查询维修工单行详情 */
export function getRepairLine(id: number) {
return requestClient.get<MesDvRepairLineApi.RepairLine>(
`/mes/dv/repair-line/get?id=${id}`,
);
}
/** 新增维修工单行 */
export function createRepairLine(data: MesDvRepairLineApi.RepairLine) {
return requestClient.post('/mes/dv/repair-line/create', data);
}
/** 修改维修工单行 */
export function updateRepairLine(data: MesDvRepairLineApi.RepairLine) {
return requestClient.put('/mes/dv/repair-line/update', data);
}
/** 删除维修工单行 */
export function deleteRepairLine(id: number) {
return requestClient.delete(`/mes/dv/repair-line/delete?id=${id}`);
}

View File

@ -0,0 +1,60 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesDvSubjectApi {
/** MES 点检保养项目 */
export interface Subject {
id?: number; // 项目编号
code?: string; // 项目编码
name?: string; // 项目名称
type?: number; // 项目类型
content?: string; // 项目内容
standard?: string; // 标准
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询点检保养项目分页 */
export function getSubjectPage(params: PageParam) {
return requestClient.get<PageResult<MesDvSubjectApi.Subject>>(
'/mes/dv/subject/page',
{ params },
);
}
/** 查询点检保养项目精简列表 */
export function getSubjectSimpleList() {
return requestClient.get<MesDvSubjectApi.Subject[]>(
'/mes/dv/subject/simple-list',
);
}
/** 查询点检保养项目详情 */
export function getSubject(id: number) {
return requestClient.get<MesDvSubjectApi.Subject>(
`/mes/dv/subject/get?id=${id}`,
);
}
/** 新增点检保养项目 */
export function createSubject(data: MesDvSubjectApi.Subject) {
return requestClient.post('/mes/dv/subject/create', data);
}
/** 修改点检保养项目 */
export function updateSubject(data: MesDvSubjectApi.Subject) {
return requestClient.put('/mes/dv/subject/update', data);
}
/** 删除点检保养项目 */
export function deleteSubject(id: number) {
return requestClient.delete(`/mes/dv/subject/delete?id=${id}`);
}
/** 导出点检保养项目 */
export function exportSubject(params: any) {
return requestClient.download('/mes/dv/subject/export-excel', { params });
}

View File

@ -0,0 +1,55 @@
import { requestClient } from '#/api/request';
export namespace MesHomeApi {
/** MES 首页汇总统计 */
export interface Summary {
workOrderActiveCount: number; // 进行中工单数
workOrderPrepareCount: number; // 待排产工单数
workOrderFinishedCount: number; // 已完成工单数
todayOutput: number; // 今日产量
yesterdayOutput: number; // 昨日产量
todayQualifiedQuantity: number; // 今日合格品数
todayUnqualifiedQuantity: number; // 今日不良品数
machineryTotal: number; // 设备总数
machineryProducing: number; // 生产中设备数
machineryStop: number; // 停机设备数
machineryMaintenance: number; // 维护中设备数
andonActiveCount: number; // 未处置安灯呼叫数
repairActiveCount: number; // 待处理维修工单数
}
/** MES 工单状态分布 */
export interface WorkOrderStatus {
status: number; // 工单状态
statusName: string; // 工单状态名称
count: number; // 数量
}
/** MES 生产趋势 */
export interface ProductionTrend {
date: string; // 日期
quantity: number; // 产量
qualifiedQuantity: number; // 合格品数
unqualifiedQuantity: number; // 不良品数
}
}
/** 获得首页汇总统计 */
export function getHomeSummary() {
return requestClient.get<MesHomeApi.Summary>('/mes/home-statistics/summary');
}
/** 获得工单状态分布 */
export function getWorkOrderStatusDistribution() {
return requestClient.get<MesHomeApi.WorkOrderStatus[]>(
'/mes/home-statistics/work-order-status',
);
}
/** 获得生产趋势 */
export function getProductionTrend(days?: number) {
return requestClient.get<MesHomeApi.ProductionTrend[]>(
'/mes/home-statistics/production-trend',
{ params: { days } },
);
}

View File

@ -0,0 +1,49 @@
import { requestClient } from '#/api/request';
export namespace MesMdAutoCodePartApi {
/** MES 编码规则分段 */
export interface AutoCodePart {
id?: number; // 分段编号
ruleId?: number; // 规则编号
sort?: number; // 排序
type?: number; // 分段类型
length?: number; // 长度
dateFormat?: string; // 日期格式
fixCharacter?: string; // 固定字符
serialStartNo?: number; // 流水号起始值
serialStep?: number; // 流水号步长
cycleFlag?: boolean; // 是否循环
cycleMethod?: number; // 循环方式
remark?: string; // 备注
}
}
/** 查询编码规则分段详情 */
export function getAutoCodePart(id: number) {
return requestClient.get<MesMdAutoCodePartApi.AutoCodePart>(
`/mes/md/auto-code-part/get?id=${id}`,
);
}
/** 查询编码规则分段列表 */
export function getAutoCodePartListByRuleId(ruleId: number) {
return requestClient.get<MesMdAutoCodePartApi.AutoCodePart[]>(
'/mes/md/auto-code-part/list-by-rule-id',
{ params: { ruleId } },
);
}
/** 新增编码规则分段 */
export function createAutoCodePart(data: MesMdAutoCodePartApi.AutoCodePart) {
return requestClient.post('/mes/md/auto-code-part/create', data);
}
/** 修改编码规则分段 */
export function updateAutoCodePart(data: MesMdAutoCodePartApi.AutoCodePart) {
return requestClient.put('/mes/md/auto-code-part/update', data);
}
/** 删除编码规则分段 */
export function deleteAutoCodePart(id: number) {
return requestClient.delete(`/mes/md/auto-code-part/delete?id=${id}`);
}

View File

@ -0,0 +1,9 @@
import { requestClient } from '#/api/request';
/** 生成 MES 编码 */
export function generateAutoCode(ruleCode: string, inputChar?: string) {
return requestClient.post<string>('/mes/md/auto-code-record/generate', {
inputChar,
ruleCode,
});
}

View File

@ -0,0 +1,57 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdAutoCodeRuleApi {
/** MES 编码规则 */
export interface AutoCodeRule {
id?: number; // 规则编号
code?: string; // 规则编码
name?: string; // 规则名称
description?: string; // 规则描述
maxLength?: number; // 最大长度
padded?: boolean; // 是否补齐
paddedChar?: string; // 补齐字符
paddedMethod?: number; // 补齐方式
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询编码规则分页 */
export function getAutoCodeRulePage(params: PageParam) {
return requestClient.get<PageResult<MesMdAutoCodeRuleApi.AutoCodeRule>>(
'/mes/md/auto-code-rule/page',
{ params },
);
}
/** 查询编码规则详情 */
export function getAutoCodeRule(id: number) {
return requestClient.get<MesMdAutoCodeRuleApi.AutoCodeRule>(
`/mes/md/auto-code-rule/get?id=${id}`,
);
}
/** 新增编码规则 */
export function createAutoCodeRule(data: MesMdAutoCodeRuleApi.AutoCodeRule) {
return requestClient.post('/mes/md/auto-code-rule/create', data);
}
/** 修改编码规则 */
export function updateAutoCodeRule(data: MesMdAutoCodeRuleApi.AutoCodeRule) {
return requestClient.put('/mes/md/auto-code-rule/update', data);
}
/** 删除编码规则 */
export function deleteAutoCodeRule(id: number) {
return requestClient.delete(`/mes/md/auto-code-rule/delete?id=${id}`);
}
/** 导出编码规则 */
export function exportAutoCodeRule(params: PageParam) {
return requestClient.download('/mes/md/auto-code-rule/export-excel', {
params,
});
}

View File

@ -0,0 +1,86 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdClientApi {
/** MES 客户 */
export interface Client {
id?: number; // 客户编号
code?: string; // 客户编码
name?: string; // 客户名称
nickname?: string; // 客户简称
englishName?: string; // 客户英文名称
description?: string; // 客户简介
logo?: string; // 客户 LOGO 地址
type?: number; // 客户类型
address?: string; // 客户地址
website?: string; // 客户官网地址
email?: string; // 客户邮箱地址
telephone?: string; // 客户电话
contact1Name?: string; // 联系人1
contact1Telephone?: string; // 联系人1电话
contact1Email?: string; // 联系人1邮箱
contact2Name?: string; // 联系人2
contact2Telephone?: string; // 联系人2电话
contact2Email?: string; // 联系人2邮箱
creditCode?: string; // 统一社会信用代码
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
/** 客户导入结果 */
export interface ClientImportRespVO {
createCodes?: string[]; // 新增成功的客户编码
updateCodes?: string[]; // 更新成功的客户编码
failureCodes?: Record<string, string>; // 导入失败的客户编码及原因
}
}
/** 查询客户分页 */
export function getClientPage(params: PageParam) {
return requestClient.get<PageResult<MesMdClientApi.Client>>(
'/mes/md-client/page',
{ params },
);
}
/** 查询客户详情 */
export function getClient(id: number) {
return requestClient.get<MesMdClientApi.Client>(
`/mes/md-client/get?id=${id}`,
);
}
/** 新增客户 */
export function createClient(data: MesMdClientApi.Client) {
return requestClient.post('/mes/md-client/create', data);
}
/** 修改客户 */
export function updateClient(data: MesMdClientApi.Client) {
return requestClient.put('/mes/md-client/update', data);
}
/** 删除客户 */
export function deleteClient(id: number) {
return requestClient.delete(`/mes/md-client/delete?id=${id}`);
}
/** 导出客户 */
export function exportClient(params: any) {
return requestClient.download('/mes/md-client/export-excel', { params });
}
/** 下载客户导入模板 */
export function importClientTemplate() {
return requestClient.download('/mes/md-client/get-import-template');
}
/** 导入客户 */
export function importClient(file: File, updateSupport: boolean) {
return requestClient.upload<MesMdClientApi.ClientImportRespVO>(
`/mes/md-client/import?updateSupport=${updateSupport}`,
{ file },
);
}

View File

@ -0,0 +1,35 @@
import { requestClient } from '#/api/request';
export namespace MesMdItemBatchConfigApi {
/** MES 物料批次属性配置 */
export interface BatchConfig {
id?: number; // 编号
itemId?: number; // 物料编号
produceDateFlag?: boolean; // 批次属性-生产日期
expireDateFlag?: boolean; // 批次属性-有效期
receiptDateFlag?: boolean; // 批次属性-入库日期
vendorFlag?: boolean; // 批次属性-供应商
clientFlag?: boolean; // 批次属性-客户
salesOrderCodeFlag?: boolean; // 批次属性-销售订单编号
purchaseOrderCodeFlag?: boolean; // 批次属性-采购订单编号
workorderFlag?: boolean; // 批次属性-生产工单
taskFlag?: boolean; // 批次属性-生产任务
workstationFlag?: boolean; // 批次属性-工作站
toolFlag?: boolean; // 批次属性-工具
moldFlag?: boolean; // 批次属性-模具
lotNumberFlag?: boolean; // 批次属性-生产批号
qualityStatusFlag?: boolean; // 批次属性-质量状态
}
}
/** 根据物料编号获取批次属性配置 */
export function getBatchConfigByItemId(itemId: number) {
return requestClient.get<MesMdItemBatchConfigApi.BatchConfig>(
`/mes/md/item-batch-config/get-by-item-id?itemId=${itemId}`,
);
}
/** 保存批次属性配置 */
export function saveBatchConfig(data: MesMdItemBatchConfigApi.BatchConfig) {
return requestClient.post('/mes/md/item-batch-config/save', data);
}

View File

@ -0,0 +1,85 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdItemApi {
/** MES 物料产品 */
export interface Item {
id?: number; // 物料编号
code?: string; // 物料编码
name?: string; // 物料名称
specification?: string; // 规格型号
unitMeasureId?: number; // 计量单位编号
unitMeasureName?: string; // 计量单位名称
itemTypeId?: number; // 物料分类编号
itemTypeName?: string; // 物料分类名称
itemOrProduct?: string; // 物料/产品标识
status?: number; // 状态
safeStockFlag?: boolean; // 是否启用安全库存
minStock?: number; // 最低库存量
maxStock?: number; // 最高库存量
highValue?: boolean; // 是否高值物料
batchFlag?: boolean; // 是否启用批次管理
remark?: string; // 备注
createTime?: Date; // 创建时间
}
/** 物料导入结果 */
export interface ItemImportRespVO {
createCodes?: string[]; // 新增成功的物料编码
updateCodes?: string[]; // 更新成功的物料编码
failureCodes?: Record<string, string>; // 导入失败的物料编码及原因
}
}
/** 查询物料产品分页 */
export function getItemPage(params: PageParam) {
return requestClient.get<PageResult<MesMdItemApi.Item>>('/mes/md/item/page', {
params,
});
}
/** 查询物料产品详情 */
export function getItem(id: number) {
return requestClient.get<MesMdItemApi.Item>(`/mes/md/item/get?id=${id}`);
}
/** 新增物料产品 */
export function createItem(data: MesMdItemApi.Item) {
return requestClient.post<number>('/mes/md/item/create', data);
}
/** 修改物料产品 */
export function updateItem(data: MesMdItemApi.Item) {
return requestClient.put('/mes/md/item/update', data);
}
/** 修改物料产品状态 */
export function updateItemStatus(id: number, status: number) {
return requestClient.put('/mes/md/item/update-status', undefined, {
params: { id, status },
});
}
/** 删除物料产品 */
export function deleteItem(id: number) {
return requestClient.delete(`/mes/md/item/delete?id=${id}`);
}
/** 导出物料产品 */
export function exportItem(params: any) {
return requestClient.download('/mes/md/item/export-excel', { params });
}
/** 下载物料导入模板 */
export function importItemTemplate() {
return requestClient.download('/mes/md/item/get-import-template');
}
/** 导入物料产品 */
export function importItem(file: File, updateSupport: boolean) {
return requestClient.upload<MesMdItemApi.ItemImportRespVO>(
`/mes/md/item/import?updateSupport=${updateSupport}`,
{ file },
);
}

View File

@ -0,0 +1,58 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdProductBomApi {
/** MES 产品 BOM */
export interface ProductBom {
id?: number; // BOM 编号
itemId?: number; // 物料产品编号
bomItemId?: number; // BOM 物料编号
quantity?: number; // 物料使用比例
status?: number; // 是否启用
remark?: string; // 备注
createTime?: Date; // 创建时间
bomItemCode?: string; // BOM 物料编码
bomItemName?: string; // BOM 物料名称
bomItemSpecification?: string; // BOM 物料规格
unitMeasureName?: string; // 计量单位名称
itemOrProduct?: string; // 物料/产品标识
}
}
/** 新增产品 BOM */
export function createProductBom(data: MesMdProductBomApi.ProductBom) {
return requestClient.post('/mes/md/product-bom/create', data);
}
/** 修改产品 BOM */
export function updateProductBom(data: MesMdProductBomApi.ProductBom) {
return requestClient.put('/mes/md/product-bom/update', data);
}
/** 删除产品 BOM */
export function deleteProductBom(id: number) {
return requestClient.delete(`/mes/md/product-bom/delete?id=${id}`);
}
/** 查询产品 BOM 详情 */
export function getProductBom(id: number) {
return requestClient.get<MesMdProductBomApi.ProductBom>(
`/mes/md/product-bom/get?id=${id}`,
);
}
/** 查询产品 BOM 分页 */
export function getProductBomPage(params: PageParam) {
return requestClient.get<PageResult<MesMdProductBomApi.ProductBom>>(
'/mes/md/product-bom/page',
{ params },
);
}
/** 根据物料产品编号查询产品 BOM 列表 */
export function getProductBomListByItemId(itemId: number) {
return requestClient.get<MesMdProductBomApi.ProductBom[]>(
`/mes/md/product-bom/list-by-item-id?itemId=${itemId}`,
);
}

View File

@ -0,0 +1,57 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdProductSipApi {
/** MES 产品 SIP */
export interface ProductSip {
id?: number; // SIP 编号
itemId?: number; // 物料产品编号
sort?: number; // 排列顺序
processId?: number; // 工序编号
title?: string; // 标题
description?: string; // 详细描述
url?: string; // 图片地址
remark?: string; // 备注
createTime?: Date; // 创建时间
processCode?: string; // 工序编码
processName?: string; // 工序名称
}
}
/** 新增产品 SIP */
export function createProductSip(data: MesMdProductSipApi.ProductSip) {
return requestClient.post('/mes/md/product-sip/create', data);
}
/** 修改产品 SIP */
export function updateProductSip(data: MesMdProductSipApi.ProductSip) {
return requestClient.put('/mes/md/product-sip/update', data);
}
/** 删除产品 SIP */
export function deleteProductSip(id: number) {
return requestClient.delete(`/mes/md/product-sip/delete?id=${id}`);
}
/** 查询产品 SIP 详情 */
export function getProductSip(id: number) {
return requestClient.get<MesMdProductSipApi.ProductSip>(
`/mes/md/product-sip/get?id=${id}`,
);
}
/** 查询产品 SIP 分页 */
export function getProductSipPage(params: PageParam) {
return requestClient.get<PageResult<MesMdProductSipApi.ProductSip>>(
'/mes/md/product-sip/page',
{ params },
);
}
/** 根据物料产品编号查询产品 SIP 列表 */
export function getProductSipListByItemId(itemId: number) {
return requestClient.get<MesMdProductSipApi.ProductSip[]>(
`/mes/md/product-sip/list-by-item-id?itemId=${itemId}`,
);
}

View File

@ -0,0 +1,57 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdProductSopApi {
/** MES 产品 SOP */
export interface ProductSop {
id?: number; // SOP 编号
itemId?: number; // 物料产品编号
sort?: number; // 排列顺序
processId?: number; // 工序编号
title?: string; // 标题
description?: string; // 详细描述
url?: string; // 图片地址
remark?: string; // 备注
createTime?: Date; // 创建时间
processCode?: string; // 工序编码
processName?: string; // 工序名称
}
}
/** 新增产品 SOP */
export function createProductSop(data: MesMdProductSopApi.ProductSop) {
return requestClient.post('/mes/md/product-sop/create', data);
}
/** 修改产品 SOP */
export function updateProductSop(data: MesMdProductSopApi.ProductSop) {
return requestClient.put('/mes/md/product-sop/update', data);
}
/** 删除产品 SOP */
export function deleteProductSop(id: number) {
return requestClient.delete(`/mes/md/product-sop/delete?id=${id}`);
}
/** 查询产品 SOP 详情 */
export function getProductSop(id: number) {
return requestClient.get<MesMdProductSopApi.ProductSop>(
`/mes/md/product-sop/get?id=${id}`,
);
}
/** 查询产品 SOP 分页 */
export function getProductSopPage(params: PageParam) {
return requestClient.get<PageResult<MesMdProductSopApi.ProductSop>>(
'/mes/md/product-sop/page',
{ params },
);
}
/** 根据物料产品编号查询产品 SOP 列表 */
export function getProductSopListByItemId(itemId: number) {
return requestClient.get<MesMdProductSopApi.ProductSop[]>(
`/mes/md/product-sop/list-by-item-id?itemId=${itemId}`,
);
}

View File

@ -0,0 +1,54 @@
import { requestClient } from '#/api/request';
export namespace MesMdItemTypeApi {
/** MES 物料产品分类 */
export interface ItemType {
id?: number; // 分类编号
parentId?: number; // 父分类编号
code?: string; // 分类编码
name?: string; // 分类名称
itemOrProduct?: string; // 物料/产品标识
sort?: number; // 显示排序
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
children?: ItemType[]; // 子分类
}
}
/** 查询物料产品分类列表 */
export function getItemTypeList(params?: any) {
return requestClient.get<MesMdItemTypeApi.ItemType[]>(
'/mes/md/item-type/list',
{ params },
);
}
/** 查询物料产品分类精简列表 */
export function getItemTypeSimpleList() {
return requestClient.get<MesMdItemTypeApi.ItemType[]>(
'/mes/md/item-type/simple-list',
);
}
/** 查询物料产品分类详情 */
export function getItemType(id: number) {
return requestClient.get<MesMdItemTypeApi.ItemType>(
`/mes/md/item-type/get?id=${id}`,
);
}
/** 新增物料产品分类 */
export function createItemType(data: MesMdItemTypeApi.ItemType) {
return requestClient.post('/mes/md/item-type/create', data);
}
/** 修改物料产品分类 */
export function updateItemType(data: MesMdItemTypeApi.ItemType) {
return requestClient.put('/mes/md/item-type/update', data);
}
/** 删除物料产品分类 */
export function deleteItemType(id: number) {
return requestClient.delete(`/mes/md/item-type/delete?id=${id}`);
}

View File

@ -0,0 +1,62 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdUnitMeasureApi {
/** MES 计量单位 */
export interface UnitMeasure {
id?: number; // 单位编号
code?: string; // 单位编码
name?: string; // 单位名称
primaryFlag?: boolean; // 是否主单位
primaryId?: number; // 主单位编号
changeRate?: number; // 与主单位换算比例
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询计量单位分页 */
export function getUnitMeasurePage(params: PageParam) {
return requestClient.get<PageResult<MesMdUnitMeasureApi.UnitMeasure>>(
'/mes/md/unit-measure/page',
{ params },
);
}
/** 查询计量单位精简列表 */
export function getUnitMeasureSimpleList() {
return requestClient.get<MesMdUnitMeasureApi.UnitMeasure[]>(
'/mes/md/unit-measure/simple-list',
);
}
/** 查询计量单位详情 */
export function getUnitMeasure(id: number) {
return requestClient.get<MesMdUnitMeasureApi.UnitMeasure>(
`/mes/md/unit-measure/get?id=${id}`,
);
}
/** 新增计量单位 */
export function createUnitMeasure(data: MesMdUnitMeasureApi.UnitMeasure) {
return requestClient.post('/mes/md/unit-measure/create', data);
}
/** 修改计量单位 */
export function updateUnitMeasure(data: MesMdUnitMeasureApi.UnitMeasure) {
return requestClient.put('/mes/md/unit-measure/update', data);
}
/** 删除计量单位 */
export function deleteUnitMeasure(id: number) {
return requestClient.delete(`/mes/md/unit-measure/delete?id=${id}`);
}
/** 导出计量单位 */
export function exportUnitMeasure(params: PageParam) {
return requestClient.download('/mes/md/unit-measure/export-excel', {
params,
});
}

View File

@ -0,0 +1,87 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdVendorApi {
/** MES 供应商 */
export interface Vendor {
id?: number; // 供应商编号
code?: string; // 供应商编码
name?: string; // 供应商名称
nickname?: string; // 供应商简称
englishName?: string; // 供应商英文名称
description?: string; // 供应商简介
logo?: string; // 供应商 LOGO 地址
level?: string; // 供应商等级
score?: number; // 供应商评分
address?: string; // 供应商地址
website?: string; // 供应商官网地址
email?: string; // 供应商邮箱地址
telephone?: string; // 供应商电话
contact1Name?: string; // 联系人1
contact1Telephone?: string; // 联系人1电话
contact1Email?: string; // 联系人1邮箱
contact2Name?: string; // 联系人2
contact2Telephone?: string; // 联系人2电话
contact2Email?: string; // 联系人2邮箱
creditCode?: string; // 统一社会信用代码
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
/** 供应商导入结果 */
export interface VendorImportRespVO {
createCodes?: string[]; // 新增成功的供应商编码
updateCodes?: string[]; // 更新成功的供应商编码
failureCodes?: Record<string, string>; // 导入失败的供应商编码及原因
}
}
/** 查询供应商分页 */
export function getVendorPage(params: PageParam) {
return requestClient.get<PageResult<MesMdVendorApi.Vendor>>(
'/mes/md-vendor/page',
{ params },
);
}
/** 查询供应商详情 */
export function getVendor(id: number) {
return requestClient.get<MesMdVendorApi.Vendor>(
`/mes/md-vendor/get?id=${id}`,
);
}
/** 新增供应商 */
export function createVendor(data: MesMdVendorApi.Vendor) {
return requestClient.post('/mes/md-vendor/create', data);
}
/** 修改供应商 */
export function updateVendor(data: MesMdVendorApi.Vendor) {
return requestClient.put('/mes/md-vendor/update', data);
}
/** 删除供应商 */
export function deleteVendor(id: number) {
return requestClient.delete(`/mes/md-vendor/delete?id=${id}`);
}
/** 导出供应商 */
export function exportVendor(params: any) {
return requestClient.download('/mes/md-vendor/export-excel', { params });
}
/** 下载供应商导入模板 */
export function importVendorTemplate() {
return requestClient.download('/mes/md-vendor/get-import-template');
}
/** 导入供应商 */
export function importVendor(file: File, updateSupport: boolean) {
return requestClient.upload<MesMdVendorApi.VendorImportRespVO>(
`/mes/md-vendor/import?updateSupport=${updateSupport}`,
{ file },
);
}

View File

@ -0,0 +1,58 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdWorkstationApi {
/** MES 工作站 */
export interface Workstation {
id?: number; // 工作站编号
code?: string; // 工作站编码
name?: string; // 工作站名称
address?: string; // 工作站地点
workshopId?: number; // 所在车间编号
workshopName?: string; // 所在车间名称
processId?: number; // 工序编号
processName?: string; // 工序名称
warehouseId?: number; // 线边库编号
locationId?: number; // 库区编号
areaId?: number; // 库位编号
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询工作站分页 */
export function getWorkstationPage(params: PageParam) {
return requestClient.get<PageResult<MesMdWorkstationApi.Workstation>>(
'/mes/md-workstation/page',
{ params },
);
}
/** 查询工作站详情 */
export function getWorkstation(id: number) {
return requestClient.get<MesMdWorkstationApi.Workstation>(
`/mes/md-workstation/get?id=${id}`,
);
}
/** 新增工作站 */
export function createWorkstation(data: MesMdWorkstationApi.Workstation) {
return requestClient.post<number>('/mes/md-workstation/create', data);
}
/** 修改工作站 */
export function updateWorkstation(data: MesMdWorkstationApi.Workstation) {
return requestClient.put('/mes/md-workstation/update', data);
}
/** 删除工作站 */
export function deleteWorkstation(id: number) {
return requestClient.delete(`/mes/md-workstation/delete?id=${id}`);
}
/** 导出工作站 */
export function exportWorkstation(params: any) {
return requestClient.download('/mes/md-workstation/export-excel', { params });
}

View File

@ -0,0 +1,35 @@
import { requestClient } from '#/api/request';
export namespace MesMdWorkstationMachineApi {
/** MES 工作站设备资源 */
export interface WorkstationMachine {
id?: number; // 资源编号
workstationId?: number; // 工作站编号
machineryId?: number; // 设备编号
machineryCode?: string; // 设备编码
machineryName?: string; // 设备名称
quantity?: number; // 数量
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询工作站设备资源列表 */
export function getWorkstationMachineList(workstationId: number) {
return requestClient.get<MesMdWorkstationMachineApi.WorkstationMachine[]>(
'/mes/md-workstation-machine/list-by-workstation',
{ params: { workstationId } },
);
}
/** 新增工作站设备资源 */
export function createWorkstationMachine(
data: MesMdWorkstationMachineApi.WorkstationMachine,
) {
return requestClient.post('/mes/md-workstation-machine/create', data);
}
/** 删除工作站设备资源 */
export function deleteWorkstationMachine(id: number) {
return requestClient.delete(`/mes/md-workstation-machine/delete?id=${id}`);
}

View File

@ -0,0 +1,41 @@
import { requestClient } from '#/api/request';
export namespace MesMdWorkstationToolApi {
/** MES 工作站工装夹具资源 */
export interface WorkstationTool {
id?: number; // 资源编号
workstationId?: number; // 工作站编号
toolTypeId?: number; // 工具类型编号
toolTypeName?: string; // 工具类型名称
quantity?: number; // 数量
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询工作站工装夹具资源列表 */
export function getWorkstationToolList(workstationId: number) {
return requestClient.get<MesMdWorkstationToolApi.WorkstationTool[]>(
'/mes/md-workstation-tool/list-by-workstation',
{ params: { workstationId } },
);
}
/** 新增工作站工装夹具资源 */
export function createWorkstationTool(
data: MesMdWorkstationToolApi.WorkstationTool,
) {
return requestClient.post('/mes/md-workstation-tool/create', data);
}
/** 修改工作站工装夹具资源 */
export function updateWorkstationTool(
data: MesMdWorkstationToolApi.WorkstationTool,
) {
return requestClient.put('/mes/md-workstation-tool/update', data);
}
/** 删除工作站工装夹具资源 */
export function deleteWorkstationTool(id: number) {
return requestClient.delete(`/mes/md-workstation-tool/delete?id=${id}`);
}

View File

@ -0,0 +1,41 @@
import { requestClient } from '#/api/request';
export namespace MesMdWorkstationWorkerApi {
/** MES 工作站人力资源 */
export interface WorkstationWorker {
id?: number; // 资源编号
workstationId?: number; // 工作站编号
postId?: number; // 岗位编号
postName?: string; // 岗位名称
quantity?: number; // 数量
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询工作站人力资源列表 */
export function getWorkstationWorkerList(workstationId: number) {
return requestClient.get<MesMdWorkstationWorkerApi.WorkstationWorker[]>(
'/mes/md-workstation-worker/list-by-workstation',
{ params: { workstationId } },
);
}
/** 新增工作站人力资源 */
export function createWorkstationWorker(
data: MesMdWorkstationWorkerApi.WorkstationWorker,
) {
return requestClient.post('/mes/md-workstation-worker/create', data);
}
/** 修改工作站人力资源 */
export function updateWorkstationWorker(
data: MesMdWorkstationWorkerApi.WorkstationWorker,
) {
return requestClient.put('/mes/md-workstation-worker/update', data);
}
/** 删除工作站人力资源 */
export function deleteWorkstationWorker(id: number) {
return requestClient.delete(`/mes/md-workstation-worker/delete?id=${id}`);
}

View File

@ -0,0 +1,60 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesMdWorkshopApi {
/** MES 车间 */
export interface Workshop {
id?: number; // 车间编号
code?: string; // 车间编码
name?: string; // 车间名称
area?: number; // 面积
chargeUserId?: number; // 负责人用户编号
chargeUserName?: string; // 负责人名称
status?: number; // 状态
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询车间分页 */
export function getWorkshopPage(params: PageParam) {
return requestClient.get<PageResult<MesMdWorkshopApi.Workshop>>(
'/mes/md-workshop/page',
{ params },
);
}
/** 查询车间精简列表 */
export function getWorkshopSimpleList() {
return requestClient.get<MesMdWorkshopApi.Workshop[]>(
'/mes/md-workshop/simple-list',
);
}
/** 查询车间详情 */
export function getWorkshop(id: number) {
return requestClient.get<MesMdWorkshopApi.Workshop>(
`/mes/md-workshop/get?id=${id}`,
);
}
/** 新增车间 */
export function createWorkshop(data: MesMdWorkshopApi.Workshop) {
return requestClient.post('/mes/md-workshop/create', data);
}
/** 修改车间 */
export function updateWorkshop(data: MesMdWorkshopApi.Workshop) {
return requestClient.put('/mes/md-workshop/update', data);
}
/** 删除车间 */
export function deleteWorkshop(id: number) {
return requestClient.delete(`/mes/md-workshop/delete?id=${id}`);
}
/** 导出车间 */
export function exportWorkshop(params: any) {
return requestClient.download('/mes/md-workshop/export-excel', { params });
}

View File

@ -0,0 +1,54 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProAndonConfigApi {
/** MES 安灯配置 */
export interface AndonConfig {
id?: number; // 编号
reason?: string; // 呼叫原因
level?: number; // 级别
handlerRoleId?: number; // 处置角色编号
handlerRoleName?: string; // 处置角色名称
handlerUserId?: number; // 处置人编号
handlerUserNickname?: string; // 处置人昵称
remark?: string; // 备注
}
}
/** 查询安灯配置分页 */
export function getAndonConfigPage(params: PageParam) {
return requestClient.get<PageResult<MesProAndonConfigApi.AndonConfig>>(
'/mes/pro/andon-config/page',
{ params },
);
}
/** 查询安灯配置列表 */
export function getAndonConfigList() {
return requestClient.get<MesProAndonConfigApi.AndonConfig[]>(
'/mes/pro/andon-config/list',
);
}
/** 查询安灯配置详情 */
export function getAndonConfig(id: number) {
return requestClient.get<MesProAndonConfigApi.AndonConfig>(
`/mes/pro/andon-config/get?id=${id}`,
);
}
/** 新增安灯配置 */
export function createAndonConfig(data: MesProAndonConfigApi.AndonConfig) {
return requestClient.post('/mes/pro/andon-config/create', data);
}
/** 修改安灯配置 */
export function updateAndonConfig(data: MesProAndonConfigApi.AndonConfig) {
return requestClient.put('/mes/pro/andon-config/update', data);
}
/** 删除安灯配置 */
export function deleteAndonConfig(id: number) {
return requestClient.delete(`/mes/pro/andon-config/delete?id=${id}`);
}

View File

@ -0,0 +1,76 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProAndonRecordApi {
/** MES 安灯记录 */
export interface AndonRecord {
id?: number;
configId?: number; // 安灯配置编号
workstationId?: number; // 工作站编号
workstationCode?: string; // 工作站编码
workstationName?: string; // 工作站名称
workOrderId?: number; // 生产工单编号
workOrderCode?: string; // 工单编码
processId?: number; // 工序编号
processName?: string; // 工序名称
userId?: number; // 发起用户编号
userNickname?: string; // 发起人昵称
reason?: string; // 呼叫原因
level?: number; // 级别
status?: number; // 处置状态
handleTime?: number; // 处置时间(毫秒时间戳)
handlerUserId?: number; // 处置人编号
handlerUserNickname?: string; // 处置人昵称
remark?: string; // 备注
createTime?: number; // 发起时间
}
/** MES 安灯记录分页查询参数 */
export interface PageParams extends PageParam {
workstationId?: number; // 工作站编号
userId?: number; // 发起用户编号
handlerUserId?: number; // 处置人编号
status?: number; // 处置状态
createTime?: string[]; // 发起时间区间
}
}
/** 查询安灯记录分页 */
export function getAndonRecordPage(params: MesProAndonRecordApi.PageParams) {
return requestClient.get<PageResult<MesProAndonRecordApi.AndonRecord>>(
'/mes/pro/andon-record/page',
{ params },
);
}
/** 查询安灯记录详情 */
export function getAndonRecord(id: number) {
return requestClient.get<MesProAndonRecordApi.AndonRecord>(
`/mes/pro/andon-record/get?id=${id}`,
);
}
/** 新增安灯记录 */
export function createAndonRecord(data: MesProAndonRecordApi.AndonRecord) {
return requestClient.post('/mes/pro/andon-record/create', data);
}
/** 删除安灯记录 */
export function deleteAndonRecord(id: number) {
return requestClient.delete(`/mes/pro/andon-record/delete?id=${id}`);
}
/** 更新安灯记录(保存/已处置) */
export function updateAndonRecord(data: MesProAndonRecordApi.AndonRecord) {
return requestClient.put('/mes/pro/andon-record/update', data);
}
/** 导出安灯记录 Excel */
export function exportAndonRecord(
params: Partial<MesProAndonRecordApi.PageParams>,
) {
return requestClient.download('/mes/pro/andon-record/export-excel', {
params,
});
}

View File

@ -0,0 +1,79 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProCardApi {
/** MES 生产流转卡 */
export interface Card {
id?: number; // 编号
code?: string; // 流转卡编码
workOrderId?: number; // 生产工单编号
workOrderCode?: string; // 工单编码
workOrderName?: string; // 工单名称
batchCode?: string; // 批次号
itemId?: number; // 产品物料编号
itemCode?: string; // 产品编码
itemName?: string; // 产品名称
specification?: string; // 规格型号
unitMeasureName?: string; // 单位名称
transferedQuantity?: number; // 流转数量
status?: number; // 状态
remark?: string; // 备注
}
/** MES 生产流转卡分页查询参数 */
export interface PageParams extends PageParam {
code?: string;
workOrderId?: number;
itemId?: number;
batchCode?: string;
}
}
/** 查询生产流转卡分页 */
export function getCardPage(params: MesProCardApi.PageParams) {
return requestClient.get<PageResult<MesProCardApi.Card>>(
'/mes/pro/card/page',
{ params },
);
}
/** 查询生产流转卡详情 */
export function getCard(id: number) {
return requestClient.get<MesProCardApi.Card>(`/mes/pro/card/get?id=${id}`);
}
/** 新增生产流转卡 */
export function createCard(data: MesProCardApi.Card) {
return requestClient.post<number>('/mes/pro/card/create', data);
}
/** 修改生产流转卡 */
export function updateCard(data: MesProCardApi.Card) {
return requestClient.put('/mes/pro/card/update', data);
}
/** 删除生产流转卡 */
export function deleteCard(id: number) {
return requestClient.delete(`/mes/pro/card/delete?id=${id}`);
}
/** 导出生产流转卡 */
export function exportCard(params: any) {
return requestClient.download('/mes/pro/card/export-excel', { params });
}
/** 提交生产流转卡 */
export function submitCard(id: number) {
return requestClient.put(`/mes/pro/card/submit?id=${id}`);
}
/** 完成生产流转卡 */
export function finishCard(id: number) {
return requestClient.put(`/mes/pro/card/finish?id=${id}`);
}
/** 取消生产流转卡 */
export function cancelCard(id: number) {
return requestClient.put(`/mes/pro/card/cancel?id=${id}`);
}

View File

@ -0,0 +1,62 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProCardProcessApi {
/** MES 流转卡工序记录 */
export interface CardProcess {
id?: number; // 编号
cardId?: number; // 流转卡编号
sort?: number; // 序号
processId?: number; // 工序编号
processCode?: string; // 工序编码
processName?: string; // 工序名称
inputTime?: number; // 进入工序时间
outputTime?: number; // 出工序时间
inputQuantity?: number; // 投入数量
outputQuantity?: number; // 产出数量
unqualifiedQuantity?: number; // 不合格品数量
workstationId?: number; // 工位编号
workstationCode?: string; // 工位编码
workstationName?: string; // 工位名称
userId?: number; // 操作人编号
nickname?: string; // 操作人名称
ipqcId?: number; // 过程检验单编号
remark?: string; // 备注
}
/** MES 流转卡工序记录分页查询参数 */
export interface PageParams extends PageParam {
cardId?: number;
}
}
/** 查询流转卡工序记录分页 */
export function getCardProcessPage(params: MesProCardProcessApi.PageParams) {
return requestClient.get<PageResult<MesProCardProcessApi.CardProcess>>(
'/mes/pro/card-process/page',
{ params },
);
}
/** 查询流转卡工序记录详情 */
export function getCardProcess(id: number) {
return requestClient.get<MesProCardProcessApi.CardProcess>(
`/mes/pro/card-process/get?id=${id}`,
);
}
/** 新增流转卡工序记录 */
export function createCardProcess(data: MesProCardProcessApi.CardProcess) {
return requestClient.post('/mes/pro/card-process/create', data);
}
/** 修改流转卡工序记录 */
export function updateCardProcess(data: MesProCardProcessApi.CardProcess) {
return requestClient.put('/mes/pro/card-process/update', data);
}
/** 删除流转卡工序记录 */
export function deleteCardProcess(id: number) {
return requestClient.delete(`/mes/pro/card-process/delete?id=${id}`);
}

View File

@ -0,0 +1,113 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProFeedbackApi {
/** MES 生产报工 */
export interface Feedback {
id?: number;
code?: string; // 报工单编号
type?: number; // 报工类型
channel?: string; // 报工途径
feedbackTime?: number; // 报工时间
workstationId?: number; // 工作站编号
workstationCode?: string; // 工作站编码
workstationName?: string; // 工作站名称
routeId?: number; // 工艺路线编号
routeCode?: string; // 工艺路线编码
processId?: number; // 工序编号
processCode?: string; // 工序编码
processName?: string; // 工序名称
checkFlag?: boolean; // 是否需要检验
workOrderId?: number; // 生产工单编号
workOrderCode?: string; // 工单编码
workOrderName?: string; // 工单名称
taskId?: number; // 生产任务编号
taskCode?: string; // 任务编码
itemId?: number; // 产品物料编号
itemCode?: string; // 物料编码
itemName?: string; // 物料名称
itemSpecification?: string; // 规格型号
unitMeasureId?: number; // 单位编号
unitMeasureName?: string; // 单位名称
expireDate?: number; // 过期日期
scheduledQuantity?: number; // 排产数量
feedbackQuantity?: number; // 本次报工数量
qualifiedQuantity?: number; // 合格品数量
unqualifiedQuantity?: number; // 不良品数量
uncheckQuantity?: number; // 待检测数量
laborScrapQuantity?: number; // 工废数量
materialScrapQuantity?: number; // 料废数量
otherScrapQuantity?: number; // 其他废品数量
feedbackUserId?: number; // 报工用户编号
feedbackUserNickname?: string; // 报工人昵称
approveUserId?: number; // 审核用户编号
approveUserNickname?: string; // 审核人昵称
status?: number; // 状态
remark?: string; // 备注
creator?: string; // 创建人
createTime?: number; // 创建时间
}
/** MES 生产报工分页查询参数 */
export interface PageParams extends PageParam {
code?: string;
type?: number;
workOrderId?: number;
itemId?: number;
feedbackUserId?: number;
creator?: string;
status?: number;
feedbackTime?: string[];
}
}
/** 查询生产报工分页 */
export function getFeedbackPage(params: MesProFeedbackApi.PageParams) {
return requestClient.get<PageResult<MesProFeedbackApi.Feedback>>(
'/mes/pro/feedback/page',
{ params },
);
}
/** 查询生产报工详情 */
export function getFeedback(id: number) {
return requestClient.get<MesProFeedbackApi.Feedback>(
`/mes/pro/feedback/get?id=${id}`,
);
}
/** 新增生产报工 */
export function createFeedback(data: MesProFeedbackApi.Feedback) {
return requestClient.post<number>('/mes/pro/feedback/create', data);
}
/** 修改生产报工 */
export function updateFeedback(data: MesProFeedbackApi.Feedback) {
return requestClient.put('/mes/pro/feedback/update', data);
}
/** 删除生产报工 */
export function deleteFeedback(id: number) {
return requestClient.delete(`/mes/pro/feedback/delete?id=${id}`);
}
/** 导出生产报工 Excel */
export function exportFeedback(params: Partial<MesProFeedbackApi.PageParams>) {
return requestClient.download('/mes/pro/feedback/export-excel', { params });
}
/** 提交生产报工 */
export function submitFeedback(id: number) {
return requestClient.put(`/mes/pro/feedback/submit?id=${id}`);
}
/** 驳回生产报工 */
export function rejectFeedback(id: number) {
return requestClient.put(`/mes/pro/feedback/reject?id=${id}`);
}
/** 审批生产报工(返回是否已审批完成) */
export function approveFeedback(id: number) {
return requestClient.put<boolean>(`/mes/pro/feedback/approve?id=${id}`);
}

View File

@ -0,0 +1,49 @@
import { requestClient } from '#/api/request';
export namespace MesProProcessContentApi {
/** MES 生产工序内容(操作步骤) */
export interface ProcessContent {
id?: number;
processId?: number;
sort?: number;
content?: string;
device?: string;
material?: string;
docUrl?: string;
remark?: string;
createTime?: Date;
}
}
/** 按工序编号查询工序内容列表 */
export function getProcessContentListByProcessId(processId: number) {
return requestClient.get<MesProProcessContentApi.ProcessContent[]>(
`/mes/pro/process-content/list-by-process?processId=${processId}`,
);
}
/** 查询工序内容详情 */
export function getProcessContent(id: number) {
return requestClient.get<MesProProcessContentApi.ProcessContent>(
`/mes/pro/process-content/get?id=${id}`,
);
}
/** 新增工序内容 */
export function createProcessContent(
data: MesProProcessContentApi.ProcessContent,
) {
return requestClient.post('/mes/pro/process-content/create', data);
}
/** 修改工序内容 */
export function updateProcessContent(
data: MesProProcessContentApi.ProcessContent,
) {
return requestClient.put('/mes/pro/process-content/update', data);
}
/** 删除工序内容 */
export function deleteProcessContent(id: number) {
return requestClient.delete(`/mes/pro/process-content/delete?id=${id}`);
}

View File

@ -0,0 +1,58 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProProcessApi {
/** MES 生产工序 */
export interface Process {
id?: number;
code?: string;
name?: string;
attention?: string;
status?: number;
remark?: string;
createTime?: Date;
}
}
/** 查询生产工序分页 */
export function getProcessPage(params: PageParam) {
return requestClient.get<PageResult<MesProProcessApi.Process>>(
'/mes/pro/process/page',
{ params },
);
}
/** 查询生产工序精简列表 */
export function getProcessSimpleList() {
return requestClient.get<MesProProcessApi.Process[]>(
'/mes/pro/process/simple-list',
);
}
/** 查询生产工序详情 */
export function getProcess(id: number) {
return requestClient.get<MesProProcessApi.Process>(
`/mes/pro/process/get?id=${id}`,
);
}
/** 新增生产工序 */
export function createProcess(data: MesProProcessApi.Process) {
return requestClient.post('/mes/pro/process/create', data);
}
/** 修改生产工序 */
export function updateProcess(data: MesProProcessApi.Process) {
return requestClient.put('/mes/pro/process/update', data);
}
/** 删除生产工序 */
export function deleteProcess(id: number) {
return requestClient.delete(`/mes/pro/process/delete?id=${id}`);
}
/** 导出生产工序 Excel */
export function exportProcess(params: any) {
return requestClient.download('/mes/pro/process/export-excel', { params });
}

View File

@ -0,0 +1,63 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProRouteApi {
/** MES 工艺路线 */
export interface Route {
id?: number;
code?: string;
name?: string;
description?: string;
status?: number;
remark?: string;
createTime?: Date;
}
}
/** 查询工艺路线分页 */
export function getRoutePage(params: PageParam) {
return requestClient.get<PageResult<MesProRouteApi.Route>>(
'/mes/pro/route/page',
{ params },
);
}
/** 查询工艺路线精简列表 */
export function getRouteSimpleList() {
return requestClient.get<MesProRouteApi.Route[]>(
'/mes/pro/route/simple-list',
);
}
/** 查询工艺路线详情 */
export function getRoute(id: number) {
return requestClient.get<MesProRouteApi.Route>(`/mes/pro/route/get?id=${id}`);
}
/** 新增工艺路线 */
export function createRoute(data: MesProRouteApi.Route) {
return requestClient.post<number>('/mes/pro/route/create', data);
}
/** 修改工艺路线 */
export function updateRoute(data: MesProRouteApi.Route) {
return requestClient.put('/mes/pro/route/update', data);
}
/** 修改工艺路线状态 */
export function updateRouteStatus(id: number, status: number) {
return requestClient.put(
`/mes/pro/route/update-status?id=${id}&status=${status}`,
);
}
/** 删除工艺路线 */
export function deleteRoute(id: number) {
return requestClient.delete(`/mes/pro/route/delete?id=${id}`);
}
/** 导出工艺路线 Excel */
export function exportRoute(params: any) {
return requestClient.download('/mes/pro/route/export-excel', { params });
}

View File

@ -0,0 +1,70 @@
import { requestClient } from '#/api/request';
export namespace MesProRouteProcessApi {
/** MES 工艺路线工序 */
export interface RouteProcess {
id?: number;
routeId?: number;
processId?: number;
processCode?: string;
processName?: string;
sort?: number;
nextProcessId?: number;
nextProcessName?: string;
linkType?: number;
prepareTime?: number;
waitTime?: number;
colorCode?: string;
keyFlag?: boolean;
checkFlag?: boolean;
remark?: string;
createTime?: Date;
}
}
/** 按工艺路线查询工序列表 */
export function getRouteProcessListByRoute(routeId: number) {
return requestClient.get<MesProRouteProcessApi.RouteProcess[]>(
`/mes/pro/route-process/list-by-route?routeId=${routeId}`,
);
}
/** 按产品查询工序列表(自动查找关联的工艺路线) */
export function getRouteProcessListByProduct(productId: number) {
return requestClient.get<MesProRouteProcessApi.RouteProcess[]>(
`/mes/pro/route-process/list-by-product?productId=${productId}`,
);
}
/** 查询工艺路线工序详情 */
export function getRouteProcess(id: number) {
return requestClient.get<MesProRouteProcessApi.RouteProcess>(
`/mes/pro/route-process/get?id=${id}`,
);
}
/** 按工艺路线 + 工序精确查询工序配置 */
export function getRouteProcessByRouteAndProcess(
routeId: number,
processId: number,
) {
return requestClient.get<MesProRouteProcessApi.RouteProcess>(
'/mes/pro/route-process/get-by-route-and-process',
{ params: { processId, routeId } },
);
}
/** 新增工艺路线工序 */
export function createRouteProcess(data: MesProRouteProcessApi.RouteProcess) {
return requestClient.post('/mes/pro/route-process/create', data);
}
/** 修改工艺路线工序 */
export function updateRouteProcess(data: MesProRouteProcessApi.RouteProcess) {
return requestClient.put('/mes/pro/route-process/update', data);
}
/** 删除工艺路线工序 */
export function deleteRouteProcess(id: number) {
return requestClient.delete(`/mes/pro/route-process/delete?id=${id}`);
}

View File

@ -0,0 +1,48 @@
import { requestClient } from '#/api/request';
export namespace MesProRouteProductApi {
/** MES 工艺路线产品 */
export interface RouteProduct {
id?: number;
routeId?: number;
itemId?: number;
itemCode?: string;
itemName?: string;
specification?: string;
unitName?: string;
quantity?: number;
productionTime?: number;
timeUnitType?: string;
remark?: string;
createTime?: Date;
}
}
/** 按工艺路线查询产品列表 */
export function getRouteProductListByRoute(routeId: number) {
return requestClient.get<MesProRouteProductApi.RouteProduct[]>(
`/mes/pro/route-product/list-by-route?routeId=${routeId}`,
);
}
/** 查询工艺路线产品详情 */
export function getRouteProduct(id: number) {
return requestClient.get<MesProRouteProductApi.RouteProduct>(
`/mes/pro/route-product/get?id=${id}`,
);
}
/** 新增工艺路线产品 */
export function createRouteProduct(data: MesProRouteProductApi.RouteProduct) {
return requestClient.post<number>('/mes/pro/route-product/create', data);
}
/** 修改工艺路线产品 */
export function updateRouteProduct(data: MesProRouteProductApi.RouteProduct) {
return requestClient.put('/mes/pro/route-product/update', data);
}
/** 删除工艺路线产品 */
export function deleteRouteProduct(id: number) {
return requestClient.delete(`/mes/pro/route-product/delete?id=${id}`);
}

View File

@ -0,0 +1,57 @@
import { requestClient } from '#/api/request';
export namespace MesProRouteProductBomApi {
/** MES 工艺路线产品 BOM */
export interface RouteProductBom {
id?: number;
routeId?: number;
processId?: number;
productId?: number;
itemId?: number;
itemCode?: string;
itemName?: string;
specification?: string;
unitName?: string;
quantity?: number;
remark?: string;
createTime?: Date;
}
}
/** 查询工艺路线产品 BOM 列表 */
export function getRouteProductBomList(params: {
processId?: number;
productId?: number;
routeId: number;
}) {
return requestClient.get<MesProRouteProductBomApi.RouteProductBom[]>(
'/mes/pro/route-product-bom/list',
{ params },
);
}
/** 查询工艺路线产品 BOM 详情 */
export function getRouteProductBom(id: number) {
return requestClient.get<MesProRouteProductBomApi.RouteProductBom>(
`/mes/pro/route-product-bom/get?id=${id}`,
);
}
/** 新增工艺路线产品 BOM */
export function createRouteProductBom(
data: MesProRouteProductBomApi.RouteProductBom,
) {
return requestClient.post('/mes/pro/route-product-bom/create', data);
}
/** 修改工艺路线产品 BOM */
export function updateRouteProductBom(
data: MesProRouteProductBomApi.RouteProductBom,
) {
return requestClient.put('/mes/pro/route-product-bom/update', data);
}
/** 删除工艺路线产品 BOM */
export function deleteRouteProductBom(id: number) {
return requestClient.delete(`/mes/pro/route-product-bom/delete?id=${id}`);
}

View File

@ -0,0 +1,95 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProTaskApi {
/** MES 生产任务 */
export interface Task {
id?: number;
code?: string; // 任务编码
name?: string; // 任务名称
workOrderId?: number; // 生产工单编号
workOrderCode?: string; // 工单编码
workOrderName?: string; // 工单名称
workstationId?: number; // 工作站编号
workstationCode?: string; // 工作站编码
workstationName?: string; // 工作站名称
routeId?: number; // 工艺路线编号
processId?: number; // 工序编号
processName?: string; // 工序名称
itemId?: number; // 产品物料编号
itemCode?: string; // 产品编码
itemName?: string; // 产品名称
itemSpecification?: string; // 规格型号
unitMeasureId?: number; // 单位编号
unitMeasureName?: string; // 单位名称
quantity?: number; // 排产数量
producedQuantity?: number; // 已生产数量
qualifyQuantity?: number; // 合格品数量
unqualifyQuantity?: number; // 不良品数量
changedQuantity?: number; // 调整数量
clientId?: number; // 客户编号
clientName?: string; // 客户名称
startTime?: number; // 开始生产时间
endTime?: number; // 结束生产时间
duration?: number; // 生产时长工作日1=8小时
requestDate?: number; // 需求日期(从工单查)
finishDate?: number; // 完成日期
cancelDate?: number; // 取消日期
colorCode?: string; // 甘特图显示颜色
status?: number; // 任务状态
checkFlag?: boolean; // 是否质检(派生自工艺路线工序)
remark?: string; // 备注
}
/** MES 生产任务分页查询参数 */
export interface PageParams extends PageParam {
code?: string;
name?: string;
workOrderId?: number;
workstationId?: number;
routeId?: number;
processId?: number;
itemId?: number;
statuses?: number[];
status?: number;
}
}
/** 查询生产任务分页 */
export function getTaskPage(params: MesProTaskApi.PageParams) {
return requestClient.get<PageResult<MesProTaskApi.Task>>(
'/mes/pro/task/page',
{ params },
);
}
/** 查询生产任务详情 */
export function getTask(id: number) {
return requestClient.get<MesProTaskApi.Task>(`/mes/pro/task/get?id=${id}`);
}
/** 新增生产任务 */
export function createTask(data: MesProTaskApi.Task) {
return requestClient.post('/mes/pro/task/create', data);
}
/** 修改生产任务 */
export function updateTask(data: MesProTaskApi.Task) {
return requestClient.put('/mes/pro/task/update', data);
}
/** 删除生产任务 */
export function deleteTask(id: number) {
return requestClient.delete(`/mes/pro/task/delete?id=${id}`);
}
/** 导出生产任务 */
export function exportTask(params: any) {
return requestClient.download('/mes/pro/task/export-excel', { params });
}
/** 查询甘特图任务列表(非分页) */
export function getGanttTaskList(params: any) {
return requestClient.get<any[]>('/mes/pro/task/gantt-list', { params });
}

View File

@ -0,0 +1,73 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProTaskIssueApi {
/** MES 生产任务投料 */
export interface TaskIssue {
id?: number; // 编号
taskId?: number; // 生产任务编号
workOrderId?: number; // 生产工单编号
workstationId?: number; // 工作站编号
sourceDocType?: string; // 来源单据类型
sourceDocId?: number; // 来源单据编号
sourceLineId?: number; // 来源单据行编号
sourceDocCode?: string; // 来源单据编码
batchCode?: string; // 投料批次
itemId?: number; // 产品物料编号
itemName?: string; // 产品名称
itemCode?: string; // 产品编码
itemSpecification?: string; // 规格型号
unitMeasureId?: number; // 单位编号
unitMeasureName?: string; // 单位名称
issuedQuantity?: number; // 总投料数量
availableQuantity?: number; // 当前可用数量
usedQuantity?: number; // 当前使用数量
remark?: string; // 备注
}
/** MES 生产任务投料分页查询参数 */
export interface PageParams extends PageParam {
taskId?: number; // 生产任务编号
workOrderId?: number; // 生产工单编号
workstationId?: number; // 工作站编号
itemId?: number; // 产品物料编号
}
}
/** 查询生产任务投料分页 */
export function getTaskIssuePage(params: MesProTaskIssueApi.PageParams) {
return requestClient.get<PageResult<MesProTaskIssueApi.TaskIssue>>(
'/mes/pro/task-issue/page',
{ params },
);
}
/** 查询生产任务投料详情 */
export function getTaskIssue(id: number) {
return requestClient.get<MesProTaskIssueApi.TaskIssue>(
`/mes/pro/task-issue/get?id=${id}`,
);
}
/** 新增生产任务投料 */
export function createTaskIssue(data: MesProTaskIssueApi.TaskIssue) {
return requestClient.post('/mes/pro/task-issue/create', data);
}
/** 修改生产任务投料 */
export function updateTaskIssue(data: MesProTaskIssueApi.TaskIssue) {
return requestClient.put('/mes/pro/task-issue/update', data);
}
/** 删除生产任务投料 */
export function deleteTaskIssue(id: number) {
return requestClient.delete(`/mes/pro/task-issue/delete?id=${id}`);
}
/** 按生产任务查询投料列表 */
export function getTaskIssueListByTask(taskId: number) {
return requestClient.get<MesProTaskIssueApi.TaskIssue[]>(
`/mes/pro/task-issue/list-by-task?taskId=${taskId}`,
);
}

View File

@ -0,0 +1,62 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProWorkOrderBomApi {
/** MES 生产工单 BOM */
export interface WorkOrderBom {
id?: number; // 编号
workOrderId?: number; // 生产工单编号
itemId?: number; // BOM 物料编号
itemName?: string; // 物料名称
itemCode?: string; // 物料编码
itemSpecification?: string; // 规格型号
unitMeasureId?: number; // 单位编号
unitMeasureName?: string; // 单位名称
quantity?: number; // 预计使用量
remark?: string; // 备注
itemOrProduct?: string; // 物料产品标识
}
/** MES 生产工单 BOM 分页查询参数 */
export interface PageParams extends PageParam {
workOrderId?: number;
}
}
/** 查询工单 BOM 分页 */
export function getWorkOrderBomPage(params: MesProWorkOrderBomApi.PageParams) {
return requestClient.get<PageResult<MesProWorkOrderBomApi.WorkOrderBom>>(
'/mes/pro/work-order-bom/page',
{ params },
);
}
/** 查询工单 BOM 详情 */
export function getWorkOrderBom(id: number) {
return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom>(
`/mes/pro/work-order-bom/get?id=${id}`,
);
}
/** 新增工单 BOM */
export function createWorkOrderBom(data: MesProWorkOrderBomApi.WorkOrderBom) {
return requestClient.post('/mes/pro/work-order-bom/create', data);
}
/** 修改工单 BOM */
export function updateWorkOrderBom(data: MesProWorkOrderBomApi.WorkOrderBom) {
return requestClient.put('/mes/pro/work-order-bom/update', data);
}
/** 删除工单 BOM */
export function deleteWorkOrderBom(id: number) {
return requestClient.delete(`/mes/pro/work-order-bom/delete?id=${id}`);
}
/** 查询工单物料需求列表 */
export function getWorkOrderBomItemListByWorkOrderId(workOrderId: number) {
return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom[]>(
`/mes/pro/work-order-bom/item-list-by-work-order-id?workOrderId=${workOrderId}`,
);
}

View File

@ -0,0 +1,101 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProWorkOrderApi {
/** MES 生产工单 */
export interface WorkOrder {
id?: number; // 编号
code?: string; // 工单编码
name?: string; // 工单名称
type?: number; // 工单类型
orderSourceType?: number; // 来源类型
orderSourceCode?: string; // 来源单据编号
productId?: number; // 产品编号
productName?: string; // 产品名称
productCode?: string; // 产品编码
productSpecification?: string; // 规格型号
unitMeasureName?: string; // 单位名称
quantity?: number; // 生产数量
quantityProduced?: number; // 已生产数量
quantityChanged?: number; // 调整数量
quantityScheduled?: number; // 已排产数量
clientId?: number; // 客户编号
clientCode?: string; // 客户编码
clientName?: string; // 客户名称
vendorId?: number; // 供应商编号
vendorName?: string; // 供应商名称
vendorCode?: string; // 供应商编码
batchCode?: string; // 批次号
requestDate?: number; // 需求日期
parentId?: number; // 父工单编号
parentCode?: string; // 父工单编码
finishDate?: number; // 完成时间
cancelDate?: number; // 取消时间
status?: number; // 工单状态
remark?: string; // 备注
createTime?: number; // 创建时间
}
/** MES 生产工单分页查询参数 */
export interface PageParams extends PageParam {
code?: string;
name?: string;
orderSourceCode?: string;
productId?: number;
clientId?: number;
status?: number;
type?: number;
requestDate?: number[];
}
}
/** 查询生产工单分页 */
export function getWorkOrderPage(params: MesProWorkOrderApi.PageParams) {
return requestClient.get<PageResult<MesProWorkOrderApi.WorkOrder>>(
'/mes/pro/work-order/page',
{ params },
);
}
/** 查询生产工单详情 */
export function getWorkOrder(id: number) {
return requestClient.get<MesProWorkOrderApi.WorkOrder>(
`/mes/pro/work-order/get?id=${id}`,
);
}
/** 新增生产工单 */
export function createWorkOrder(data: MesProWorkOrderApi.WorkOrder) {
return requestClient.post<number>('/mes/pro/work-order/create', data);
}
/** 修改生产工单 */
export function updateWorkOrder(data: MesProWorkOrderApi.WorkOrder) {
return requestClient.put('/mes/pro/work-order/update', data);
}
/** 删除生产工单 */
export function deleteWorkOrder(id: number) {
return requestClient.delete(`/mes/pro/work-order/delete?id=${id}`);
}
/** 导出生产工单 */
export function exportWorkOrder(params: any) {
return requestClient.download('/mes/pro/work-order/export-excel', { params });
}
/** 完成工单 */
export function finishWorkOrder(id: number) {
return requestClient.put(`/mes/pro/work-order/finish?id=${id}`);
}
/** 取消工单 */
export function cancelWorkOrder(id: number) {
return requestClient.put(`/mes/pro/work-order/cancel?id=${id}`);
}
/** 确认工单 */
export function confirmWorkOrder(id: number) {
return requestClient.put(`/mes/pro/work-order/confirm?id=${id}`);
}

View File

@ -0,0 +1,71 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesProWorkRecordApi {
/** MES 工作记录流水 */
export interface WorkRecordLog {
id?: number; // 编号
userId?: number; // 用户编号
userNickname?: string; // 用户昵称
workstationId?: number; // 工作站编号
workstationCode?: string; // 工作站编码
workstationName?: string; // 工作站名称
type?: number; // 1=上工 2=下工
remark?: string; // 备注
createTime?: Date; // 创建时间
}
/** MES 当前用户工作站绑定状态 */
export interface MyWorkRecord {
userId?: number; // 用户编号
userNickname?: string; // 用户昵称
workstationId?: number; // 工作站编号
workstationCode?: string; // 工作站编码
workstationName?: string; // 工作站名称
type?: number; // 1=上工 2=下工
clockInTime?: Date; // 上工时间
clockOutTime?: Date; // 下工时间
}
}
/** 查询工作记录分页 */
export function getWorkRecordLogPage(params: PageParam) {
return requestClient.get<PageResult<MesProWorkRecordApi.WorkRecordLog>>(
'/mes/pro/workrecord/log/page',
{ params },
);
}
/** 查询工作记录详情 */
export function getWorkRecordLog(id: number) {
return requestClient.get<MesProWorkRecordApi.WorkRecordLog>(
`/mes/pro/workrecord/log/get?id=${id}`,
);
}
/** 导出工作记录 */
export function exportWorkRecordLog(params: any) {
return requestClient.download('/mes/pro/workrecord/log/export-excel', {
params,
});
}
/** 上工(绑定工作站) */
export function clockInWorkRecord(workstationId: number) {
return requestClient.put('/mes/pro/workrecord/clock-in', null, {
params: { workstationId },
});
}
/** 下工(解绑工作站) */
export function clockOutWorkRecord() {
return requestClient.put('/mes/pro/workrecord/clock-out');
}
/** 查询当前用户绑定的工作站 */
export function getMyWorkRecord() {
return requestClient.get<MesProWorkRecordApi.MyWorkRecord>(
'/mes/pro/workrecord/get-my',
);
}

View File

@ -0,0 +1,58 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesQcDefectApi {
/** MES 缺陷类型 */
export interface Defect {
id?: number; // 编号
code?: string; // 缺陷编码
name?: string; // 缺陷描述
type?: number; // 检测项类型
level?: number; // 缺陷等级
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询缺陷类型分页 */
export function getDefectPage(params: PageParam) {
return requestClient.get<PageResult<MesQcDefectApi.Defect>>(
'/mes/qc/defect/page',
{ params },
);
}
/** 查询缺陷类型精简列表 */
export function getDefectSimpleList() {
return requestClient.get<MesQcDefectApi.Defect[]>(
'/mes/qc/defect/simple-list',
);
}
/** 查询缺陷类型详情 */
export function getDefect(id: number) {
return requestClient.get<MesQcDefectApi.Defect>(
`/mes/qc/defect/get?id=${id}`,
);
}
/** 新增缺陷类型 */
export function createDefect(data: MesQcDefectApi.Defect) {
return requestClient.post('/mes/qc/defect/create', data);
}
/** 修改缺陷类型 */
export function updateDefect(data: MesQcDefectApi.Defect) {
return requestClient.put('/mes/qc/defect/update', data);
}
/** 删除缺陷类型 */
export function deleteDefect(id: number) {
return requestClient.delete(`/mes/qc/defect/delete?id=${id}`);
}
/** 导出缺陷类型 */
export function exportDefect(params: any) {
return requestClient.download('/mes/qc/defect/export-excel', { params });
}

View File

@ -0,0 +1,49 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesQcDefectRecordApi {
/** MES 质检缺陷记录 */
export interface DefectRecord {
id?: number; // 编号
qcType?: number; // 检验类型
qcId?: number; // 检验单 ID
lineId?: number; // 检验行 ID
name?: string; // 缺陷描述
level?: number; // 缺陷等级
quantity?: number; // 缺陷数量
remark?: string; // 备注
}
}
/** 查询质检缺陷记录 */
export function getDefectRecord(id: number) {
return requestClient.get<MesQcDefectRecordApi.DefectRecord>(
`/mes/qc/defect-record/get?id=${id}`,
);
}
/** 查询质检缺陷记录分页 */
export function getDefectRecordPage(
params: PageParam & { lineId?: number; qcId?: number; qcType?: number },
) {
return requestClient.get<PageResult<MesQcDefectRecordApi.DefectRecord>>(
'/mes/qc/defect-record/page',
{ params },
);
}
/** 新增质检缺陷记录 */
export function createDefectRecord(data: MesQcDefectRecordApi.DefectRecord) {
return requestClient.post('/mes/qc/defect-record/create', data);
}
/** 修改质检缺陷记录 */
export function updateDefectRecord(data: MesQcDefectRecordApi.DefectRecord) {
return requestClient.put('/mes/qc/defect-record/update', data);
}
/** 删除质检缺陷记录 */
export function deleteDefectRecord(id: number) {
return requestClient.delete(`/mes/qc/defect-record/delete?id=${id}`);
}

View File

@ -0,0 +1,53 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace MesQcIndicatorApi {
/** MES 质检指标 */
export interface Indicator {
id?: number; // 编号
code?: string; // 检测项编码
name?: string; // 检测项名称
type?: number; // 检测项类型
tool?: string; // 检测工具
resultType?: number; // 结果值类型
resultSpecification?: string; // 结果值属性
remark?: string; // 备注
createTime?: Date; // 创建时间
}
}
/** 查询质检指标分页 */
export function getIndicatorPage(params: PageParam) {
return requestClient.get<PageResult<MesQcIndicatorApi.Indicator>>(
'/mes/qc/indicator/page',
{ params },
);
}
/** 查询质检指标详情 */
export function getIndicator(id: number) {
return requestClient.get<MesQcIndicatorApi.Indicator>(
`/mes/qc/indicator/get?id=${id}`,
);
}
/** 新增质检指标 */
export function createIndicator(data: MesQcIndicatorApi.Indicator) {
return requestClient.post('/mes/qc/indicator/create', data);
}
/** 修改质检指标 */
export function updateIndicator(data: MesQcIndicatorApi.Indicator) {
return requestClient.put('/mes/qc/indicator/update', data);
}
/** 删除质检指标 */
export function deleteIndicator(id: number) {
return requestClient.delete(`/mes/qc/indicator/delete?id=${id}`);
}
/** 导出质检指标 */
export function exportIndicator(params: any) {
return requestClient.download('/mes/qc/indicator/export-excel', { params });
}

Some files were not shown because too many files have changed in this diff Show More