全局列宽均分+批量按钮统一到上方+修改预处理协议增加执行验证阶段

- 02-前端全局规范.md: 新增el-table列宽均分规则和操作按钮统一布局规则
- 8个页面设计文档: 列表字段列宽改为自动均分,批量操作按钮从底部栏改为页头
- 05-修改请求预处理协议.md: 新增第四步执行中验证和第五步完成验收,配2个完整示例
- 8个Vue组件: 移除数据列固定width,批量操作按钮移到操作栏
main
haoliang 1 week ago
parent 8d24cb54c7
commit c5847b1f71

@ -31,6 +31,22 @@
| el-tag | 状态标签 | size=small, 按状态配color |
| el-tooltip | 提示 | placement=top |
### el-table 列宽均分规则
- **禁止使用固定 `width`**:所有 `el-table-column` 不设置 `width` 属性,由浏览器自动按内容均分剩余空间
- **操作列例外**:最右侧操作列(如"操作"列)可设置固定 `width`如180px其余列不设置
- **需要最小宽度的列**:使用 `min-width` 替代 `width`(如长文本列 `min-width=150`
- **排序/索引列例外**:序号列可设 `width=60`,选择框列可设 `width=50`
- **目标效果**:除操作列/序号列/选择框列外的所有数据列自动撑满表格宽度,无空白区域
### 操作按钮统一布局规则
- **所有操作按钮统一放在列表上方**:增删改查、批量操作、导出等按钮均在搜索栏下方、表格上方的一排区域内
- **按钮排列顺序**(从左到右):主操作(新增)→ 批量操作(批量删除/批量标记等)→ 其他操作(导出等)
- **禁止使用下方浮出条**:不再使用表格底部浮出条(`position: sticky`)放置批量操作按钮
- **批量操作按钮的显示条件**:选中行数>0时才显示按钮文本含数量如"批量删除(3)"
- **行内操作列**:每行右侧的操作列(编辑/删除/查看等)保留在表格最后一列不变
### 防重复请求
- 所有写操作按钮点击后立即loading=true+disabled=true

@ -19,7 +19,7 @@
┌──────────────────────────────────────────────────────────┐
│ [面包屑] 首页 / 设备管理 │
├──────────────────────────────────────────────────────────┤
│ [操作栏] [+ 新增机床] [导入] [导出]
│ [操作栏] [+ 新增机床] [导入] [导出] [批量停用(N)] [批量启用(N)]
├──────────────────────────────────────────────────────────┤
│ [查询条件区] │
│ 车间[▼全部] 在线状态[▼全部] 品牌[▼全部] 搜索[____] │
@ -30,8 +30,6 @@
│ [x] | 西-1.8 | fanake_1.8 | A栋 | FANUC| 10.1.1.8| 在线 | 张三 | [编辑][删除] │
├──────────────────────────────────────────────────────────┤
│ [分页] 共160条 每页[20▼] < 1 2 3 ... 8 >
├──────────────────────────────────────────────────────────┤
│ [批量操作栏] 已选2项 [批量停用] [批量启用] │
└──────────────────────────────────────────────────────────┘
### 3. 查询条件
@ -47,15 +45,17 @@
| 字段名 | 列宽 | 排序 | 筛选 | 固定 | 超长处理 | 对齐 |
|--------|------|------|------|------|---------|------|
| 选择框 | 40px | - | - | left | - | center |
| 机床名称 | 120px | y | - | left | tooltip | left |
| device_code | 140px | y | - | - | tooltip | left |
| 车间 | 80px | y | 下拉 | - | - | center |
| 品牌 | 100px | y | 下拉 | - | - | center |
| IP地址 | 120px | - | - | - | - | left |
| 在线状态 | 80px | - | - | - | - | center |
| 绑定工人 | 100px | - | - | - | - | center |
| 操作 | 120px | - | - | right | - | center |
| 选择框 | 50 | - | - | left | - | center |
| 机床名称 | - | y | - | left | tooltip | left |
| device_code | - | y | - | - | tooltip | left |
| 车间 | - | y | 下拉 | - | - | center |
| 品牌 | - | y | 下拉 | - | - | center |
| IP地址 | - | - | - | - | - | left |
| 在线状态 | - | - | - | - | - | center |
| 绑定工人 | - | - | - | - | - | center |
| 操作 | 180 | - | - | right | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则选择框固定50数据列不设width自动均分操作列固定180。
### 5. 操作按钮
@ -66,8 +66,8 @@
| 导出 | machine:export | 页头 | 始终 | 调API下载Excel |
| 编辑 | machine:update | 行操作 | 始终 | 打开编辑弹窗 |
| 删除 | machine:delete | 行操作 | 始终 | 确认->软删除 |
| 批量停用 | machine:disable | 底部栏 | 已选含启用项 | 确认->批量 |
| 批量启用 | machine:enable | 底部栏 | 已选含停用项 | 确认->批量 |
| 批量停用 | machine:disable | 页头 | 已选含启用项 | 确认->批量 |
| 批量启用 | machine:enable | 页头 | 已选含停用项 | 确认->批量 |
| 机床名称链接 | - | 行内 | 始终 | 跳转详情页 |
### 6. 弹窗规格

@ -36,10 +36,12 @@
| 字段名 | 列宽 | 排序 | 超长处理 | 对齐 |
|--------|------|------|---------|------|
| 品牌名称 | 150px | y | tooltip | left |
| 状态 | 80px | - | - | center |
| 映射字段数 | 100px | - | - | center |
| 操作 | 180px | - | - | center |
| 品牌名称 | - | y | tooltip | left |
| 状态 | - | - | - | center |
| 映射字段数 | - | - | - | center |
| 操作 | 180 | - | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分操作列固定180。
### 5. 操作按钮

@ -35,14 +35,16 @@
| 字段名 | 列宽 | 排序 | 超长处理 | 对齐 |
|--------|------|------|---------|------|
| 名称 | 120px | y | tooltip | left |
| URL | 250px | - | tooltip | left |
| 品牌 | 100px | - | - | center |
| 采集间隔 | 80px | - | - | center |
| 状态 | 80px | - | - | center |
| 上次采集 | 120px | - | - | center |
| 连续失败 | 80px | - | - | center |
| 操作 | 120px | - | - | center |
| 名称 | - | y | tooltip | left |
| URL | min-width=200 | - | tooltip | left |
| 品牌 | - | - | - | center |
| 采集间隔 | - | - | - | center |
| 状态 | - | - | - | center |
| 上次采集 | - | - | - | center |
| 连续失败 | - | - | - | center |
| 操作 | 120 | - | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分URL列设min-width=200保证可读性操作列固定120。
### 5. 操作按钮

@ -48,13 +48,15 @@
| 字段名 | 列宽 | 排序 | 筛选 | 固定 | 超长处理 | 对齐 |
|--------|------|------|------|------|---------|------|
| 选择框 | 40px | - | - | left | - | center |
| 工号 | 120px | y | - | - | tooltip | left |
| 姓名 | 120px | y | - | - | tooltip | left |
| 状态 | 80px | - | - | - | - | center |
| 绑定机床数 | 100px | y | - | - | - | center |
| 绑定机床 | auto | - | - | - | tooltip(逗号分隔) | left |
| 操作 | 120px | - | - | right | - | center |
| 选择框 | 50 | - | - | left | - | center |
| 工号 | - | y | - | - | tooltip | left |
| 姓名 | - | y | - | - | tooltip | left |
| 状态 | - | - | - | - | - | center |
| 绑定机床数 | - | y | - | - | - | center |
| 绑定机床 | - | - | - | - | tooltip(逗号分隔) | left |
| 操作 | 120 | - | - | right | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则选择框固定50数据列不设width自动均分操作列固定120。
### 5. 操作按钮
@ -63,8 +65,8 @@
| 新增工人 | worker:create | 页头 | 始终 | 打开新增弹窗 |
| 编辑 | worker:update | 行操作 | 始终 | 打开编辑弹窗 |
| 删除 | worker:delete | 行操作 | 启用状态且无绑定机床 | 确认->软删除 |
| 批量停用 | worker:disable | 底部栏 | 已选含启用项 | 确认->批量 |
| 批量启用 | worker:enable | 底部栏 | 已选含停用项 | 确认->批量 |
| 批量停用 | worker:disable | 页头 | 已选含启用项 | 确认->批量 |
| 批量启用 | worker:enable | 页头 | 已选含停用项 | 确认->批量 |
| 姓名链接 | - | 行内 | 始终 | 跳转工人详情页(/worker/:id) |
### 6. 弹窗规格

@ -55,15 +55,17 @@
| 字段名 | 列宽 | 排序 | 筛选 | 固定 | 超长处理 | 对齐 |
|--------|------|------|------|------|---------|------|
| 日期 | 110px | y | - | left | - | center |
| 机床名称 | 120px | y | - | - | tooltip | left |
| 程序名 | 140px | y | - | - | tooltip | left |
| 产量 | 80px | y | - | - | - | center |
| 运行时间 | 100px | - | - | - | - | center |
| 切削时间 | 100px | - | - | - | - | center |
| 日状态 | 80px | - | 下拉 | - | - | center |
| 修正标记 | 80px | - | - | - | - | center |
| 操作 | 120px | - | - | right | - | center |
| 日期 | - | y | - | left | - | center |
| 机床名称 | - | y | - | - | tooltip | left |
| 程序名 | - | y | - | - | tooltip | left |
| 产量 | - | y | - | - | - | center |
| 运行时间 | - | - | - | - | - | center |
| 切削时间 | - | - | - | - | - | center |
| 日状态 | - | - | 下拉 | - | - | center |
| 修正标记 | - | - | - | - | - | center |
| 操作 | 120 | - | - | right | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分操作列固定120。
### 5. 操作按钮

@ -56,14 +56,16 @@
| 字段名 | 列宽 | 排序 | 筛选 | 固定 | 超长处理 | 对齐 |
|--------|------|------|------|------|---------|------|
| 选择框 | 40px | - | - | left | - | center |
| 告警时间 | 170px | y | - | - | - | center |
| 告警类型 | 100px | - | - | - | - | center |
| 标题 | 160px | - | - | - | tooltip | left |
| 机床 | 100px | - | - | - | tooltip | center |
| 详情 | auto | - | - | - | tooltip | left |
| 处理状态 | 80px | - | - | - | - | center |
| 操作 | 120px | - | - | right | - | center |
| 选择框 | 50 | - | - | left | - | center |
| 告警时间 | - | y | - | - | - | center |
| 告警类型 | - | - | - | - | - | center |
| 标题 | - | - | - | - | tooltip | left |
| 机床 | - | - | - | - | tooltip | center |
| 详情 | - | - | - | - | tooltip | left |
| 处理状态 | - | - | - | - | - | center |
| 操作 | 120 | - | - | right | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则选择框固定50数据列不设width自动均分操作列固定120。
### 5. 操作按钮

@ -68,11 +68,13 @@
| 字段名 | 列宽 | 排序 | 超长处理 | 对齐 |
|--------|------|------|---------|------|
| 配置项(config_key) | 200px | - | tooltip | left |
| 配置值(config_value) | auto | - | tooltip | left |
| 值类型(value_type) | 80px | - | - | center |
| 说明(description) | 200px | - | tooltip | left |
| 操作 | 160px | - | - | center |
| 配置项(config_key) | - | - | tooltip | left |
| 配置值(config_value) | - | - | tooltip | left |
| 值类型(value_type) | - | - | - | center |
| 说明(description) | - | - | tooltip | left |
| 操作 | 160 | - | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分操作列固定160。
#### 操作按钮
@ -100,10 +102,12 @@
| 字段名 | 列宽 | 排序 | 超长处理 | 对齐 |
|--------|------|------|---------|------|
| 车间名称 | 200px | - | tooltip | left |
| 排序 | 80px | y | - | center |
| 状态 | 80px | - | - | center |
| 操作 | 160px | - | - | center |
| 车间名称 | - | - | tooltip | left |
| 排序 | - | y | - | center |
| 状态 | - | - | - | center |
| 操作 | 160 | - | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分操作列固定160。
#### 操作按钮

@ -66,13 +66,15 @@
| 字段名 | 列宽 | 排序 | 超长处理 | 对齐 |
|--------|------|------|---------|------|
| 修正时间 | 170px | y(默认倒序) | - | center |
| 目标表 | 150px | - | tooltip | left |
| 目标ID | 80px | - | - | center |
| 修正前 | 80px | - | - | center |
| 修正后 | 80px | - | - | center |
| 修正原因 | auto | - | tooltip | left |
| 操作IP | 130px | - | - | center |
| 修正时间 | - | y(默认倒序) | - | center |
| 目标表 | - | - | tooltip | left |
| 目标ID | - | - | - | center |
| 修正前 | - | - | - | center |
| 修正后 | - | - | - | center |
| 修正原因 | - | - | tooltip | left |
| 操作IP | - | - | - | center |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分。
### 4. Tab2-系统运行日志
@ -89,10 +91,12 @@
| 字段名 | 列宽 | 排序 | 超长处理 | 对齐 |
|--------|------|------|---------|------|
| 时间 | 170px | y(默认倒序) | - | center |
| 级别 | 80px | - | - | center |
| 来源 | 130px | - | tooltip | left |
| 消息 | auto | - | tooltip+点击展开详情 | left |
| 时间 | - | y(默认倒序) | - | center |
| 级别 | - | - | - | center |
| 来源 | - | - | tooltip | left |
| 消息 | - | - | tooltip+点击展开详情 | left |
> 列宽规则见 `02-前端全局规范.md` el-table列宽均分规则数据列不设width自动均分。
### 5. 操作按钮

@ -40,6 +40,79 @@
预估步骤:[1-N步]
```
## 第四步:执行中验证(边改边验)
每完成一个文件的修改,立即执行对应的自检动作,不等全部改完再回头检查。
### 自检规则
| 时机 | 验证动作 | 适用范围 |
|------|---------|---------|
| 改完设计文档后 | 读关联文档检查联动字段是否同步如页面§9数据结构↔API端点↔Mock | F/A/D类修改 |
| 改完代码文件后 | `lsp_diagnostics` 检查该文件确认无error | 所有代码修改 |
| 改完Vue组件后 | 对照对应页面设计文档的字段表逐列核对 | F类修改 |
| 改完C#代码后 | 对照对应后端规范的命名/分层/测试要求 | B类修改 |
| 所有文件改完后 | `npm run build`(前端)或 `dotnet build`(后端)确认编译通过 | 代码修改 |
### 禁止行为
- 禁止跳过自检直接标记任务完成
- 禁止一次性改完全部文件后再统一验证(错误会累积)
- 禁止用 `as any`、`@ts-ignore` 压制诊断错误来通过验证
## 第五步:完成验收(改完后总验)
所有文件修改完成且执行中验证通过后,执行总验收。
### 验收清单
**第1项变更清单核对**
列出所有已修改的文件,逐文件确认:
- 改动内容与第三步的修改计划摘要一致
- 无遗漏文件(对照计划中的涉及文件清单逐个勾选)
- 无多余改动(未在计划中的文件未被修改)
**第2项定向验证按影响面类型**
| 影响面 | 验证动作 |
|--------|---------|
| F 前端UI | `npm run dev` 启动开发服务器,逐页面检查视觉效果 |
| F 前端逻辑 | grep搜索残留旧代码旧URL、旧字段名、已删除的组件引用 |
| F Mock数据 | 检查Mock文件与页面§9数据结构一致 |
| B 后端 | `dotnet build` 编译通过 + 测试运行通过 |
| B 后端测试 | 对照 `04-后端开发规范.md` §6 必测7大类场景确认覆盖 |
| D 数据库 | 迁移脚本幂等性验证(重复执行不报错不丢数据) |
| A API接口 | 双列URL同步检查Mock列↔正式列同时更新 |
| R 需求文档 | 检查与 `00-需求与设计文档.md` 已确认决策无冲突 |
**第3项跨文档一致性抽查**
根据修改类型,抽查以下关联一致性:
| 修改类型 | 抽查项 |
|---------|--------|
| 新增/删除字段 | 页面§4列表字段 ↔ API响应JSON ↔ Mock数据 ↔ Entity/DTO |
| 新增/删除接口 | 端点清单(Mock列+正式列) ↔ 页面§10接口引用 ↔ Mock文件 |
| 新增/删除页面 | 路由总表 ↔ 模块进度表 ↔ 菜单映射 |
| 状态变更 | 页面§7状态机 ↔ 组件代码中的状态判断逻辑 |
| 按钮变更 | 页面§5操作按钮 ↔ 组件template中的按钮元素 |
**第4项Git提交**
- commit message 对应修改计划摘要
- push到远程仓库
### 验收通过标准
以下全部满足方可声明任务完成:
1. ✅ 变更清单核对:计划中的所有文件均已修改,无遗漏无多余
2. ✅ 编译/构建通过(如有代码修改)
3. ✅ 定向验证通过(按影响面类型逐项执行)
4. ✅ 跨文档一致性抽查通过
5. ✅ Git commit + push 完成
## 豁免条件
以下情况可跳过预处理直接执行:
@ -222,3 +295,102 @@ AI回复
> 用户:"设备列表的分页 pageSize 上限从100改成200直接执行"
AI跳过预处理直接开始修改。
### 示例6前端全局规范修改含完整执行中验证+完成验收)
> 用户:"所有列表页的列宽改为均分,批量操作按钮统一放到上方"
**第一步~第三步**(略,按正常流程输出修改计划摘要)
**第四步:执行中验证**
每改完一个文件后的自检记录:
> 改完 `02-前端全局规范.md`
> - ✅ 新增"el-table列宽均分规则"和"操作按钮统一布局规则"两个章节
> - ✅ 规则内容与用户需求一致禁止固定width、操作列例外、批量按钮改页头
>
> 改完 `03-01-设备列表页面.md`
> - ✅ §4列表字段选择框50数据列全部改"-"操作列180
> - ✅ §5操作按钮批量停用/启用从"底部栏"改为"页头"
> - ✅ §2布局图移除底部批量操作栏操作栏增加批量按钮
> - ✅ 联动检查:页面文档的列宽值与全局规范新规则一致
>
> 改完 `MachineListPage.vue`
> - ✅ lsp_diagnostics 无error
> - ✅ 逐列核对template中的el-table-column属性与页面§4字段表一致
> - ✅ grep搜索 `width=` 无残留仅操作列和选择框列有width
> - ✅ grep搜索 `sticky``底部栏` 无残留
>
> (其余页面同理,每改完一个文件立即自检)
**第五步:完成验收**
> **第1项 变更清单核对:**
>
> | 计划文件 | 状态 | 说明 |
> |---------|------|------|
> | `02-前端全局规范.md` | ✅ | 新增两条规则 |
> | `03-01-设备列表页面.md` | ✅ | 列宽+按钮位置 |
> | `04-01-品牌列表页面.md` | ✅ | 列宽 |
> | `05-01-采集地址页面.md` | ✅ | 列宽 |
> | `06-01-员工管理页面.md` | ✅ | 列宽+按钮位置 |
> | `07-01-产量报表页面.md` | ✅ | 列宽 |
> | `08-01-告警中心页面.md` | ✅ | 列宽 |
> | `11-01-操作日志页面.md` | ✅ | 列宽 |
> | `09-01-系统设置页面.md` | ✅ | 列宽 |
> | `MachineListPage.vue` | ✅ | 列宽+按钮位置 |
> | `WorkerListPage.vue` | ✅ | 列宽+按钮位置 |
> | 其余5个Vue组件 | ✅ | 列宽 |
>
> **第2项 定向验证:**
> - F 前端逻辑grep搜索 `width=` 在Vue组件中仅命中选择框列和操作列 → ✅
> - F 前端逻辑grep搜索 `底部栏`/`sticky` 在Vue组件中零命中 → ✅
> - F 前端UI`npm run dev` 启动,逐页面查看列宽均分效果 → ⏳ 需用户浏览器确认
>
> **第3项 跨文档一致性抽查:**
> - 抽查"设备列表"页面§4列宽值 ↔ Vue组件el-table-column的width属性 → ✅ 一致
> - 抽查"员工列表"页面§5批量按钮位置 ↔ Vue组件中批量按钮DOM位置 → ✅ 一致
>
> **第4项 Git提交**
> - commit: "全局列宽均分+批量按钮统一到上方8个页面文档+8个Vue组件"
> - push → ✅ 完成
### 示例7后端Bug修复含完整执行中验证+完成验收)
> 用户:"MachineService.GetList 分页 page=0 时报错"
**第三步输出计划:**
> 涉及文件:
> - `src/CncService/Impl/MachineService.cs` → GetList 增加 page 修正
> - `tests/CncService.Tests/MachineServiceTests.cs` → 新增边界测试
**第四步:执行中验证**
> 改完 `MachineService.cs`
> - ✅ lsp_diagnostics 无error
> - ✅ 逻辑page < 1 1
>
> 改完 `MachineServiceTests.cs`
> - ✅ lsp_diagnostics 无error
> - ✅ 新增测试覆盖page=0、page=-1 两个场景
> - ✅ 测试命名遵循 `MethodName_Scenario_Expected` 模式
**第五步:完成验收**
> **第1项 变更清单核对:**
> - `MachineService.cs` ✅ 仅改分页修正逻辑
> - `MachineServiceTests.cs` ✅ 新增2个测试用例
> - 无多余改动 ✅
>
> **第2项 定向验证:**
> - `dotnet build` → 编译通过 ✅
> - `dotnet test` → 全部测试通过含新增2个
> - 对照§6必测场景§G分页参数场景已覆盖 ✅
>
> **第3项 跨文档一致性抽查:**
> - 本次为纯Bugfix不涉及文档变更无跨文档一致性风险 ✅
>
> **第4项 Git提交**
> - commit: "修复GetList分页page=0报错增加边界测试"
> - push → ✅ 完成

@ -50,17 +50,17 @@
<!-- 列表 -->
<el-table :data="tableData" border stripe v-loading="loading" @selection-change="(rows: Alert[]) => selectedRows = rows">
<el-table-column type="selection" width="40" fixed="left" align="center" />
<el-table-column prop="createdAt" label="告警时间" width="170" sortable />
<el-table-column label="告警类型" width="100" align="center">
<el-table-column type="selection" width="50" fixed="left" align="center" />
<el-table-column prop="createdAt" label="告警时间" sortable />
<el-table-column label="告警类型" align="center">
<template #default="{ row }">
<el-tag :type="alertTypeTag(row.alertType)" size="small">{{ alertTypeLabel(row.alertType) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="title" label="标题" width="160" show-overflow-tooltip />
<el-table-column prop="machineName" label="机床" width="100" show-overflow-tooltip align="center" />
<el-table-column prop="title" label="标题" show-overflow-tooltip />
<el-table-column prop="machineName" label="机床" show-overflow-tooltip align="center" />
<el-table-column prop="detail" label="详情" show-overflow-tooltip />
<el-table-column label="处理状态" width="80" align="center">
<el-table-column label="处理状态" align="center">
<template #default="{ row }">
<el-tag :type="row.isResolved ? 'success' : 'danger'" size="small">{{ row.isResolved ? '已处理' : '未处理' }}</el-tag>
</template>

@ -2,12 +2,12 @@
<div>
<div class="mb-16"><el-button type="primary" @click="goAdd">+ </el-button></div>
<el-table :data="tableData" border stripe v-loading="loading">
<el-table-column prop="brandName" label="品牌名称" min-width="150"/>
<el-table-column prop="deviceField" label="device字段" width="120"/>
<el-table-column prop="tagsPath" label="tags路径" width="120"/>
<el-table-column label="状态" width="80" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="fieldCount" label="字段数" width="80" align="center"/>
<el-table-column label="操作" width="260" align="center"><template #default="{row}">
<el-table-column prop="brandName" label="品牌名称"/>
<el-table-column prop="deviceField" label="device字段"/>
<el-table-column prop="tagsPath" label="tags路径"/>
<el-table-column label="状态" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="fieldCount" label="字段数" align="center"/>
<el-table-column label="操作" width="180" align="center"><template #default="{row}">
<el-button link type="primary" @click="goEdit(row.id)"></el-button>
<!-- 复制按钮放在编辑之后 -->
<el-button text type="default" @click="handleCopy(row)" style="margin-left:6px; display:inline-flex; align-items:center; gap:6px">

@ -6,15 +6,15 @@
<el-form-item><el-button type="primary" @click="loadData"></el-button><el-button @click="resetQuery"></el-button></el-form-item>
</el-form>
<el-table :data="tableData" border stripe v-loading="loading">
<el-table-column prop="name" label="名称" width="150"><template #default="{row}"><el-link type="primary" @click="goDetail(row.id)">{{row.name}}</el-link></template></el-table-column>
<el-table-column prop="url" label="URL" show-overflow-tooltip/>
<el-table-column prop="brandName" label="品牌" width="100" align="center"/>
<el-table-column prop="collectInterval" label="采集间隔" width="100" align="center"/>
<el-table-column label="状态" width="80" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="lastCollectTime" label="最后采集" width="170"/>
<el-table-column prop="machineCount" label="机床数" width="80" align="center"/>
<el-table-column prop="failCount" label="连续失败" width="100" align="center"><template #default="{row}"><el-tag :type="row.failCount===0?'success':row.failCount<=3?'warning':'danger'" size="small">{{row.failCount}} </el-tag></template></el-table-column>
<el-table-column label="操作" width="160" align="center"><template #default="{row}">
<el-table-column prop="name" label="名称"><template #default="{row}"><el-link type="primary" @click="goDetail(row.id)">{{row.name}}</el-link></template></el-table-column>
<el-table-column prop="url" label="URL" min-width="200" show-overflow-tooltip/>
<el-table-column prop="brandName" label="品牌" align="center"/>
<el-table-column prop="collectInterval" label="采集间隔" align="center"/>
<el-table-column label="状态" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="lastCollectTime" label="最后采集"/>
<el-table-column prop="machineCount" label="机床数" align="center"/>
<el-table-column prop="failCount" label="连续失败" align="center"><template #default="{row}"><el-tag :type="row.failCount===0?'success':row.failCount<=3?'warning':'danger'" size="small">{{row.failCount}} </el-tag></template></el-table-column>
<el-table-column label="操作" width="120" align="center"><template #default="{row}">
<el-button link type="primary" @click="handleEdit(row)"></el-button>
<el-button link type="danger" @click="handleDelete(row)"></el-button>
</template></el-table-column>

@ -24,17 +24,17 @@
</el-form>
<el-table :data="adjList" border stripe v-loading="adjLoading">
<el-table-column prop="createdAt" label="修正时间" width="170" sortable align="center" />
<el-table-column prop="targetTable" label="目标表" width="150" show-overflow-tooltip>
<el-table-column prop="createdAt" label="修正时间" sortable align="center" />
<el-table-column prop="targetTable" label="目标表" show-overflow-tooltip>
<template #default="{ row }">
{{ targetTableLabel(row.targetTable) }}
</template>
</el-table-column>
<el-table-column prop="targetId" label="目标ID" width="80" align="center" />
<el-table-column prop="oldValue" label="修正前" width="80" align="center" />
<el-table-column prop="newValue" label="修正后" width="80" align="center" />
<el-table-column prop="targetId" label="目标ID" align="center" />
<el-table-column prop="oldValue" label="修正前" align="center" />
<el-table-column prop="newValue" label="修正后" align="center" />
<el-table-column prop="reason" label="修正原因" show-overflow-tooltip />
<el-table-column prop="operatorIp" label="操作IP" width="130" align="center" />
<el-table-column prop="operatorIp" label="操作IP" align="center" />
</el-table>
<el-empty v-if="!adjLoading && adjList.length === 0" description="暂无产量修正记录" />
@ -82,13 +82,13 @@
</el-form>
<el-table :data="sysList" border stripe v-loading="sysLoading">
<el-table-column prop="createdAt" label="时间" width="170" sortable align="center" />
<el-table-column label="级别" width="80" align="center">
<el-table-column prop="createdAt" label="时间" sortable align="center" />
<el-table-column label="级别" align="center">
<template #default="{ row }">
<el-tag :type="logLevelTag(row.logLevel)" size="small">{{ row.logLevel }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="source" label="来源" width="130" show-overflow-tooltip />
<el-table-column prop="source" label="来源" show-overflow-tooltip />
<el-table-column label="消息" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.message }}</span>

@ -4,6 +4,8 @@
<el-button type="primary" @click="handleAdd">+ </el-button>
<el-button @click="importVisible = true">导入</el-button>
<el-button type="success" @click="handleExport"></el-button>
<el-button v-if="selectedRows.length" size="default" @click="batchToggle(0)" :disabled="!selectedRows.some(r => r.isEnabled)">({{ selectedRows.length }})</el-button>
<el-button v-if="selectedRows.length" size="default" type="primary" @click="batchToggle(1)" :disabled="!selectedRows.some(r => !r.isEnabled)">({{ selectedRows.length }})</el-button>
</div>
<el-form :inline="true" class="mb-16">
@ -33,30 +35,30 @@
</el-form>
<el-table :data="tableData" border stripe v-loading="loading" @selection-change="(rows: Machine[]) => selectedRows = rows">
<el-table-column type="selection" width="40" fixed="left" align="center" />
<el-table-column type="selection" width="50" fixed="left" align="center" />
<el-table-column label="机床名称" min-width="120" fixed="left" show-overflow-tooltip>
<template #default="{ row }">
<el-link type="primary" @click="goDetail(row.id)">{{ row.name }}</el-link>
</template>
</el-table-column>
<el-table-column prop="deviceCode" label="device_code" width="140" show-overflow-tooltip sortable />
<el-table-column prop="workshopName" label="车间" width="80" align="center" sortable />
<el-table-column prop="brandName" label="品牌" width="100" align="center" sortable />
<el-table-column prop="ipAddress" label="IP地址" width="120" />
<el-table-column label="在线状态" width="80" align="center">
<el-table-column prop="deviceCode" label="device_code" show-overflow-tooltip sortable />
<el-table-column prop="workshopName" label="车间" align="center" sortable />
<el-table-column prop="brandName" label="品牌" align="center" sortable />
<el-table-column prop="ipAddress" label="IP地址" />
<el-table-column label="在线状态" align="center">
<template #default="{ row }">
<el-tag :type="row.isOnline ? 'success' : 'info'" size="small">{{ row.isOnline ? '在线' : '离线' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" width="80" align="center">
<el-table-column label="状态" align="center">
<template #default="{ row }">
<el-tag :type="row.isEnabled ? 'success' : 'danger'" size="small">{{ row.isEnabled ? '启用' : '停用' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="workerName" label="绑定工人" width="100" align="center">
<el-table-column prop="workerName" label="绑定工人" align="center">
<template #default="{ row }">{{ row.workerName || '-' }}</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right" align="center">
<el-table-column label="操作" width="180" fixed="right" align="center">
<template #default="{ row }">
<el-button type="primary" plain @click="handleViewDetail(row)" style="margin-right:6px">
<el-icon><View/></el-icon>
@ -68,12 +70,6 @@
</el-table-column>
</el-table>
<div v-if="selectedRows.length" style="margin-top:12px;padding:8px;background:#f5f7fa;border-radius:4px;display:flex;align-items:center;gap:12px">
<span>已选{{ selectedRows.length }}</span>
<el-button size="small" @click="batchToggle(0)" :disabled="!selectedRows.some(r => r.isEnabled)">批量停用</el-button>
<el-button size="small" type="primary" @click="batchToggle(1)" :disabled="!selectedRows.some(r => !r.isEnabled)">批量启用</el-button>
</div>
<el-pagination
v-model:current-page="page.page"
v-model:page-size="page.pageSize"

@ -42,15 +42,15 @@
<!-- 数据表格 -->
<el-table :data="tableData" border stripe v-loading="loading">
<el-table-column prop="date" label="日期" width="110"/>
<el-table-column prop="machineName" label="机床" width="120"/>
<el-table-column prop="programName" label="程序名" min-width="140" show-overflow-tooltip/>
<el-table-column label="产量" width="80" align="center"><template #default="{row}">{{row.dataStatus==='data_missing'?'-':row.quantity}}</template></el-table-column>
<el-table-column prop="runTime" label="运行时间" width="100" align="center"/>
<el-table-column prop="cuttingTime" label="切削时间" width="100" align="center"/>
<el-table-column label="日状态" width="80" align="center"><template #default="{row}"><el-tag :type="row.dataStatus==='normal'?'info':row.dataStatus==='offline'?'danger':'warning'" size="small">{{row.dataStatus==='normal'?'正常':row.dataStatus==='offline'?'离线':'缺失'}}</el-tag></template></el-table-column>
<el-table-column label="修正" width="80" align="center"><template #default="{row}">{{row.isAdjusted?'✓':'-'}}</template></el-table-column>
<el-table-column label="历史/操作" width="180" align="center"><template #default="{row}"><el-button text type="primary" @click="handleAdjust(row)"></el-button>
<el-table-column prop="date" label="日期"/>
<el-table-column prop="machineName" label="机床"/>
<el-table-column prop="programName" label="程序名" show-overflow-tooltip/>
<el-table-column label="产量" align="center"><template #default="{row}">{{row.dataStatus==='data_missing'?'-':row.quantity}}</template></el-table-column>
<el-table-column prop="runTime" label="运行时间" align="center"/>
<el-table-column prop="cuttingTime" label="切削时间" align="center"/>
<el-table-column label="日状态" align="center"><template #default="{row}"><el-tag :type="row.dataStatus==='normal'?'info':row.dataStatus==='offline'?'danger':'warning'" size="small">{{row.dataStatus==='normal'?'正常':row.dataStatus==='offline'?'离线':'缺失'}}</el-tag></template></el-table-column>
<el-table-column label="修正" align="center"><template #default="{row}">{{row.isAdjusted?'✓':'-'}}</template></el-table-column>
<el-table-column label="操作" width="180" align="center"><template #default="{row}"><el-button text type="primary" @click="handleAdjust(row)"></el-button>
<el-button text @click="showHistory(row)" style="margin-left:8px">修正历史</el-button></template></el-table-column>
</el-table>
<el-pagination v-model:current-page="page.page" v-model:page-size="page.pageSize" :page-sizes="[20,50,100]" :total="page.total" background layout="total,sizes,prev,pager,next,jumper"/>

@ -7,7 +7,7 @@
<el-form-item><el-input v-model="configKeyword" placeholder="配置项/说明" clearable @input="filterConfig" /></el-form-item>
</el-form>
<el-table :data="filteredConfigs" border stripe v-loading="configLoading">
<el-table-column prop="configKey" label="配置项" width="200" show-overflow-tooltip />
<el-table-column prop="configKey" label="配置项" show-overflow-tooltip />
<el-table-column label="配置值" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ getDisplayValue(row) }}</span>
@ -16,8 +16,8 @@
</el-button>
</template>
</el-table-column>
<el-table-column prop="valueType" label="类型" width="80" align="center" />
<el-table-column prop="description" label="说明" width="200" show-overflow-tooltip />
<el-table-column prop="valueType" label="类型" align="center" />
<el-table-column prop="description" label="说明" show-overflow-tooltip />
<el-table-column label="操作" width="160" align="center">
<template #default="{ row }">
<el-button link type="primary" @click="editConfig(row)"></el-button>
@ -57,9 +57,9 @@
<el-tab-pane label="车间管理" name="workshop">
<div class="mb-16"><el-button type="primary" @click="addWorkshop">+ </el-button></div>
<el-table :data="workshopList" border stripe v-loading="workshopLoading">
<el-table-column prop="name" label="车间名称" width="200" show-overflow-tooltip />
<el-table-column prop="sortOrder" label="排序" width="80" align="center" sortable />
<el-table-column label="状态" width="80" align="center">
<el-table-column prop="name" label="车间名称" show-overflow-tooltip />
<el-table-column prop="sortOrder" label="排序" align="center" sortable />
<el-table-column label="状态" align="center">
<template #default="{ row }">
<el-tag :type="row.isEnabled ? 'success' : 'danger'" size="small">{{ row.isEnabled ? '启用' : '停用' }}</el-tag>
</template>

@ -1,26 +1,27 @@
<template>
<div>
<div class="mb-16"><el-button type="primary" @click="handleAdd">+ </el-button></div>
<div class="mb-16">
<el-button type="primary" @click="handleAdd">+ </el-button>
<el-button v-if="selectedRows.length" size="default" @click="batchStatus(1)">({{ selectedRows.length }})</el-button>
<el-button v-if="selectedRows.length" size="default" @click="batchStatus(0)">({{ selectedRows.length }})</el-button>
</div>
<el-form :inline="true" class="mb-16">
<el-form-item label="状态"><el-select v-model="query.isEnabled" clearable><el-option label="启用" :value="1"/><el-option label="停用" :value="0"/></el-select></el-form-item>
<el-form-item><el-input v-model="query.keyword" placeholder="工号/姓名" clearable/></el-form-item>
<el-form-item><el-button type="primary" @click="loadData"></el-button><el-button @click="resetQuery"></el-button></el-form-item>
</el-form>
<el-table :data="tableData" border stripe v-loading="loading">
<el-table-column type="selection" width="40"/>
<el-table-column prop="code" label="工号" width="120"/>
<el-table-column prop="name" label="姓名" width="120"><template #default="{row}"><el-link type="primary" @click="goDetail(row.id)">{{row.name}}</el-link></template></el-table-column>
<el-table-column label="状态" width="80" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="machineCount" label="绑定机床数" width="100" align="center"/>
<el-table-column type="selection" width="50"/>
<el-table-column prop="code" label="工号"/>
<el-table-column prop="name" label="姓名"><template #default="{row}"><el-link type="primary" @click="goDetail(row.id)">{{row.name}}</el-link></template></el-table-column>
<el-table-column label="状态" align="center"><template #default="{row}"><el-tag :type="row.isEnabled?'success':'danger'" size="small">{{row.isEnabled?'启用':'停用'}}</el-tag></template></el-table-column>
<el-table-column prop="machineCount" label="绑定机床数" align="center"/>
<el-table-column prop="machineNames" label="绑定机床" show-overflow-tooltip/>
<el-table-column label="操作" width="120" align="center"><template #default="{row}">
<el-button link type="primary" @click="handleEdit(row)"></el-button>
<el-button link type="danger" @click="handleDelete(row)" :disabled="row.machineCount>0">删除</el-button>
</template></el-table-column>
</el-table>
<div v-if="selectedRows.length" style="margin-top:12px;padding:8px 12px;background:#ecf5ff;border-radius:4px">
已选{{selectedRows.length}} <el-button size="small" @click="batchStatus(1)"></el-button><el-button size="small" @click="batchStatus(0)"></el-button>
</div>
<!-- 分页控件 -->
<div style="margin-top:12px;display:flex;justify-content:flex-end;align-items:center">
<el-pagination

Loading…
Cancel
Save