# 报工单页面类别与字段控制设计文档 **版本:** v2.0.003 **日期:** 2026-03-05 **负责人:** 周启威 --- ## 需求整理 ### 原始需求 1. **报工单中分了 ABCDE 五类**,能否在新增/编辑的时候把五类中任一一类停用,然后写一个配置表、页面上一个按钮可以控制五个类别的停用与启用 2. **报工单中分了 ABCDE 五类**,在这五类中的字段命名/增删改查能不能也放入配置表,五类中的字段也需要控制与自定义,现在目前程序中现有的字段也需要控制与自定义了 3. **规则**:停用/启用 对应的是 隐藏/显示,只要是停用就隐藏该字段 4. **数据类型也需要自定义**,然后控件类型也需要自定义 5. **分类也可以自己增加并修改**,我新增的自定义字段应该可以指定进入任一分类中 6. **ABCDE 的话还是自动排吧**,比如我 C 停用了,应该 D→C, E→D,默认是这样的,但是也可以自定义 ### 需求总结 #### 一、类别管理需求 1. **系统类别(A/B/C/D/E)**: - 可以停用/启用(停用=隐藏) - 可以修改类别名称 - 不可删除 - 支持名称重置为默认值 2. **自定义类别(F/G/H...)**: - 可以新增自定义类别 - 可以修改类别名称 - 可以删除(删除前需确认该类别下无字段) - 可以停用/启用 3. **类别排序**: - 支持手动调整排序(拖拽或上下移动) - 前端显示时,启用的类别自动重新编号为 A、B、C、D... - 例如:C 停用后,D 自动显示为 C,E 自动显示为 D #### 二、字段管理需求 1. **系统字段(现有字段)**: - 可以停用/启用(停用=隐藏) - 可以修改显示名称(如"报工人"改为"操作员") - 可以修改控件类型 - 不可删除 - 支持名称重置为默认值 2. **自定义字段(新增字段)**: - 可以新增自定义字段 - 可以配置字段名称、数据类型、控件类型 - 可以选择放入任一类别中(包括自定义类别) - 可以移动到其他类别 - 可以删除 - 可以停用/启用 3. **字段配置项**: - 字段名称(可自定义) - 数据类型(STRING/NUMBER/DATE/DATETIME/BOOLEAN/SELECT) - 控件类型(INPUT/NUMBER/DATE/DATETIME/SELECT/TEXTAREA/SWITCH) - 下拉选项(SELECT 类型时配置) - 是否必填 - 排序 #### 三、数据存储需求 1. **系统字段**:存储在 `pro_report` 表对应列中 2. **自定义字段**:存储在 `pro_report.custom_fields` JSON 字段中 #### 四、显示规则 1. **停用=隐藏**:停用的类别和字段在表单中完全隐藏 2. **启用=显示**:启用的类别和字段在表单中显示 3. **自动编号**:前端显示时,启用的类别自动重新编号为 A、B、C、D... --- ## 一、需求背景 报工单表单中分为五类(A-基础信息、B-数量信息、C-时间节拍、D-成本效益、E-异常记录),需要实现: 1. **类别控制**: - 能够在配置中停用/启用任一类别,停用后该类别在新增/编辑时隐藏 - 支持新增自定义类别(如 F、G、H 等) - 支持修改类别名称(如将"基础信息"改为"基本信息") - 系统类别(A/B/C/D/E)不可删除,只能停用;自定义类别可删除 2. **字段控制**:五类中的字段能够单独控制停用/启用(隐藏/显示) 3. **字段自定义**: - 现有字段可以自定义显示名称(改名),例如将"报工人"改为"操作员" - 支持新增自定义字段,可配置字段名称、数据类型、控件类型 - **新增自定义字段时可以选择放入任一类别中(包括自定义类别)** - 自定义字段的值存储在 JSON 扩展字段中 4. **规则**:停用=隐藏,启用=显示 --- ## 二、设计方案 ### 2.1 数据库设计 #### 2.1.1 类别配置表(pro_report_category_config) 存储系统类别和自定义类别的配置 | 字段名 | 类型 | 说明 | |--------|------|------| | id | bigint | 主键ID | | category_code | varchar(50) | 类别编码(A/B/C/D/E 为系统类别,F/G/H... 为自定义类别) | | category_name | varchar(100) | 类别名称(可自定义修改) | | default_category_name | varchar(100) | 默认类别名称(系统初始名称,用于重置) | | category_type | varchar(20) | 类别类型(SYSTEM=系统类别/CUSTOM=自定义类别) | | is_enabled | char(1) | 是否启用(Y=启用/N=停用),默认Y | | sort_order | int | 排序号 | | remark | varchar(500) | 备注 | | create_by | varchar(64) | 创建者 | | create_time | datetime | 创建时间 | | update_by | varchar(64) | 更新者 | | update_time | datetime | 更新时间 | #### 2.1.2 字段配置表(pro_report_field_config) 存储每个类别下字段的启用/停用状态、自定义显示名称、数据类型和控件类型 | 字段名 | 类型 | 说明 | |--------|------|------| | id | bigint | 主键ID | | category_code | varchar(50) | 所属类别编码(A/B/C/D/E) | | field_code | varchar(100) | 字段编码(对应实体类字段名或自定义字段唯一标识,不可修改) | | field_name | varchar(100) | 字段显示名称(可自定义修改,如"报工人"可改为"操作员") | | default_field_name | varchar(100) | 默认字段名称(系统初始名称,用于重置) | | field_type | varchar(20) | 字段类型(SYSTEM=系统字段/CUSTOM=自定义字段) | | data_type | varchar(50) | 数据类型(STRING=文本/NUMBER=数字/DATE=日期/DATETIME=日期时间/BOOLEAN=布尔/SELECT=下拉选择) | | control_type | varchar(50) | 控件类型(INPUT=文本框/NUMBER=数字框/DATE=日期选择/DATETIME=日期时间选择/SELECT=下拉框/TEXTAREA=文本域/SWITCH=开关) | | options | text | 下拉选项(JSON格式,仅当control_type=SELECT时有效,如:[{"label":"选项1","value":"1"}]) | | is_enabled | char(1) | 是否启用(Y=启用/N=停用),默认Y | | is_required | char(1) | 是否必填(Y=必填/N=非必填),默认N | | sort_order | int | 排序号 | | remark | varchar(500) | 备注 | | create_by | varchar(64) | 创建者 | | create_time | datetime | 创建时间 | | update_by | varchar(64) | 更新者 | | update_time | datetime | 更新时间 | ### 2.2 字段清单 #### A. 基础信息(category_code='A') | field_code | field_name | field_type | data_type | control_type | is_required | 说明 | |------------|------------|------------|-----------|--------------|-------------|------| | reportUserId | 报工人 | SYSTEM | NUMBER | SELECT | Y | 系统字段,必填 | | reportTime | 报工时间 | SYSTEM | DATETIME | DATETIME | Y | 系统字段,必填 | | reportType | 报工类型 | SYSTEM | STRING | SELECT | N | 系统字段,字典 | | shiftName | 班次 | SYSTEM | STRING | SELECT | N | 系统字段,字典 | | teamName | 班组 | SYSTEM | STRING | SELECT | N | 系统字段,字典 | | executionStandard | 执行标准 | SYSTEM | STRING | INPUT | N | 系统字段 | | workshopId | 车间 | SYSTEM | NUMBER | SELECT | Y | 系统字段,必填 | | stationId | 工位 | SYSTEM | NUMBER | SELECT | Y | 系统字段,必填 | #### B. 数量信息(category_code='B') | field_code | field_name | field_type | data_type | control_type | is_required | 说明 | |------------|------------|------------|-----------|--------------|-------------|------| | planCount | 计划数 | SYSTEM | NUMBER | INPUT | N | 系统字段,只读 | | reportQuantity | 报工数量 | SYSTEM | NUMBER | NUMBER | Y | 系统字段,必填 | | qualifiedQuantity | 合格数量 | SYSTEM | NUMBER | NUMBER | Y | 系统字段,必填 | | unqualifiedQuantity | 不合格数量 | SYSTEM | NUMBER | INPUT | N | 系统字段,自动计算 | | yieldRate | 良品率 | SYSTEM | NUMBER | INPUT | N | 系统字段,自动计算 | #### C. 时间节拍(category_code='C') | field_code | field_name | field_type | data_type | control_type | is_required | 说明 | |------------|------------|------------|-----------|--------------|-------------|------| | planStartTime | 计划开始时间 | SYSTEM | DATETIME | INPUT | N | 系统字段,只读 | | planEndTime | 计划完工时间 | SYSTEM | DATETIME | DATETIME | N | 系统字段 | | actualStartTime | 实际开始时间 | SYSTEM | DATETIME | DATETIME | N | 系统字段 | | actualEndTime | 实际完工时间 | SYSTEM | DATETIME | DATETIME | N | 系统字段 | | theoreticalCycleTime | 理论节拍 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | downtimeMinutes | 停机时间 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | downtimeReason | 停机原因 | SYSTEM | STRING | INPUT | N | 系统字段 | #### D. 成本效益(category_code='D') | field_code | field_name | field_type | data_type | control_type | is_required | 说明 | |------------|------------|------------|-----------|--------------|-------------|------| | performanceWages | 绩效工资 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | energyConsumption | 能耗 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | materialConsumption | 工耗 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | otherCosts | 其他成本 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | valueAdded | 增值 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | stationOee | 工位OEE | SYSTEM | NUMBER | NUMBER | N | 系统字段 | | currentBenefit | 本次效益 | SYSTEM | NUMBER | INPUT | N | 系统字段,自动计算 | | isSettle | 是否结算工资 | SYSTEM | STRING | SELECT | N | 系统字段,字典 | | wages | 结算工资 | SYSTEM | NUMBER | NUMBER | N | 系统字段 | #### E. 异常记录(category_code='E') | field_code | field_name | field_type | data_type | control_type | is_required | 说明 | |------------|------------|------------|-----------|--------------|-------------|------| | stationException | 工位异常情况 | SYSTEM | STRING | TEXTAREA | N | 系统字段 | | rectificationSuggestion | 整改建议 | SYSTEM | STRING | TEXTAREA | N | 系统字段 | | remark | 备注 | SYSTEM | STRING | TEXTAREA | N | 系统字段 | --- ### 2.3 自定义字段存储方案 #### 2.3.1 存储位置 自定义字段的值存储在 `pro_report` 表的 `custom_fields` 字段中(JSON 类型)。 ```sql ALTER TABLE `pro_report` ADD COLUMN `custom_fields` json DEFAULT NULL COMMENT '自定义字段值(JSON格式)'; ``` #### 2.3.2 存储格式 ```json { "custom_field_001": "自定义文本值", "custom_field_002": 123.45, "custom_field_003": "2026-03-05 10:30:00", "custom_field_004": true } ``` #### 2.3.3 字段编码规则 - 系统字段:使用实体类字段名(如 `reportUserId`) - 自定义字段:使用 `custom_field_` + 序号(如 `custom_field_001`) #### 2.3.4 数据类型映射 | data_type | 存储格式 | 示例 | |-----------|---------|------| | STRING | 字符串 | "文本内容" | | NUMBER | 数字 | 123.45 | | DATE | 字符串(yyyy-MM-dd) | "2026-03-05" | | DATETIME | 字符串(yyyy-MM-dd HH:mm:ss) | "2026-03-05 10:30:00" | | BOOLEAN | 布尔值 | true / false | | SELECT | 字符串(选项值) | "option1" | #### 2.3.5 字段保存与读取规则 **保存报工单时**: 1. **系统字段(field_type=SYSTEM)**: - 直接保存到 `pro_report` 表对应的列 - 例如:`reportUserId` 保存到 `report_user_id` 列 - 使用 MyBatis-Plus 自动映射 2. **自定义字段(field_type=CUSTOM)**: - 保存到 `pro_report.custom_fields` JSON 字段 - 例如:`custom_field_001` 保存为 `{"custom_field_001": "值"}` - 后端需要将自定义字段值序列化为 JSON **查询报工单时**: 1. **系统字段**: - 直接从 `pro_report` 表对应列读取 - MyBatis-Plus 自动映射到实体类 2. **自定义字段**: - 从 `pro_report.custom_fields` JSON 字段解析 - 后端需要将 JSON 反序列化为 Map 或对象 - 前端合并系统字段和自定义字段数据 **示例代码(后端保存)**: ```java // 保存报工单 public void saveReport(Report report, Map customFields) { // 1. 保存系统字段(MyBatis-Plus 自动处理) reportMapper.insert(report); // 2. 保存自定义字段到 JSON if (customFields != null && !customFields.isEmpty()) { String customFieldsJson = JSON.toJSONString(customFields); report.setCustomFields(customFieldsJson); reportMapper.updateById(report); } } ``` **示例代码(后端查询)**: ```java // 查询报工单 public ReportVO getReport(Long id) { Report report = reportMapper.selectById(id); ReportVO vo = new ReportVO(); // 1. 复制系统字段 BeanUtils.copyProperties(report, vo); // 2. 解析自定义字段 if (StringUtils.isNotEmpty(report.getCustomFields())) { Map customFields = JSON.parseObject( report.getCustomFields(), new TypeReference>() {} ); vo.setCustomFields(customFields); } return vo; } ``` **示例代码(前端保存)**: ```javascript // 提交报工单 submitForm() { const formData = { // 系统字段 reportUserId: this.form.reportUserId, reportTime: this.form.reportTime, reportQuantity: this.form.reportQuantity, // ... 其他系统字段 // 自定义字段(单独传递) customFields: { custom_field_001: this.form.custom_field_001, custom_field_002: this.form.custom_field_002, // ... 其他自定义字段 } }; saveReport(formData).then(response => { this.$modal.msgSuccess("保存成功"); }); } ``` --- --- ## 三、功能设计 ### 3.1 配置管理页面 #### 3.1.1 类别配置 - 页面路径:`/production/report/categoryConfig` - 功能: - 列表展示所有类别(系统类别 + 自定义类别)的启用状态 - 支持单个类别的启用/停用切换 - **支持新增自定义类别**(点击"新增类别"按钮) - **支持修改类别名称**(双击编辑或点击编辑按钮) - **支持删除自定义类别**(系统类别不可删除,只能停用) - 支持类别名称重置为默认值(仅系统类别) - 支持批量启用/停用 - 支持排序调整(拖拽排序) #### 3.1.2 字段配置 - 页面路径:`/production/report/fieldConfig` - 功能: - 按类别分组展示字段列表(包括系统类别和自定义类别) - **支持新增自定义字段**(点击"新增字段"按钮,选择所属类别) - 支持单个字段的启用/停用切换 - **支持字段显示名称自定义修改**(双击编辑或点击编辑按钮) - 支持字段名称重置为默认值(仅系统字段) - **支持删除自定义字段**(系统字段不可删除,只能停用) - 支持字段必填属性设置 - 支持字段排序调整 - 支持按类别筛选 - **支持修改字段所属类别**(可将字段移动到其他类别) ### 3.2 报工单表单适配 #### 3.2.1 类别显示控制 - 前端加载配置接口,获取启用的类别列表 - 根据配置动态渲染 `el-collapse-item` - 停用的类别完全不渲染 - **启用的类别按 sort_order 排序后,自动重新编号为 A、B、C、D...** - **显示格式:`{自动编号}. {类别名称}`(如 `A. 基础信息`)** **前端实现示例**: ```javascript // 加载类别配置 async loadCategoryConfig() { const res = await listCategoryConfig({ isEnabled: 'Y' }); // 按 sort_order 排序 const enabledCategories = res.rows.sort((a, b) => a.sortOrder - b.sortOrder); // 自动重新编号 this.displayCategories = enabledCategories.map((cat, index) => ({ ...cat, displayCode: String.fromCharCode(65 + index), // A, B, C, D... displayName: `${String.fromCharCode(65 + index)}. ${cat.categoryName}` })); } ``` #### 3.2.2 字段显示控制 - 前端加载字段配置接口,获取每个类别下启用的字段列表 - 根据配置动态渲染字段控件 - 停用的字段完全不渲染 - 必填字段根据配置动态添加校验规则 --- ## 四、接口设计 ### 4.1 类别配置接口 #### 4.1.1 查询类别配置列表 ``` GET /production/report/categoryConfig/list 响应: [ { "id": 1, "categoryCode": "A", "categoryName": "基础信息", "isEnabled": "Y", "sortOrder": 1 }, ... ] ``` #### 4.1.2 更新类别配置 ``` PUT /production/report/categoryConfig/{id} 请求体: { "isEnabled": "N" } ``` ### 4.2 字段配置接口 #### 4.2.1 查询字段配置列表 ``` GET /production/report/fieldConfig/list?categoryCode=A 响应: [ { "id": 1, "categoryCode": "A", "fieldCode": "reportUserId", "fieldName": "报工人", "isEnabled": "Y", "isRequired": "Y", "sortOrder": 1 }, ... ] ``` #### 4.2.2 更新字段配置 ``` PUT /production/report/fieldConfig/{id} 请求体: { "fieldName": "操作员", // 自定义显示名称 "isEnabled": "N", "isRequired": "N" } ``` #### 4.2.3 重置字段名称 ``` PUT /production/report/fieldConfig/{id}/resetName 响应: { "code": 200, "msg": "重置成功", "data": { "fieldName": "报工人" // 恢复为默认名称 } } ``` #### 4.2.4 批量更新字段配置 ``` PUT /production/report/fieldConfig/batch 请求体: [ { "id": 1, "isEnabled": "Y" }, { "id": 2, "isEnabled": "N" } ] ``` --- ## 五、前端实现要点 ### 5.1 配置加载 ```javascript // 在 formA.vue 和 form.vue 的 created 钩子中加载配置 async loadReportConfig() { // 加载类别配置 const categoryRes = await listCategoryConfig() this.enabledCategories = categoryRes.rows.filter(c => c.isEnabled === 'Y') // 加载字段配置 const fieldRes = await listFieldConfig() this.fieldConfigMap = {} fieldRes.rows.forEach(f => { if (!this.fieldConfigMap[f.categoryCode]) { this.fieldConfigMap[f.categoryCode] = [] } if (f.isEnabled === 'Y') { this.fieldConfigMap[f.categoryCode].push(f) } }) } ``` ### 5.2 动态渲染类别 ```vue ``` ### 5.3 动态渲染字段 ```vue ``` --- ## 六、后端实现要点 ### 6.1 实体类 ```java // ReportCategoryConfig.java @Data @TableName("pro_report_category_config") public class ReportCategoryConfig extends BaseEntity { @TableId(type = IdType.AUTO) private Long id; private String categoryCode; private String categoryName; private String isEnabled; private Integer sortOrder; } // ReportFieldConfig.java @Data @TableName("pro_report_field_config") public class ReportFieldConfig extends BaseEntity { @TableId(type = IdType.AUTO) private Long id; private String categoryCode; private String fieldCode; private String fieldName; private String isEnabled; private String isRequired; private Integer sortOrder; } ``` ### 6.2 Controller ```java @RestController @RequestMapping("/production/report/categoryConfig") public class ReportCategoryConfigController extends BaseController { @Autowired private IReportCategoryConfigService categoryConfigService; @GetMapping("/list") public TableDataInfo list(ReportCategoryConfig config) { startPage(); List list = categoryConfigService.selectList(config); return getDataTable(list); } @PutMapping("/{id}") public AjaxResult update(@PathVariable Long id, @RequestBody ReportCategoryConfig config) { config.setId(id); return toAjax(categoryConfigService.updateById(config)); } } @RestController @RequestMapping("/production/report/fieldConfig") public class ReportFieldConfigController extends BaseController { @Autowired private IReportFieldConfigService fieldConfigService; @GetMapping("/list") public TableDataInfo list(ReportFieldConfig config) { startPage(); List list = fieldConfigService.selectList(config); return getDataTable(list); } @PutMapping("/{id}") public AjaxResult update(@PathVariable Long id, @RequestBody ReportFieldConfig config) { config.setId(id); return toAjax(fieldConfigService.updateById(config)); } @PutMapping("/{id}/resetName") public AjaxResult resetName(@PathVariable Long id) { return fieldConfigService.resetFieldName(id); } @PutMapping("/batch") public AjaxResult batchUpdate(@RequestBody List configs) { return toAjax(fieldConfigService.updateBatchById(configs)); } } ``` --- ## 七、菜单权限配置 ### 7.1 新增菜单 | 菜单名称 | 菜单路径 | 权限标识 | 父菜单 | |---------|---------|---------|--------| | 报工单配置 | /production/report/config | production:report:config | 生产管理 | | 类别配置 | /production/report/categoryConfig | production:report:categoryConfig | 报工单配置 | | 字段配置 | /production/report/fieldConfig | production:report:fieldConfig | 报工单配置 | ### 7.2 权限标识 - `production:report:categoryConfig:list` - 查询类别配置 - `production:report:categoryConfig:edit` - 修改类别配置 - `production:report:fieldConfig:list` - 查询字段配置 - `production:report:fieldConfig:edit` - 修改字段配置 - `production:report:fieldConfig:batchEdit` - 批量修改字段配置 --- ## 八、实施步骤 | 步骤 | 任务 | 工作量 | |------|------|--------| | 1 | 执行 SQL 脚本创建配置表和初始化数据 | 0.5h | | 2 | 后端:创建实体类、Mapper、Service、Controller(含重置名称接口) | 2.5h | | 3 | 前端:创建配置管理页面(类别配置、字段配置,含字段名称编辑) | 5h | | 4 | 前端:报工单表单适配(动态加载配置、动态渲染、使用自定义名称) | 4h | | 5 | 联调测试、修复问题 | 2h | | **合计** | | **约 2 个工作日** | --- ## 九、核心规则说明 ### 9.1 字段类型规则 | 规则项 | 系统字段(SYSTEM) | 自定义字段(CUSTOM) | |--------|-------------------|---------------------| | **字段编码** | 使用实体类字段名(如 `reportUserId`) | 使用 `custom_field_` + 序号(如 `custom_field_001`) | | **存储位置** | `pro_report` 表对应列(如 `report_user_id`) | `pro_report.custom_fields` JSON 字段 | | **字段名称** | 可自定义修改显示名称 | 可自定义修改显示名称 | | **数据类型** | 固定(由数据库列类型决定) | 可配置(STRING/NUMBER/DATE/DATETIME/BOOLEAN/SELECT) | | **控件类型** | 可配置 | 可配置 | | **所属类别** | 固定(不可修改) | 可修改(可移动到其他类别) | | **是否可删除** | 不可删除,只能停用 | 可删除 | ### 9.1.1 类别类型规则 | 规则项 | 系统类别(SYSTEM) | 自定义类别(CUSTOM) | |--------|-------------------|---------------------| | **类别编码** | A/B/C/D/E(固定) | F/G/H/I...(自动生成) | | **类别名称** | 可自定义修改 | 可自定义修改 | | **是否可删除** | 不可删除,只能停用 | 可删除(删除前需确认该类别下无字段) | | **排序** | 可调整 | 可调整 | ### 9.2 数据保存规则 **规则 1:系统字段直接保存到对应列** - 系统字段(field_type=SYSTEM)的值直接保存到 `pro_report` 表对应的列 - 例如:`reportUserId` → `report_user_id` 列 - 使用 MyBatis-Plus 自动映射,无需特殊处理 **规则 2:自定义字段保存到 JSON** - 自定义字段(field_type=CUSTOM)的值保存到 `custom_fields` JSON 字段 - 所有自定义字段值合并为一个 JSON 对象 - 例如:`{"custom_field_001": "值1", "custom_field_002": 123}` **规则 3:JSON 字段格式要求** - 必须是有效的 JSON 格式 - 键名为字段编码(field_code) - 值类型根据 data_type 确定(字符串、数字、布尔值等) ### 9.3 数据查询规则 **规则 1:系统字段直接读取** - 从 `pro_report` 表对应列直接读取 - MyBatis-Plus 自动映射到实体类 **规则 2:自定义字段从 JSON 解析** - 从 `custom_fields` JSON 字段解析 - 后端反序列化为 Map 或对象 - 前端合并系统字段和自定义字段数据 **规则 3:字段配置动态加载** - 前端根据字段配置表动态渲染表单 - 系统字段和自定义字段统一处理 - 根据 field_type 判断数据来源 ### 9.4 字段配置规则 **规则 1:字段编码不可修改** - field_code 一旦创建不可修改 - 系统字段编码对应实体类字段名 - 自定义字段编码使用 `custom_field_` 前缀 **规则 2:字段名称可自定义** - field_name 可随时修改 - 支持重置为 default_field_name **规则 3:停用=隐藏** - is_enabled='N' 时,字段在表单中完全隐藏 - 停用的字段不参与表单验证 - 停用的字段不影响已保存的数据 **规则 4:必填字段保护** - 核心必填字段(报工人、报工时间、报工数量等)不允许停用 - 前端和后端都需要校验 ### 9.5 自定义字段管理规则 **规则 1:新增自定义字段** - 在字段配置页面点击"新增字段" - **选择所属类别(可选择系统类别或自定义类别)** - 配置字段名称、数据类型、控件类型 - 系统自动生成 field_code(custom_field_xxx) **规则 2:删除自定义字段** - 只能删除自定义字段(field_type=CUSTOM) - 系统字段不可删除,只能停用 - 删除前需确认是否有数据使用该字段 **规则 3:修改自定义字段** - 可修改字段名称、数据类型、控件类型 - **可修改字段所属类别(移动到其他类别)** - 修改数据类型可能导致已有数据格式不兼容 - 建议修改前备份数据 ### 9.6 自定义类别管理规则 **规则 1:新增自定义类别** - 在类别配置页面点击"新增类别" - 输入类别名称 - 系统自动生成 category_code(F/G/H...) - 新增的类别默认启用 **规则 2:删除自定义类别** - 只能删除自定义类别(category_type=CUSTOM) - 系统类别(A/B/C/D/E)不可删除,只能停用 - 删除前需确认该类别下没有字段 - 如果类别下有字段,需要先删除或移动字段 **规则 3:修改自定义类别** - 可修改类别名称 - 可调整排序 - 系统类别名称可修改,但不可删除 **规则 4:类别编码生成规则** - 系统类别:A/B/C/D/E(固定) - 自定义类别:按字母顺序自动生成(F/G/H/I/J...) - 如果字母用完,使用 AA/AB/AC...(26 个字母后) ### 9.7 类别显示与排序规则 **规则 1:类别编号自动排序(默认行为)** - 前端显示时,只显示启用的类别 - 启用的类别按 `sort_order` 排序后,自动重新编号为 A、B、C、D... - 例如: - 配置:A(启用)、B(启用)、C(停用)、D(启用)、E(启用) - 显示:A. 基础信息、B. 数量信息、C. 成本效益、D. 异常记录 - 实际对应:A→A、B→B、D→C、E→D **规则 2:自定义排序(用户手动调整)** - 用户可以通过拖拽或上下移动按钮调整类别顺序 - 调整后更新 `sort_order` 字段 - 前端按照 `sort_order` 排序显示 - 自定义排序后,仍然自动重新编号 **规则 3:类别编号显示规则** - 前端显示格式:`{自动编号}. {类别名称}` - 例如:`A. 基础信息`、`B. 数量信息` - 自动编号不存储在数据库,仅用于前端显示 - 数据库中的 `category_code` 保持不变 **规则 4:停用类别的处理** - 停用的类别在报工单表单中完全隐藏 - 停用的类别不参与自动编号 - 停用的类别在配置页面仍然显示(标记为停用状态) **示例说明**: | 数据库配置 | sort_order | is_enabled | 前端显示 | |-----------|-----------|-----------|---------| | A-基础信息 | 1 | Y | A. 基础信息 | | B-数量信息 | 2 | Y | B. 数量信息 | | C-时间节拍 | 3 | N | (隐藏) | | D-成本效益 | 4 | Y | C. 成本效益 | | E-异常记录 | 5 | Y | D. 异常记录 | | F-自定义类别 | 6 | Y | E. 自定义类别 | ## 十、注意事项 1. **必填字段保护**:报工人、报工时间、报工数量、合格数量等核心必填字段不允许停用 2. **字段编码不可修改**:field_code(字段编码)对应数据库字段名或自定义字段标识,不允许修改 3. **类别编号自动排序**:前端显示时,启用的类别自动重新编号为 A、B、C、D...,停用的类别不参与编号 4. **类别编码固定**:数据库中的 category_code 保持不变(A/B/C/D/E/F/G...),仅前端显示编号会自动调整 5. **JSON 字段性能**:自定义字段存储在 JSON 中,查询性能较差,不建议在 WHERE 条件中使用 6. **数据类型兼容**:修改自定义字段的数据类型时,需要考虑已有数据的兼容性 7. **配置缓存**:前端可以缓存配置数据,避免每次打开表单都请求接口 8. **配置变更通知**:配置修改后,需要刷新页面才能生效(或使用 WebSocket 推送配置变更) 9. **移动端适配**:配置管理页面仅在 PC 端显示,移动端隐藏配置入口 10. **历史数据兼容**:已保存的报工单不受配置影响,配置仅影响新增/编辑时的表单显示 11. **名称重置功能**:支持将自定义的字段名称和类别名称重置为系统默认名称 12. **自定义字段数量限制**:建议每个类别的自定义字段不超过 20 个,避免表单过于复杂 13. **删除类别前检查**:删除自定义类别前,需确认该类别下没有字段 --- ## 十、扩展规划 ### 10.1 自定义字段(后续版本) - 支持用户自定义新增字段 - 字段类型:文本、数字、日期、下拉、多选等 - 自定义字段存储在 JSON 字段中 ### 10.2 多配置方案(后续版本) - 支持不同车间/工位使用不同的配置方案 - 配置方案可以复制、导入、导出 ### 10.3 字段联动(后续版本) - 支持字段之间的显示/隐藏联动 - 支持字段值的计算联动