diff --git a/docs/功能测试-BOM物料清单.md b/docs/功能测试-BOM物料清单.md new file mode 100644 index 00000000..7526945c --- /dev/null +++ b/docs/功能测试-BOM物料清单.md @@ -0,0 +1,20 @@ +# 功能测试任务列表 - BOM物料清单 + +> 路由:`/production_configuration/matetial_model/bom` + +| 序号 | 测试项 | 操作步骤 | 预期结果 | 结果 | +|---|---|---|---|---| +| 1 | 页面入口 | 从菜单进入“BOM物料清单”,或直接访问路由 | 页面正常打开,表格展示 BOM 编码、名称、产品型号、状态、创建人、创建时间和备注 | ☐ | +| 2 | 条件查询 | 输入 BOM 编码、名称或选择产品型号后点击“查询” | 列表按条件刷新,分页回到第一页 | ☐ | +| 3 | 重置查询 | 点击“重置” | 查询条件清空,列表恢复默认数据 | ☐ | +| 4 | 新增校验 | 点击“新增”,不填写编码、名称或产品型号直接确认 | 表单提示必填校验,不提交请求 | ☐ | +| 5 | 新增 BOM | 填写 BOM 编码、名称、产品型号、状态和备注后确认 | 弹窗关闭,提示操作成功,列表出现新增 BOM | ☐ | +| 6 | 编辑 BOM | 点击“编辑”,修改名称、状态或备注后确认 | 表单回显旧值,保存后列表展示新值 | ☐ | +| 7 | 删除 BOM | 点击“删除”并确认 | 提示操作成功,记录被删除,分页刷新正确 | ☐ | +| 8 | 打开 BOM 关系 | 点击“设置BOM” | 全屏关系弹窗打开,左侧显示工序单元,右侧显示当前工序 IN/OUT 关系 | ☐ | +| 9 | 切换工序 | 在左侧选择不同工序单元 | IN/OUT 列表按工序刷新 | ☐ | +| 10 | 添加 IN 物料 | 在 IN 区域点击“新增”,选择一个或多个物料后确认 | 物料加入 IN 列表,重复物料提示不可重复选择 | ☐ | +| 11 | 编辑 IN 投入数量 | 修改 IN 列表的投入数量并移出输入框 | 数量保存成功,刷新后仍保持新值 | ☐ | +| 12 | 添加 OUT 物料限制 | 在 OUT 区域尝试选择多个物料或已有 OUT 后继续新增 | 系统提示 OUT 结构只允许 1 个半成品 | ☐ | +| 13 | 删除 BOM 关系 | 勾选 IN/OUT 关系后点击删除,或点击行内删除 | 关系删除成功,列表刷新 | ☐ | +| 14 | 权限按钮 | 使用缺少新增/编辑/删除/设置BOM权限的账号进入页面 | 对应按钮不显示或不可操作 | ☐ | diff --git a/docs/功能测试-排班日历.md b/docs/功能测试-排班日历.md new file mode 100644 index 00000000..3daac6a0 --- /dev/null +++ b/docs/功能测试-排班日历.md @@ -0,0 +1,14 @@ +# 功能测试任务列表 - 排班日历 + +> 路由:`/system_settings/organization/production_shift_calender` + +| 序号 | 测试项 | 操作步骤 | 预期结果 | 结果 | +|---|---|---|---|---| +| 1 | 页面入口 | 从菜单进入“排班日历” | 页面正常打开,展示当前月份日历 | ☐ | +| 2 | 初始数据加载 | 打开页面后观察日历单元格 | 系统请求当前日历可视范围的排班数据,并在日期下显示班次计划标签 | ☐ | +| 3 | 休息日展示 | 查看包含休息日的日期 | 休息日以灰色标签显示“休” | ☐ | +| 4 | 工作日展示 | 查看包含排班的日期 | 日期下展示班次计划标签 | ☐ | +| 5 | 明细悬浮 | 鼠标悬浮工作日班次计划标签 | 弹出层展示班次名称、开始/结束时间、绑定班组和跨天标识 | ☐ | +| 6 | 跨月切换 | 点击日历上一月/下一月 | 日历切换月份并重新加载新可视范围数据 | ☐ | +| 7 | 选择日期 | 点击任意日期 | 日期高亮状态正常,不影响排班数据显示 | ☐ | +| 8 | 空数据展示 | 切换到无排班数据的月份 | 日历正常显示,无错误提示或残留旧数据 | ☐ | diff --git a/docs/功能测试-班次管理.md b/docs/功能测试-班次管理.md new file mode 100644 index 00000000..c420c8e5 --- /dev/null +++ b/docs/功能测试-班次管理.md @@ -0,0 +1,19 @@ +# 功能测试任务列表 - 班次管理 + +> 路由:`/system_settings/organization/production_shift_management` + +| 序号 | 测试项 | 操作步骤 | 预期结果 | 结果 | +|---|---|---|---|---| +| 1 | 页面入口 | 从菜单进入“班次管理” | 页面正常打开,展示班次计划名称、编码、起止时间、状态、创建/更新时间 | ☐ | +| 2 | 条件查询 | 输入计划名称、编码或创建时间后查询 | 列表按条件刷新 | ☐ | +| 3 | 新增校验 | 点击新增,不填名称、编码或时间范围直接确认 | 显示必填校验 | ☐ | +| 4 | 新增班次计划 | 填写计划信息、选择班组、添加班次明细后确认 | 保存成功,列表出现新计划 | ☐ | +| 5 | 班组绑定唯一性 | 两条班次明细绑定同一个班组 | 第二次绑定被阻止并提示 | ☐ | +| 6 | 明细必填校验 | 添加班次明细但缺少名称、开始时间或结束时间 | 提示对应行缺失字段 | ☐ | +| 7 | 编辑班次计划 | 点击编辑,修改状态、休息日、明细后确认 | 保存成功,重新打开可回显新数据 | ☐ | +| 8 | 单条删除 | 点击删除并确认 | 计划删除成功 | ☐ | +| 9 | 批量删除 | 勾选多条计划后批量删除 | 所选计划删除成功 | ☐ | +| 10 | 导入模板 | 点击导入后下载模板 | 浏览器下载班次计划导入模板 | ☐ | +| 11 | 导入数据 | 选择合法 xls/xlsx 文件并确认导入 | 预览展示后提交成功,列表刷新 | ☐ | +| 12 | 导出任务 | 点击导出并确认 | 提示下载任务创建成功 | ☐ | +| 13 | 权限按钮 | 使用缺少权限账号进入页面 | 对应新增/编辑/删除/导入/导出按钮隐藏或不可操作 | ☐ | diff --git a/docs/功能测试-班组管理.md b/docs/功能测试-班组管理.md new file mode 100644 index 00000000..79930d69 --- /dev/null +++ b/docs/功能测试-班组管理.md @@ -0,0 +1,19 @@ +# 功能测试任务列表 - 班组管理 + +> 路由:`/system_settings/organization/production_team_manage` + +| 序号 | 测试项 | 操作步骤 | 预期结果 | 结果 | +|---|---|---|---|---| +| 1 | 页面入口 | 从菜单进入“班组管理” | 页面正常打开,展示班组名称、所属厂区、所属产线、创建/更新时间 | ☐ | +| 2 | 条件查询 | 输入班组名称、选择厂区/产线或创建时间后查询 | 列表按条件刷新 | ☐ | +| 3 | 新增校验 | 点击新增,不填班组名称、厂区或产线直接确认 | 显示必填校验,不提交 | ☐ | +| 4 | 新增班组 | 填写班组信息,添加成员并设置班组长后确认 | 提示操作成功,列表出现新班组 | ☐ | +| 5 | 班组长唯一性 | 添加多个成员并尝试设置两个班组长 | 第二个班组长被拦截,提示只允许一个班组长 | ☐ | +| 6 | 编辑班组 | 点击编辑,修改成员或班组信息后确认 | 保存成功,重新打开可看到新数据 | ☐ | +| 7 | 删除成员 | 编辑已有班组,删除已有成员 | 成员删除成功,列表刷新 | ☐ | +| 8 | 单条删除 | 点击行内删除并确认 | 班组删除成功 | ☐ | +| 9 | 批量删除 | 勾选多条数据后点击批量删除并确认 | 所选班组删除成功 | ☐ | +| 10 | 导入模板 | 点击导入后下载模板 | 浏览器下载班组导入模板 | ☐ | +| 11 | 导入数据 | 选择合法 xls/xlsx 文件并确认导入 | 预览数据正确,提交后提示成功并刷新列表 | ☐ | +| 12 | 导出任务 | 点击导出并确认 | 提示下载任务创建成功 | ☐ | +| 13 | 权限按钮 | 使用缺少权限账号进入页面 | 对应新增/编辑/删除/导入/导出按钮隐藏或不可操作 | ☐ | diff --git a/docs/功能测试-监控设置.md b/docs/功能测试-监控设置.md new file mode 100644 index 00000000..5f855637 --- /dev/null +++ b/docs/功能测试-监控设置.md @@ -0,0 +1,15 @@ +# 功能测试任务列表 - 监控设置 + +> 路由:`/system_settings/system_monitoring/setting` + +| 序号 | 测试项 | 操作步骤 | 预期结果 | 结果 | +|---|---|---|---|---| +| 1 | 页面入口 | 从菜单进入“监控设置”,或直接访问路由 | 页面正常打开,表格展示监控编码、名称、IP、端口、版本和预警阈值字段 | ☐ | +| 2 | 条件查询 | 输入监控编码或监控名称后点击“查询” | 列表按条件刷新,分页回到第一页 | ☐ | +| 3 | 重置查询 | 输入查询条件后点击“重置” | 查询条件清空,列表恢复默认数据 | ☐ | +| 4 | 新增必填校验 | 点击“新增”,不填写编码、名称、IP 或端口直接确认 | 表单提示对应必填校验,不提交请求 | ☐ | +| 5 | 新增监控配置 | 填写编码、名称、IP、端口、刷新间隔、CPU/磁盘/内存阈值和 Python 版本后确认 | 弹窗关闭,提示操作成功,列表出现新增记录 | ☐ | +| 6 | 编辑监控配置 | 点击某条记录“编辑”,修改名称或阈值后确认 | 弹窗回显旧值,保存后列表展示新值 | ☐ | +| 7 | 删除取消 | 点击“删除”后在确认框选择取消 | 数据不删除,列表保持不变 | ☐ | +| 8 | 删除确认 | 点击“删除”后确认 | 提示操作成功,记录从列表移除,分页数量正确刷新 | ☐ | +| 9 | 权限按钮 | 使用无新增/编辑/删除权限的账号进入页面 | 对应按钮不显示或不可操作 | ☐ | diff --git a/docs/迁移任务列表.md b/docs/迁移任务列表.md index ae74b2a3..3d6b726f 100644 --- a/docs/迁移任务列表.md +++ b/docs/迁移任务列表.md @@ -3,8 +3,8 @@ > 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。 - 总功能数:79 -- 已迁移:74 -- 未迁移:5 +- 已迁移:79 +- 未迁移:0 | 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 | |:---:|---|---|---|---|---| @@ -13,7 +13,7 @@ | ✅ | 系统设置 (System Administration) | 菜单管理 (Menu Management) | 菜单配置 (Menu Configuration) | 系统菜单配置 | `src/views/system-administration/menu-management/menu-configuration/` | | ✅ | 系统设置 (System Administration) | 系统助手 (System Utilities) | 操作日志 (Operation Logs) | 系统操作日志 | `src/views/system-administration/system-utilities/operation-logs/` | | ✅ | 系统设置 (System Administration) | 系统助手 (System Utilities) | 接口日志 (API Logs) | 与设备对接流程交互日志(支持按 IP 和接口名称查询) | `src/views/system-administration/system-utilities/api-logs/` | -| ⬜ | 系统设置 (System Administration) | 系统监控 (System Monitoring) | 监控设置 (Monitoring Configuration) | 系统监控配置 | 待确认 | +| ✅ | 系统设置 (System Administration) | 系统监控 (System Monitoring) | 监控设置 (Monitoring Configuration) | 系统监控配置 | `src/views/system-administration/system-monitoring/monitoring-configuration/` | | ✅ | 生产配置 (Production Master Data) | 工厂模型 (Factory Model) | 产线设置 (Production Line) | 管理产线(支持增删改查) | `src/views/production-master-data/factory-model/production-line/` | | ✅ | 生产配置 (Production Master Data) | 工厂模型 (Factory Model) | 工厂区域 (Factory Area) | 管理工厂区域(支持增删改查) | `src/views/production-master-data/factory-model/factory-area/` | | ✅ | 生产配置 (Production Master Data) | 工艺模型 (Process Model) | 工艺流程类别 (Process Category) | 工艺流程类别的增删改查 | `src/views/production-master-data/process-model/process-category/` | @@ -23,12 +23,12 @@ | ✅ | 生产配置 (Production Master Data) | 产品管理 (Product Management) | 不良管理 (Defect Management) | 不良代码及描述管理,支持批量导入 | `src/views/production-master-data/product-model/product-ng-info/` | | ✅ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | 物料类别列表 (Material Category) | 区分原材料和半成品 | `src/views/production-master-data/material-model/material-category/` | | ✅ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | 物料信息管理 (Material Master) | 维护物料编码、名称、规格等属性 | `src/views/production-master-data/material-model/material-master/` | -| ⬜ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | BOM物料清单 (Bill of Materials) | 产品BOM管理 | 待确认 | +| ✅ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | BOM物料清单 (Bill of Materials) | 产品BOM管理 | `src/views/production-master-data/material-model/bill-of-materials/` | | ✅ | 生产配置 (Production Master Data) | 物料模型 (Material Model) | 计量单位 (Unit of Measure) | 计量单位配置与管理 | `src/views/production-master-data/material-model/material-unit/` | | ✅ | 生产配置 (Production Master Data) | SPC采集模型 (SPC Configuration) | SPC采集配置 (Data Collection Configuration) | 配置SPC采集参数 | `src/views/production-master-data/spc-configuration/data-collection-configuration/` | -| ⬜ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班组管理 (Team Management) | 管理生产班组 | 待确认 | -| ⬜ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班次管理 (Shift Management) | 管理生产班次 | 待确认 | -| ⬜ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 排班日历 (Scheduling Calendar) | 查看排班日历 | 待确认 | +| ✅ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班组管理 (Team Management) | 管理生产班组 | `src/views/production-master-data/team-model/team-management/` | +| ✅ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 班次管理 (Shift Management) | 管理生产班次 | `src/views/production-master-data/team-model/shift-management/` | +| ✅ | 生产配置 (Production Master Data) | 班组模型 (Team Model) | 排班日历 (Scheduling Calendar) | 查看排班日历 | `src/views/production-master-data/team-model/scheduling-calendar/` | | ✅ | 设备模型 (Equipment Management) | 设备类别 (Equipment Category) | 设备类别 (Equipment Category) | 管理设备类别 | `src/views/equipment-management/equipment-model/equipment-category/` | | ✅ | 设备模型 (Equipment Management) | 设备信息 (Equipment Management) | 设备信息 (Equipment Registry) | 管理设备信息 | `src/views/equipment-management/equipment-model/equipment-registry/` | | ✅ | 设备模型 (Equipment Management) | 设备点检 (Inspection Management) | 设备点检项目 (Inspection Items) | 点检项目管理 | `src/views/equipment-management/inspection-management/inspection-items/` | diff --git a/src/api/production-master-data/bill-of-materials.js b/src/api/production-master-data/bill-of-materials.js new file mode 100644 index 00000000..ce256b33 --- /dev/null +++ b/src/api/production-master-data/bill-of-materials.js @@ -0,0 +1,56 @@ +import { request } from '@/api/_service' + +const BASE = 'production_configuration/matetial_model/bom/' +const RELATION_BASE = 'production_configuration/matetial_model/bom_relationship/' + +function apiParams (method, data = {}) { + return { + method: `production_configuration_matetial_model_bom_${method}`, + platform: 'background', + ...data + } +} + +function relationApiParams (method, data = {}) { + return { + method: `production_configuration_matetial_model_bom_relationship_${method}`, + platform: 'background', + ...data + } +} + +export function getBomAll (data) { + return request({ url: BASE + 'all', method: 'get', params: apiParams('all', data) }) +} + +export function getBomList (data) { + return request({ url: BASE + 'list', method: 'get', params: apiParams('list', data) }) +} + +export function createBom (data) { + return request({ url: BASE + 'create', method: 'post', data: apiParams('create', data) }) +} + +export function editBom (data) { + return request({ url: BASE + 'edit', method: 'put', data: apiParams('edit', data) }) +} + +export function deleteBom (data) { + return request({ url: BASE + 'delete', method: 'delete', data: apiParams('delete', data) }) +} + +export function getBomRelationshipList (data) { + return request({ url: RELATION_BASE + 'list', method: 'get', params: relationApiParams('list', data) }) +} + +export function createBomRelationship (data) { + return request({ url: RELATION_BASE + 'create', method: 'post', data: relationApiParams('create', data) }) +} + +export function editBomRelationship (data) { + return request({ url: RELATION_BASE + 'edit', method: 'put', data: relationApiParams('edit', data) }) +} + +export function deleteBomRelationship (data) { + return request({ url: RELATION_BASE + 'delete', method: 'delete', data: relationApiParams('delete', data) }) +} diff --git a/src/api/production-master-data/shift-management.js b/src/api/production-master-data/shift-management.js new file mode 100644 index 00000000..4c4a12a7 --- /dev/null +++ b/src/api/production-master-data/shift-management.js @@ -0,0 +1,17 @@ +import { request } from '@/api/_service' + +const BASE = 'system_settings/organization/production_shift_management/' + +function params (method, data = {}) { + return { method: `system_settings_organization_production_shift_management_${method}`, platform: 'background', ...data } +} + +export function getShiftAll (data) { return request({ url: BASE + 'all', method: 'get', params: params('all', data) }) } +export function getShiftList (data) { return request({ url: BASE + 'list', method: 'get', params: params('list', data) }) } +export function createShift (data) { return request({ url: BASE + 'create', method: 'post', data: params('create', data) }) } +export function editShift (data) { return request({ url: BASE + 'edit', method: 'put', data: params('edit', data) }) } +export function deleteShift (data) { return request({ url: BASE + 'delete', method: 'delete', data: params('delete', data) }) } +export function getShiftImportTemplate (data) { return request({ url: BASE + 'get_import_template', method: 'post', responseType: 'blob', data: params('get_import_template', data) }) } +export function importShiftData (data) { return request({ url: BASE + 'data_import', method: 'post', data: params('data_import', data) }) } +export function exportShiftTask (data) { return request({ url: BASE + 'data_export_task', method: 'post', data: params('data_export_task', data) }) } +export function getShiftCalendarByDateRange (data) { return request({ url: BASE + 'get_shift_by_date_range', method: 'get', params: params('get_shift_by_date_range', data) }) } diff --git a/src/api/production-master-data/team-management.js b/src/api/production-master-data/team-management.js index cc4967ac..f88868aa 100644 --- a/src/api/production-master-data/team-management.js +++ b/src/api/production-master-data/team-management.js @@ -1,76 +1,24 @@ import { request } from '@/api/_service' const BASE = 'system_settings/organization/production_team_manage/' +const MEMBER_BASE = 'system_settings/organization/production_members_manage/' -function apiParams (method, data = {}) { - return { - method: `system_settings_organization_production_team_manage_${method}`, - platform: 'background', - ...data - } +function params (method, data = {}) { + return { method: `system_settings_organization_production_team_manage_${method}`, platform: 'background', ...data } } -export function getTeamManagementList (data) { - return request({ - url: BASE + 'list', - method: 'get', - params: apiParams('list', data) - }) +function memberParams (method, data = {}) { + return { method: `system_settings_organization_production_members_manage_${method}`, platform: 'background', ...data } } -export function createTeamManagement (data) { - return request({ - url: BASE + 'create', - method: 'post', - data: apiParams('create', data) - }) -} +export function getTeamAll (data) { return request({ url: BASE + 'all', method: 'get', params: params('all', data) }) } +export function getTeamList (data) { return request({ url: BASE + 'list', method: 'get', params: params('list', data) }) } +export function createTeam (data) { return request({ url: BASE + 'create', method: 'post', data: params('create', data) }) } +export function editTeam (data) { return request({ url: BASE + 'edit', method: 'put', data: params('edit', data) }) } +export function deleteTeam (data) { return request({ url: BASE + 'delete', method: 'delete', data: params('delete', data) }) } +export function getTeamImportTemplate (data) { return request({ url: BASE + 'get_import_template', method: 'post', responseType: 'blob', data: params('get_import_template', data) }) } +export function importTeamData (data) { return request({ url: BASE + 'data_import', method: 'post', data: params('data_import', data) }) } +export function exportTeamTask (data) { return request({ url: BASE + 'data_export_task', method: 'post', data: params('data_export_task', data) }) } -export function editTeamManagement (data) { - return request({ - url: BASE + 'edit', - method: 'put', - data: apiParams('edit', data) - }) -} - -export function deleteTeamManagement (data) { - return request({ - url: BASE + 'delete', - method: 'delete', - data: apiParams('delete', data) - }) -} - -export function getTeamManagementALL (data) { - return request({ - url: BASE + 'all', - method: 'get', - params: apiParams('all', data) - }) -} - -export function getImportTemplate (data) { - return request({ - url: BASE + 'get_import_template', - method: 'post', - responseType: 'blob', - data: apiParams('get_import_template', data) - }) -} - -export function importTeamManagement (data) { - return request({ - url: BASE + 'data_import', - method: 'post', - data: apiParams('data_import', data) - }) -} - -export function exportTeamManagementTask (data) { - return request({ - url: BASE + 'data_export_task', - method: 'post', - data: apiParams('data_export_task', data) - }) -} \ No newline at end of file +export function getTeamMemberList (data) { return request({ url: MEMBER_BASE + 'list', method: 'get', params: memberParams('list', data) }) } +export function deleteTeamMember (data) { return request({ url: MEMBER_BASE + 'delete', method: 'delete', data: memberParams('delete', data) }) } diff --git a/src/api/system-administration/monitoring-configuration.js b/src/api/system-administration/monitoring-configuration.js new file mode 100644 index 00000000..1f7643b9 --- /dev/null +++ b/src/api/system-administration/monitoring-configuration.js @@ -0,0 +1,43 @@ +import { request } from '@/api/_service' + +const BASE = 'system_settings/system_monitor/setting/' + +function apiParams (method, data = {}) { + return { + method: `system_settings_system_monitoring_setting_${method}`, + platform: 'background', + ...data + } +} + +export function getMonitoringConfigurationList (data) { + return request({ + url: BASE + 'list', + method: 'get', + params: apiParams('list', data) + }) +} + +export function createMonitoringConfiguration (data) { + return request({ + url: BASE + 'create', + method: 'post', + data: apiParams('create', data) + }) +} + +export function editMonitoringConfiguration (data) { + return request({ + url: BASE + 'edit', + method: 'post', + data: apiParams('edit', data) + }) +} + +export function deleteMonitoringConfiguration (data) { + return request({ + url: BASE + 'delete', + method: 'post', + data: apiParams('delete', data) + }) +} diff --git a/src/locales/en.json b/src/locales/en.json index c8977f75..641b7a2c 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -356,6 +356,55 @@ "please_enter": "Please enter {name}", "help": "Material master data is used to maintain material code, name, specifications, etc." }, + "bill_of_materials": { + "query": "Search", + "reset": "Reset", + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "set_bom": "Set BOM", + "operation": "Operation", + "confirm": "Confirm", + "cancel": "Cancel", + "return": "Back", + "prompt": "Notice", + "operation_success": "Operation successful", + "confirm_message": "Are you sure you want to perform this operation?", + "bom_version_code": "BOM Version Code", + "bom_version_name": "BOM Version Name", + "product_model_name": "Product Model", + "status": "Status", + "enable": "Enabled", + "disable": "Disabled", + "select_status": "Please select status", + "create_user": "Created By", + "create_time": "Created At", + "remark": "Remark", + "enter_remark": "Please enter remark", + "enter_bom_version_code": "Please enter BOM version code", + "enter_bom_version_name": "Please enter BOM version name", + "select_product_model_name": "Please select product model", + "enter_bom_code": "Please enter BOM code", + "enter_bom_name": "Please enter BOM name", + "select_product_model": "Please select product model", + "length_1_45": "Length must be 1-45 characters", + "add_bom_info": "Add BOM", + "edit_bom_info": "Edit BOM", + "bom_management": "BOM Management", + "material_category": "Material Category", + "material_code": "Material Code", + "material_name": "Material Name", + "input_quantity": "Input Quantity", + "enter_input_quantity": "Please enter input quantity", + "unit": "Unit", + "select_add_material": "Select Material", + "all": "All", + "selected": "Selected", + "search_by_code_or_name": "Search by code or name", + "duplicate_material_selected": "Selected materials cannot be selected again", + "out_only_one": "OUT structure allows only one semi-finished item", + "please_select_data": "Please select data first" + }, "material_unit": { "search": "Search", "reset": "Reset", @@ -438,6 +487,156 @@ "help": "Error/NG management is used to maintain equipment error types and product NG types" } }, + "team_model": { + "team_management": { + "search": "Search", + "reset": "Reset", + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "batch_delete": "Batch Delete", + "import": "Import", + "export": "Export", + "confirm": "Confirm", + "cancel": "Cancel", + "prompt": "Notice", + "operation": "Operation", + "team_name": "Team Name", + "enter_team_name": "Please enter team name", + "area": "Area", + "select_area": "Please select area", + "production_line": "Production Line", + "select_area_then_line": "Select area before line", + "last_create_time": "Create Time", + "select_create_time": "Please select create time", + "start_time": "Start Time", + "end_time": "End Time", + "serial_number": "No.", + "affiliated_factory": "Factory Area", + "affiliated_production_line": "Production Line", + "create_time": "Created At", + "update_time": "Updated At", + "add_team": "Add Team", + "edit_team": "Edit Team", + "please_select": "Please select", + "please_select_factory_then_line": "Select factory before line", + "select_affiliated_factory": "Please select factory", + "select_affiliated_production_line": "Please select production line", + "please_enter_team_name": "Please enter team name", + "please_select_affiliated_factory": "Please select factory", + "please_select_affiliated_production_line": "Please select production line", + "length_2_to_20_characters": "Length must be 2-20 characters", + "add_member": "Add Member", + "member_name": "Member Name", + "is_team_leader": "Team Leader", + "yes": "Yes", + "no": "No", + "only_one_team_leader_allowed": "Only one team leader is allowed", + "operation_successful": "Operation successful", + "delete_team_confirm_message": "Are you sure to delete this team?", + "batch_delete_confirm_message": "Are you sure to delete selected teams?", + "please_select_table_data": "Please select table data first", + "export_confirm_message": "Export current query result?", + "download_task_created": "Download task created", + "operation_cancelled": "Operation cancelled", + "production_team_data_import": "Import Team Data", + "upload_file_alert_title": "Import using the template format", + "upload_file_alert_description": "Download the template before importing", + "production_team_data_import_table": "Team Import Table", + "select_file": "Select File", + "download_template": "Download Template", + "preview": "Preview", + "please_import_department_data": "Please import team data first", + "team_data_import_template": "Team Import Template", + "upload_format_error": "Please upload xls or xlsx file" + }, + "shift_management": { + "search": "Search", + "reset": "Reset", + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "batch_delete": "Batch Delete", + "import": "Import", + "export": "Export", + "confirm": "Confirm", + "cancel": "Cancel", + "prompt": "Notice", + "operation": "Operation", + "shift_plan_name": "Shift Plan Name", + "shift_plan_code": "Shift Plan Code", + "enter_shift_plan_name": "Please enter shift plan name", + "enter_shift_plan_code": "Please enter shift plan code", + "last_create_time": "Create Time", + "serial_number": "No.", + "start_time": "Start Time", + "end_time": "End Time", + "start_date": "Start Date", + "end_date": "End Date", + "status": "Status", + "enabled": "Enabled", + "disabled": "Disabled", + "creator": "Creator", + "create_time": "Created At", + "update_time": "Updated At", + "add_shift_plan": "Add Shift Plan", + "edit_shift_plan": "Edit Shift Plan", + "shift_name": "Shift Name", + "shift_code": "Shift Code", + "enter_shift_name": "Please enter shift name", + "enter_shift_code": "Please enter shift code", + "shift_time_range": "Shift Time Range", + "please_select_shift_time_range": "Please select shift time range", + "rotation_mode": "Rotation Mode", + "enter_content": "Please enter content", + "day": "Day", + "week": "Week", + "month": "Month", + "rest_day_setting": "Rest Days", + "monday": "Mon", + "tuesday": "Tue", + "wednesday": "Wed", + "thursday": "Thu", + "friday": "Fri", + "saturday": "Sat", + "sunday": "Sun", + "production_team": "Production Team", + "please_select": "Please select", + "remark": "Remark", + "enter_remark": "Please enter remark", + "add_shift": "Add Shift", + "shift_start_time": "Shift Start Time", + "shift_end_time": "Shift End Time", + "select_shift_start_time": "Please select shift start time", + "select_shift_end_time": "Please select shift end time", + "production_team_binding": "Team Binding", + "production_team_can_only_bind_one_shift": "One team can only bind one shift", + "please_enter_shift_plan_name": "Please enter shift plan name", + "please_enter_shift_plan_code": "Please enter shift plan code", + "please_enter_shift_name_row": "Please enter shift name, row: ", + "please_select_shift_start_time_row": "Please select shift start time, row: ", + "please_select_shift_end_time_row": "Please select shift end time, row: ", + "operation_successful": "Operation successful", + "delete_department_confirm_message": "Are you sure to delete this shift plan?", + "batch_delete_confirm_message": "Are you sure to delete selected shift plans?", + "please_select_table_data": "Please select table data first", + "export_confirm_message": "Export current query result?", + "download_task_created": "Download task created", + "shift_plan_data_import": "Import Shift Plan Data", + "upload_file_alert_title": "Import using the template format", + "upload_file_alert_description": "Download the template before importing", + "select_file": "Select File", + "download_template": "Download Template", + "please_import_department_data": "Please import shift plan data first", + "shift_plan_data_import_template": "Shift Plan Import Template", + "upload_format_error": "Please upload xls or xlsx file" + } , + "scheduling_calendar": { + "rest": "Rest", + "cross_day": "Cross Day" + } + + }, "spc_configuration": { "data_collection_configuration": { "search": "Search", @@ -2219,6 +2418,47 @@ "please_select": "Please select" } }, + "system_monitoring": { + "monitoring_configuration": { + "search": "Search", + "reset": "Reset", + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "confirm": "Confirm", + "cancel": "Cancel", + "prompt": "Notice", + "operation": "Operation", + "operation_success": "Operation successful", + "confirm_operation": "Are you sure you want to perform this operation?", + "serial_number": "No.", + "monitor_code": "Monitor Code", + "monitor_name": "Monitor Name", + "ip_address": "IP Address", + "port": "Port", + "python_version": "Python Version", + "refresh_interval": "Refresh Interval", + "cpu_warning": "CPU Warning", + "disk_warning": "Disk Warning", + "memory_swap_warning": "Memory/Swap Warning", + "enter_monitor_code": "Please enter monitor code", + "enter_monitor_name": "Please enter monitor name", + "enter_ip_address": "Please enter IP address", + "enter_port": "Please enter port", + "enter_refresh_interval": "Please enter refresh interval", + "enter_disk_warning": "Please enter disk warning", + "enter_cpu_warning": "Please enter CPU warning", + "enter_memory_swap_warning": "Please enter memory/swap warning", + "enter_python_version": "Please enter Python version", + "please_enter_monitor_code": "Please enter monitor code", + "please_enter_monitor_name": "Please enter monitor name", + "please_enter_ip_address": "Please enter IP address", + "please_enter_port": "Please enter port", + "length_1_to_100": "Length must be 1-100 characters", + "add_monitor_config": "Add Monitoring Configuration", + "edit_monitor_config": "Edit Monitoring Configuration" + } + }, "system_utilities": { "api_logs": { "id": "ID", diff --git a/src/locales/zh-chs.json b/src/locales/zh-chs.json index 2b51c94b..78c5def4 100644 --- a/src/locales/zh-chs.json +++ b/src/locales/zh-chs.json @@ -356,6 +356,55 @@ "please_enter": "请输入{name}", "help": "物料信息用于维护物料编码、名称、规格等属性" }, + "bill_of_materials": { + "query": "查询", + "reset": "重置", + "add": "新增", + "edit": "编辑", + "delete": "删除", + "set_bom": "设置BOM", + "operation": "操作", + "confirm": "确定", + "cancel": "取消", + "return": "返回", + "prompt": "提示", + "operation_success": "操作成功", + "confirm_message": "确定要执行该操作吗?", + "bom_version_code": "BOM版本编码", + "bom_version_name": "BOM版本名称", + "product_model_name": "型号名称", + "status": "状态", + "enable": "启用", + "disable": "禁用", + "select_status": "请选择状态", + "create_user": "创建人", + "create_time": "创建时间", + "remark": "备注", + "enter_remark": "请输入备注", + "enter_bom_version_code": "请输入BOM版本编码", + "enter_bom_version_name": "请输入BOM版本名称", + "select_product_model_name": "请选择型号名称", + "enter_bom_code": "请输入BOM编码", + "enter_bom_name": "请输入BOM名称", + "select_product_model": "请选择产品型号", + "length_1_45": "长度在 1 到 45 个字符", + "add_bom_info": "新增BOM信息", + "edit_bom_info": "编辑BOM信息", + "bom_management": "BOM管理", + "material_category": "物料类别", + "material_code": "物料编码", + "material_name": "物料名称", + "input_quantity": "投入数量", + "enter_input_quantity": "请输入投入数量", + "unit": "单位", + "select_add_material": "选择添加物料", + "all": "全部", + "selected": "已选", + "search_by_code_or_name": "按编码或名称搜索", + "duplicate_material_selected": "已选择物料请勿重复选择", + "out_only_one": "OUT结构只允许存在1个半成品,请勿选择1个以上半成品", + "please_select_data": "请先选择数据" + }, "material_unit": { "search": "查询", "reset": "重置", @@ -438,6 +487,156 @@ "help": "异常不良管理用于维护设备的异常种类和产品的不良种类信息" } }, + "team_model": { + "team_management": { + "search": "查询", + "reset": "重置", + "add": "新增", + "edit": "编辑", + "delete": "删除", + "batch_delete": "批量删除", + "import": "导入", + "export": "导出", + "confirm": "确定", + "cancel": "取消", + "prompt": "提示", + "operation": "操作", + "team_name": "班组名称", + "enter_team_name": "请输入班组名称", + "area": "厂区", + "select_area": "请选择厂区", + "production_line": "产线", + "select_area_then_line": "请先选择厂区再选择产线", + "last_create_time": "创建时间", + "select_create_time": "请选择创建时间", + "start_time": "开始时间", + "end_time": "结束时间", + "serial_number": "序号", + "affiliated_factory": "所属厂区", + "affiliated_production_line": "所属产线", + "create_time": "创建时间", + "update_time": "更新时间", + "add_team": "新增班组", + "edit_team": "编辑班组", + "please_select": "请选择", + "please_select_factory_then_line": "请先选择厂区再选择产线", + "select_affiliated_factory": "请选择所属厂区", + "select_affiliated_production_line": "请选择所属产线", + "please_enter_team_name": "请输入班组名称", + "please_select_affiliated_factory": "请选择所属厂区", + "please_select_affiliated_production_line": "请选择所属产线", + "length_2_to_20_characters": "长度在 2 到 20 个字符", + "add_member": "添加成员", + "member_name": "成员名称", + "is_team_leader": "是否班组长", + "yes": "是", + "no": "否", + "only_one_team_leader_allowed": "只允许设置一个班组长", + "operation_successful": "操作成功", + "delete_team_confirm_message": "确定要删除该班组吗?", + "batch_delete_confirm_message": "确定要删除所选班组吗?", + "please_select_table_data": "请先选择表格数据", + "export_confirm_message": "确定要导出当前查询结果吗?", + "download_task_created": "下载任务创建成功", + "operation_cancelled": "操作已取消", + "production_team_data_import": "班组数据导入", + "upload_file_alert_title": "请按模板格式导入文件", + "upload_file_alert_description": "导入前请先下载模板并按模板字段填写", + "production_team_data_import_table": "班组数据导入表", + "select_file": "选择文件", + "download_template": "下载模板", + "preview": "预览", + "please_import_department_data": "请先导入班组数据", + "team_data_import_template": "班组数据导入模板", + "upload_format_error": "请上传 xls 或 xlsx 文件" + }, + "shift_management": { + "search": "查询", + "reset": "重置", + "add": "新增", + "edit": "编辑", + "delete": "删除", + "batch_delete": "批量删除", + "import": "导入", + "export": "导出", + "confirm": "确定", + "cancel": "取消", + "prompt": "提示", + "operation": "操作", + "shift_plan_name": "班次计划名称", + "shift_plan_code": "班次计划编码", + "enter_shift_plan_name": "请输入班次计划名称", + "enter_shift_plan_code": "请输入班次计划编码", + "last_create_time": "创建时间", + "serial_number": "序号", + "start_time": "开始时间", + "end_time": "结束时间", + "start_date": "开始日期", + "end_date": "结束日期", + "status": "状态", + "enabled": "启用", + "disabled": "禁用", + "creator": "创建人", + "create_time": "创建时间", + "update_time": "更新时间", + "add_shift_plan": "新增班次计划", + "edit_shift_plan": "编辑班次计划", + "shift_name": "班次名称", + "shift_code": "班次编码", + "enter_shift_name": "请输入班次名称", + "enter_shift_code": "请输入班次编码", + "shift_time_range": "班次计划时间范围", + "please_select_shift_time_range": "请选择班次时间范围", + "rotation_mode": "轮转模式", + "enter_content": "请输入内容", + "day": "天", + "week": "周", + "month": "月", + "rest_day_setting": "休息日设置", + "monday": "周一", + "tuesday": "周二", + "wednesday": "周三", + "thursday": "周四", + "friday": "周五", + "saturday": "周六", + "sunday": "周日", + "production_team": "生产班组", + "please_select": "请选择", + "remark": "备注", + "enter_remark": "请输入备注", + "add_shift": "添加班次", + "shift_start_time": "班次开始时间", + "shift_end_time": "班次结束时间", + "select_shift_start_time": "请选择班次开始时间", + "select_shift_end_time": "请选择班次结束时间", + "production_team_binding": "生产班组绑定", + "production_team_can_only_bind_one_shift": "一个生产班组只能绑定一个班次", + "please_enter_shift_plan_name": "请输入班次计划名称", + "please_enter_shift_plan_code": "请输入班次计划编码", + "please_enter_shift_name_row": "请输入班次名称,行号:", + "please_select_shift_start_time_row": "请选择班次开始时间,行号:", + "please_select_shift_end_time_row": "请选择班次结束时间,行号:", + "operation_successful": "操作成功", + "delete_department_confirm_message": "确定要删除该班次计划吗?", + "batch_delete_confirm_message": "确定要删除所选班次计划吗?", + "please_select_table_data": "请先选择表格数据", + "export_confirm_message": "确定要导出当前查询结果吗?", + "download_task_created": "下载任务创建成功", + "shift_plan_data_import": "班次计划数据导入", + "upload_file_alert_title": "请按模板格式导入文件", + "upload_file_alert_description": "导入前请先下载模板并按模板字段填写", + "select_file": "选择文件", + "download_template": "下载模板", + "please_import_department_data": "请先导入班次计划数据", + "shift_plan_data_import_template": "班次计划数据导入模板", + "upload_format_error": "请上传 xls 或 xlsx 文件" + } , + "scheduling_calendar": { + "rest": "休", + "cross_day": "跨天" + } + + }, "spc_configuration": { "data_collection_configuration": { "search": "查询", @@ -2219,6 +2418,47 @@ "please_select": "请选择" } }, + "system_monitoring": { + "monitoring_configuration": { + "search": "查询", + "reset": "重置", + "add": "新增", + "edit": "编辑", + "delete": "删除", + "confirm": "确定", + "cancel": "取消", + "prompt": "提示", + "operation": "操作", + "operation_success": "操作成功", + "confirm_operation": "确定要执行该操作吗?", + "serial_number": "序号", + "monitor_code": "监控编码", + "monitor_name": "监控名称", + "ip_address": "IP地址", + "port": "端口", + "python_version": "Python版本", + "refresh_interval": "刷新间隔", + "cpu_warning": "CPU预警值", + "disk_warning": "磁盘预警值", + "memory_swap_warning": "内存/交换区预警值", + "enter_monitor_code": "请输入监控编码", + "enter_monitor_name": "请输入监控名称", + "enter_ip_address": "请输入IP地址", + "enter_port": "请输入端口", + "enter_refresh_interval": "请输入刷新间隔", + "enter_disk_warning": "请输入磁盘预警值", + "enter_cpu_warning": "请输入CPU预警值", + "enter_memory_swap_warning": "请输入内存/交换区预警值", + "enter_python_version": "请输入Python版本", + "please_enter_monitor_code": "请输入监控编码", + "please_enter_monitor_name": "请输入监控名称", + "please_enter_ip_address": "请输入IP地址", + "please_enter_port": "请输入端口", + "length_1_to_100": "长度在 1 到 100 个字符", + "add_monitor_config": "新增监控配置", + "edit_monitor_config": "编辑监控配置" + } + }, "system_utilities": { "api_logs": { "id": "ID", diff --git a/src/router/modules/production-master-data.js b/src/router/modules/production-master-data.js index 3d2e35a1..36b3a069 100644 --- a/src/router/modules/production-master-data.js +++ b/src/router/modules/production-master-data.js @@ -68,6 +68,12 @@ export default { meta: { ...meta, cache: true, title: '物料信息管理' }, component: _import('production-master-data/material-model/material-master') }, + { + path: 'matetial_model/bom', + name: `${pre}material_model-bill_of_materials`, + meta: { ...meta, cache: true, title: 'BOM物料清单' }, + component: _import('production-master-data/material-model/bill-of-materials') + }, { path: 'matetial_model/unit', name: `${pre}material_model-material_unit`, diff --git a/src/router/modules/system-administration.js b/src/router/modules/system-administration.js index c52ed664..b8f5380d 100644 --- a/src/router/modules/system-administration.js +++ b/src/router/modules/system-administration.js @@ -49,6 +49,30 @@ export default { name: `${pre}system_assistant-problem_help`, meta: { ...meta, cache: true, title: '问题帮助' }, component: _import('system-administration/system-utilities/problem-help') + }, + { + path: 'system_monitoring/setting', + name: `${pre}system_monitoring-setting`, + meta: { ...meta, cache: true, title: '监控设置' }, + component: _import('system-administration/system-monitoring/monitoring-configuration') + }, + { + path: 'organization/production_team_manage', + name: `${pre}organization-production_team_manage`, + meta: { ...meta, cache: true, title: '班组管理' }, + component: _import('production-master-data/team-model/team-management') + }, + { + path: 'organization/production_shift_management', + name: `${pre}organization-production_shift_management`, + meta: { ...meta, cache: true, title: '班次管理' }, + component: _import('production-master-data/team-model/shift-management') + }, + { + path: 'organization/production_shift_calender', + name: `${pre}organization-production_shift_calender`, + meta: { ...meta, cache: true, title: '排班日历' }, + component: _import('production-master-data/team-model/scheduling-calendar') } ])('system_settings-') } diff --git a/src/views/production-master-data/material-model/bill-of-materials/components/BomRelationship/index.vue b/src/views/production-master-data/material-model/bill-of-materials/components/BomRelationship/index.vue new file mode 100644 index 00000000..babb2e2f --- /dev/null +++ b/src/views/production-master-data/material-model/bill-of-materials/components/BomRelationship/index.vue @@ -0,0 +1,282 @@ + + + + + diff --git a/src/views/production-master-data/material-model/bill-of-materials/index.vue b/src/views/production-master-data/material-model/bill-of-materials/index.vue new file mode 100644 index 00000000..da238659 --- /dev/null +++ b/src/views/production-master-data/material-model/bill-of-materials/index.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/src/views/production-master-data/team-model/scheduling-calendar/index.vue b/src/views/production-master-data/team-model/scheduling-calendar/index.vue new file mode 100644 index 00000000..842f5519 --- /dev/null +++ b/src/views/production-master-data/team-model/scheduling-calendar/index.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/src/views/production-master-data/team-model/shift-management/index.vue b/src/views/production-master-data/team-model/shift-management/index.vue new file mode 100644 index 00000000..cac53884 --- /dev/null +++ b/src/views/production-master-data/team-model/shift-management/index.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/src/views/production-master-data/team-model/team-management/index.vue b/src/views/production-master-data/team-model/team-management/index.vue index 37f7843a..1371e0bd 100644 --- a/src/views/production-master-data/team-model/team-management/index.vue +++ b/src/views/production-master-data/team-model/team-management/index.vue @@ -4,298 +4,88 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - {{ $t(key('team_members')) }} - - - {{ $t(key('add_member')) }} - - - - + + {{ $t(key('add_member')) }} + + - + - - + + - - - - - + + {{ $t(key('cancel')) }} + {{ $t(key('confirm')) }} + - - - - - - - - - {{ $t(key('select_file')) }} - - - {{ $t(key('download_template')) }} - - - - - - - - - - - - - - + + + + {{ $t(key('select_file')) }} + {{ $t(key('download_template')) }} + + + + + + + + + + {{ $t(key('cancel')) }} + {{ $t(key('confirm')) }} + - @@ -304,20 +94,19 @@ import { useTableColumns } from '@/composables/useTableColumns' import { useTableButtons } from '@/composables/useTableButtons' import { i18nMixin } from '@/composables/useI18n' import { confirmMixin } from '@/composables/useConfirmHandle' -import { - getTeamManagementList, - createTeamManagement, - editTeamManagement, - deleteTeamManagement, - getTeamManagementALL, - getImportTemplate, - importTeamManagement, - exportTeamManagementTask -} from '@/api/production-master-data/team-management' +import PageTable from '@/components/page-table' import { getFactoryAreaALL } from '@/api/production-master-data/factory-area' import { getProductionLineList } from '@/api/production-master-data/production-line' -import { getUserAll } from '@/api/system-administration/user' -import PageTable from '@/components/page-table' +import { getUserList } from '@/api/system-administration/user' +import { downloadRename, readExcel } from '@/utils/file' +import { getTeamList, createTeam, editTeam, deleteTeam, getTeamImportTemplate, importTeamData, exportTeamTask, getTeamMemberList, deleteTeamMember } from '@/api/production-master-data/team-management' + +function readPageData (res) { + const data = res && res.data ? res.data : res + if (!data) return { list: [], total: 0 } + if (Array.isArray(data)) return { list: data, total: data.length } + return { list: data.data || data.list || [], total: Number(data.count || data.total || 0) } +} export default { name: 'production-master-data-team-management', @@ -329,104 +118,62 @@ export default { submitting: false, tableData: [], selectedRows: [], - dialogVisible: false, - importDialogVisible: false, - dialogTitle: '', - editId: '', - handleType: 'create', - search: { name: '', area_id: '', line_id: '', create_time: '' }, - pagination: { current: 1, size: 10, total: 0 }, - areaOptions: [], - lineOptions: [], - userOptions: [], - formData: { name: '', area_id: '', line_id: '', user_id: '' }, - membersData: [], - membersForm: { - members_user_id: undefined, - is_main: '1' - }, - rules: { - name: [ - { required: true, message: this.key('please_enter_team_name'), trigger: 'blur' }, - { min: 2, max: 20, message: this.key('length_2_to_20_characters'), trigger: 'blur' } - ], - area_id: [ - { required: true, message: this.key('please_select_affiliated_factory'), trigger: 'change' } - ], - line_id: [ - { required: true, message: this.key('please_select_affiliated_production_line'), trigger: 'change' } - ] - }, columns: [], toolbarButtons: [], rowButtons: [], + search: { name: '', area_id: '', line_id: '', create_time: '' }, + pagination: { current: 1, size: 10, total: 0 }, + areaOptions: [], + searchLineOptions: [], + formLineOptions: [], + userOptions: [], + dialogVisible: false, + dialogTitle: '', + handleType: 'create', + editId: '', + leaderIndex: undefined, + formData: { name: '', area_id: '', line_id: '' }, + membersData: [], + importVisible: false, importFileList: [], - importPreviewData: [], - importTableLoading: false, + importRows: [], importLoading: false, - pagination: { - total: 0, - pageSize: 8, - currentPage: 1, + importTableLoading: false, + rules: { + name: [{ required: true, message: this.key('please_enter_team_name'), trigger: 'blur' }, { min: 2, max: 20, message: this.key('length_2_to_20_characters'), trigger: 'blur' }], + area_id: [{ required: true, message: this.key('please_select_affiliated_factory'), trigger: 'change' }], + line_id: [{ required: true, message: this.key('please_select_affiliated_production_line'), trigger: 'change' }] } } }, + computed: { + translatedRules () { + const next = {} + Object.keys(this.rules).forEach(key => { next[key] = this.rules[key].map(rule => ({ ...rule, message: this.$t(rule.message) })) }) + return next + } + }, created () { - this.initAreaOptions() - this.initUserOptions() + this.initOptions() this.columns = useTableColumns([ { prop: 'sort', label: this.key('serial_number'), width: 80 }, - { prop: 'name', label: this.key('team_name'), minWidth: 120 }, - { prop: 'area_name', label: this.key('affiliated_factory'), minWidth: 120 }, - { prop: 'line_name', label: this.key('affiliated_production_line'), minWidth: 120 }, - { prop: 'create_time', label: this.key('create_time'), width: 160 }, - { prop: 'update_time', label: this.key('update_time'), width: 160 }, - { prop: '_actions', label: this.key('operation'), width: 250, fixed: 'right' } + { prop: 'name', label: this.key('team_name'), minWidth: 140 }, + { prop: 'area_name', label: this.key('affiliated_factory'), minWidth: 140 }, + { prop: 'line_name', label: this.key('affiliated_production_line'), minWidth: 160 }, + { prop: 'create_time', label: this.key('create_time'), minWidth: 160 }, + { prop: 'update_time', label: this.key('update_time'), minWidth: 160 }, + { prop: '_actions', label: this.key('operation'), width: 180, fixed: 'right' } ]) const btns = useTableButtons({ toolbar: [ - { - key: 'add', - label: this.key('add'), - icon: 'el-icon-plus', - type: 'primary', - auth: '/system_settings/organization/production_team_manage/create', - onClick: this.openAdd - }, - { - key: 'batch_delete', - label: this.key('batch_delete'), - icon: 'el-icon-delete', - type: 'danger', - auth: '/system_settings/organization/production_team_manage/batch-delete', - onClick: this.handleBatchDelete - }, - { - key: 'import', - label: this.key('import'), - icon: 'el-icon-upload2', - type: '', - style: { background: '#3CBA92', color: '#FFFFFF' }, - auth: '/system_settings/organization/production_team_manage/import', - onClick: this.openImport - } + { key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/system_settings/organization/production_team_manage/create', onClick: this.openAdd }, + { key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/system_settings/organization/production_team_manage/batch-delete', needSelection: true, onClick: this.handleBatchDelete }, + { key: 'import', label: this.key('import'), icon: 'el-icon-upload2', type: 'success', auth: '/system_settings/organization/production_team_manage/import', onClick: this.openImport }, + { key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/system_settings/organization/production_team_manage/export', onClick: this.handleExport } ], row: [ - { - key: 'edit', - label: this.key('edit'), - icon: 'el-icon-edit', - auth: '/system_settings/organization/production_team_manage/edit', - onClick: this.openEdit - }, - { - key: 'delete', - label: this.key('delete'), - icon: 'el-icon-delete', - color: 'danger', - auth: '/system_settings/organization/production_team_manage/delete', - onClick: this.handleDelete - } + { key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/system_settings/organization/production_team_manage/edit', onClick: this.openEdit }, + { key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/system_settings/organization/production_team_manage/delete', onClick: this.handleDelete } ] }, this.$permission) this.toolbarButtons = btns.toolbarButtons @@ -434,284 +181,107 @@ export default { this.fetchData() }, methods: { + async initOptions () { + const [areas, users] = await Promise.all([getFactoryAreaALL({}), getUserList({ page_no: 1, page_size: 10000 })]) + this.areaOptions = ((areas && areas.data) || areas || []).map(item => ({ label: item.name, value: item.area_id || item.id })) + const userPage = readPageData(users) + this.userOptions = userPage.list.map(item => ({ label: item.nickname || item.name || item.username, value: item.user_id || item.id })) + }, + async loadLines (areaId, target) { + if (!areaId) { this[target] = []; return } + const res = await getProductionLineList({ area_id: areaId, page_no: 1, page_size: 10000 }) + const { list } = readPageData(res) + this[target] = list.map(item => ({ label: item.name, value: item.id })) + }, + onSearchAreaChange (areaId) { this.search.line_id = ''; this.loadLines(areaId, 'searchLineOptions') }, + onFormAreaChange (areaId) { this.formData.line_id = ''; this.loadLines(areaId, 'formLineOptions') }, async fetchData () { this.loading = true try { - const res = await getTeamManagementList({ - ...this.search, - page_no: this.pagination.current, - page_size: this.pagination.size - }) - const list = Array.isArray(res) ? res : (res.data?.data || []) - const total = Array.isArray(res) ? res.length : (res.data?.count || 0) + const res = await getTeamList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size }) + const { list, total } = readPageData(res) this.tableData = list this.pagination.total = total - } finally { - this.loading = false - } - }, - async initAreaOptions () { - try { - const res = await getFactoryAreaALL() - const data = Array.isArray(res) ? res : (res.data || []) - this.areaOptions = data.map(item => ({ value: item.area_id || item.id, label: item.name })) - } catch { /* 忽略加载失败 */ } - }, - async initUserOptions () { - try { - const res = await getUserAll() - const data = Array.isArray(res) ? res : (res.data || []) - this.userOptions = data.map(item => ({ value: item.user_id || item.id, label: item.nickname || item.username })) - } catch { /* 忽略加载失败 */ } - }, - async loadLineOptionsByArea(areaId) { - if (!areaId) { - this.lineOptions = [] - return - } - try { - const res = await getProductionLineList({ area_id: areaId, page_no: 1, page_size: 1000 }) - const data = Array.isArray(res) ? res : (res.data?.data || []) - this.lineOptions = data.map(item => ({ value: item.id, label: item.name })) - } catch { /* 忽略加载失败 */ } - }, - onSearch () { - this.pagination.current = 1 - this.fetchData() - }, - onReset () { - this.search = { name: '', area_id: '', line_id: '', create_time: '' } - this.lineOptions = [] - this.pagination.current = 1 - this.fetchData() - }, - onAreaChange(value) { - this.search.line_id = '' // 清空产线选择 - this.loadLineOptionsByArea(value) - }, - onPageChange (page) { - this.pagination.current = page.current - this.pagination.size = page.size - this.fetchData() - }, - onSelect (rows) { - this.selectedRows = rows - }, - resetForm () { - this.formData = { name: '', area_id: '', line_id: '', user_id: '' } - this.membersData = [] - this.editId = '' - }, - async openAdd () { - this.handleType = 'create' - this.dialogTitle = this.key('add_team') - await this.$nextTick() - this.resetForm() - this.dialogVisible = true + } finally { this.loading = false } }, + onSearch () { this.pagination.current = 1; this.fetchData() }, + onReset () { this.search = { name: '', area_id: '', line_id: '', create_time: '' }; this.searchLineOptions = []; this.pagination.current = 1; this.fetchData() }, + onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() }, + openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_team'); this.dialogVisible = true }, async openEdit (row) { - this.handleType = 'edit' - this.dialogTitle = this.key('edit_team') - this.editId = row.id - this.formData = { - name: row.name, - area_id: row.area_id, - line_id: row.line_id - } - // 加载产线选项 - await this.loadLineOptionsByArea(row.area_id) - // 加载成员数据 - this.membersData = row.members || [] - await this.$nextTick() + this.handleType = 'edit'; this.dialogTitle = this.key('edit_team'); this.editId = row.id + this.formData = { name: row.name, area_id: row.area_id, line_id: row.line_id } + await this.loadLines(row.area_id, 'formLineOptions') + const res = await getTeamMemberList({ production_team_id: row.id, page_no: 1, page_size: 10000 }) + const { list } = readPageData(res) + this.membersData = list.map(item => ({ ...item, is_main: Number(item.is_main) })) + this.leaderIndex = this.membersData.findIndex(item => Number(item.is_main) === 1) + if (this.leaderIndex < 0) this.leaderIndex = undefined this.dialogVisible = true }, - async onDialogSubmit () { - this.submitting = true - try { - const submitData = { - ...this.formData, - members: this.membersData - } - if (this.handleType === 'create') { - await createTeamManagement(submitData) - } else { - await editTeamManagement({ ...submitData, id: this.editId }) - } - this.$message.success(this.$t(this.key('operation_success'))) - this.dialogVisible = false - this.fetchData() - } finally { - this.submitting = false - } + addMember () { this.membersData.push({ user_id: '', is_main: 0 }) }, + onLeaderChange (val, index) { + if (Number(val) === 1 && this.leaderIndex !== undefined && this.leaderIndex !== index) { + this.$message.error(this.$t(this.key('only_one_team_leader_allowed'))) + this.membersData[index].is_main = 0 + } else if (this.leaderIndex === index && Number(val) === 0) this.leaderIndex = undefined + else if (Number(val) === 1) this.leaderIndex = index }, - handleDialogClose () { - this.resetForm() - this.dialogVisible = false - }, - async handleDelete (row) { - const cancelled = await this.$confirmAction( - { - message: this.key('confirm_delete'), - title: this.key('tip') - }, - () => deleteTeamManagement({ id: [row.id] }) - ) - if (cancelled) return - this.$message.success(this.$t(this.key('operation_success'))) - this.pagination.current = Math.min( - this.pagination.current, - Math.ceil((this.pagination.total - 1) / this.pagination.size) || 1 - ) - this.fetchData() - }, - handleBatchDelete () { - if (this.selectedRows.length === 0) { - this.$message.warning(this.$t(this.key('select_rows_first'))) - return - } - this.$confirm(this.$t(this.key('confirm_batch_delete')), this.$t(this.key('tip')), { - confirmButtonText: this.$t(this.key('confirm')), - cancelButtonText: this.$t(this.key('cancel')), - type: 'warning' - }).then(async () => { - const ids = this.selectedRows.map(row => row.id) - await deleteTeamManagement({ id: ids }) - this.$message.success(this.$t(this.key('operation_success'))) - this.fetchData() - }).catch(() => {}) - }, - openImport() { - this.importFileList = [] - this.importPreviewData = [] - this.importDialogVisible = true - }, - handleImportDialogClose() { - this.importDialogVisible = false - this.importFileList = [] - this.importPreviewData = [] - }, - handleFileUpload(file, fileList) { - this.importFileList = fileList.slice(-1) // 只保留最后一个文件 - }, - async handleDownloadTemplate() { - try { - const res = await getImportTemplate({}) - // 创建下载链接 - const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) - const url = window.URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = 'team_management_import_template.xlsx' - a.click() - window.URL.revokeObjectURL(url) - } catch (error) { - this.$message.error(this.$t(this.key('download_template_failed'))) - } - }, - async handleStartImport() { - if (this.importFileList.length === 0) { - this.$message.warning(this.$t(this.key('please_select_file'))) - return - } - - this.importLoading = true - try { - const file = this.importFileList[0].raw || this.importFileList[0] - const formData = new FormData() - formData.append('file', file) - - await importTeamManagement(formData) - this.$message.success(this.$t(this.key('import_success'))) - this.importDialogVisible = false - this.fetchData() - } catch (error) { - this.$message.error(this.$t(this.key('import_failed'))) - } finally { - this.importLoading = false - } - }, - async handleExportCommand(command) { - if (command === 'export') { - // 直接导出 - try { - const res = await exportTeamManagementTask({...this.search, action: 'download'}) - // 创建下载链接 - const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) - const url = window.URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = 'team_management_export.xlsx' - a.click() - window.URL.revokeObjectURL(url) - } catch (error) { - this.$message.error(this.$t(this.key('export_failed'))) - } - } else if (command === 'export_task') { - // 创建下载任务 - try { - await exportTeamManagementTask({...this.search, action: 'task'}) - this.$message.success(this.$t(this.key('download_task_created'))) - // 跳转到下载任务页面 - this.$router.push({ name: 'task' }) - } catch (error) { - this.$message.error(this.$t(this.key('create_download_task_failed'))) - } - } - }, - // 以下是成员管理相关方法 - areaDataChange(value) { - this.loadLineOptionsByArea(value) - }, - handleTeamAddMembers() { - // 添加一个新的成员行 - this.membersData.push({ - user_id: null, - is_main: 0 - }) - }, - handleMembersDelete(row, index) { + async deleteMember (row, index) { + if (row.id) { await deleteTeamMember({ id: [row.id] }); this.$message.success(this.$t(this.key('operation_successful'))) } this.membersData.splice(index, 1) }, - is_main_change(val, index) { - // 确保只有一个主负责人 - if (val === 1) { - this.membersData.forEach((item, idx) => { - if (idx !== index) { - item.is_main = 0 - } - }) - } - }, - handleSizeChange(val) { - this.pagination.pageSize = val - this.fetchData() - }, - handleCurrentChange(val) { - this.pagination.currentPage = val - this.fetchData() - }, - handleSubmitDialogMembersAdd() { - // 验证表单 - this.$refs.teamForm.validate((valid) => { - if (valid) { - this.onDialogSubmit() - } else { - this.$message.error(this.$t(this.key('validation_failed'))) - } + submitDialog () { + this.$refs.form.validate(async valid => { + if (!valid) return + this.submitting = true + try { + const payload = { ...this.formData, membersData: this.membersData } + if (this.handleType === 'create') await createTeam(payload) + else await editTeam({ ...payload, id: this.editId }) + this.$message.success(this.$t(this.key('operation_successful'))) + this.closeDialog(); this.fetchData() + } finally { this.submitting = false } }) + }, + closeDialog () { this.dialogVisible = false; this.formData = { name: '', area_id: '', line_id: '' }; this.membersData = []; this.formLineOptions = []; this.leaderIndex = undefined; this.editId = '' }, + async handleDelete (row) { + const cancelled = await this.$confirmAction({ message: this.key('delete_team_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteTeam({ id: [row.id] })) + if (cancelled) return + this.$message.success(this.$t(this.key('operation_successful'))); this.fetchData() + }, + async handleBatchDelete () { + if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_table_data'))); return } + const cancelled = await this.$confirmAction({ message: this.key('batch_delete_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteTeam({ id: this.selectedRows.map(item => item.id) })) + if (cancelled) return + this.$message.success(this.$t(this.key('operation_successful'))); this.fetchData() + }, + openImport () { this.importFileList = []; this.importRows = []; this.importVisible = true }, + async downloadTemplate () { this.importLoading = true; try { const res = await getTeamImportTemplate({}); downloadRename(res, 'xlsx', this.$t(this.key('team_data_import_template'))) } finally { this.importLoading = false } }, + async onImportFileChange (file) { + if (!file || !/\.(xls|xlsx)$/i.test(file.name)) { this.$message.error(this.$t(this.key('upload_format_error'))); return } + this.importFileList = [file] + this.importTableLoading = true + try { + const rows = await readExcel(file.raw) + this.importRows = rows.map(row => ({ name: row['班组名称'], area_name: row['所属厂区'], line_name: row['所属产线'], members_user_name: row['成员名称'], is_main: row['是否班组组长'] })) + } finally { this.importTableLoading = false } + }, + async submitImport () { + if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_department_data'))); return } + await importTeamData({ import_data: JSON.stringify(this.importRows) }) + this.$message.success(this.$t(this.key('operation_successful'))); this.importVisible = false; this.fetchData() + }, + async handleExport () { + const cancelled = await this.$confirmAction({ message: this.key('export_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => exportTeamTask({ ...this.search, action: 'download' })) + if (cancelled) return + this.$message.success(this.$t(this.key('download_task_created'))) } } } \ No newline at end of file +.search-bar { padding: 10px 0; } +/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; } + diff --git a/src/views/system-administration/system-monitoring/monitoring-configuration/index.vue b/src/views/system-administration/system-monitoring/monitoring-configuration/index.vue new file mode 100644 index 00000000..23881d08 --- /dev/null +++ b/src/views/system-administration/system-monitoring/monitoring-configuration/index.vue @@ -0,0 +1,194 @@ + + + + +