fieldRule($data,$user); if(!$status) return [$status,$msg]; try { DB::beginTransaction(); CustomFieldDefinitions::insert($data['data']); DB::commit(); }catch (\Exception $exception){ DB::rollBack(); return [false,$exception->getMessage()]; } return [true,'']; } public function edit($data,$user){ list($status,$msg) = $this->fieldRule($data,$user, false); if(!$status) return [$status,$msg]; try { DB::beginTransaction(); $update = $msg['data'][0]; $id = $update['id']; $model = new CustomFieldDefinitions(); $model->where('id', $id)->update([ 'menu_id' => $update['menu_id'], 'field_label' => $update['field_label'], 'field_type' => $update['field_type'], ]); DB::commit(); }catch (\Exception $exception){ DB::rollBack(); return [false,$exception->getMessage()]; } return [true,'']; } public function del($data, $user){ if(empty($data['id']) || ! is_array($data['id'])) return [false,'ID不能为空或格式错误']; try { CustomFieldDefinitions::whereIn('id', $data['id'])->update([ 'del_time' => time() ]); }catch (\Exception $exception){ DB::rollBack(); return [false,$exception->getMessage()]; } return [true,'']; } public function fieldCommon($data,$user, $field = []){ if(empty($field)) $field = CustomFieldDefinitions::$field; $model = CustomFieldDefinitions::TopClear($user,$data); $model = $model->where('del_time',0) ->select($field) ->orderby('id', 'desc'); if(! empty($data['field_label'])) $model->where('field_label', 'LIKE', '%'.$data['field_label'].'%'); return $model; } public function list($data, $user){ $model = $this->fieldCommon($data, $user); $list = $this->limit($model,'',$data); $list = $this->fillList($list); return [true, $list]; } public function fillList($data){ if(empty($data['data'])) return $data; $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_column($data['data'],'crt_id'))); $menu_map = (new SysMenuService())->getMap(array_unique(array_column($data['data'],'menu_id'))); foreach ($data['data'] as $key => $value){ $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : ''; $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? ''; $data['data'][$key]['menu_title'] = $menu_map[$value['menu_id']] ?? ''; $data['data'][$key]['field_type_title'] = CustomFieldDefinitions::State_Type[$value['field_type']] ?? ''; } return $data; } public function detail($data, $user){ if(empty($data['id'])) return [false,'id不能为空']; list($status, $return) = $this->list(['id' => [$data['id']]], $user); $return = $return['data'][0] ?? []; return [true, $return]; } public function fieldRule(&$data,$user, $is_add = true){ $data['top_depart_id'] = $user['top_depart_id']; // $bool = SysModules::where('del_time',0) // ->where('top_depart_id', $data['top_depart_id']) // ->where('menu_id', $data['menu_id']) // ->exists(); // if(! $bool) return [false, $title . '不允许增加自定义表头']; if(empty($data['data'])) return [false,'自定义数据不能为空']; $title = array_column($data['data'],'field_label'); $title = array_map(function($val) { return $val !== null ? $val : 0; }, $title); $title_count = array_count_values($title); foreach ($title as $value){ if(empty($value)) return [false,'自定义名称不能为空!']; if($title_count[$value] > 1) return [false,'自定义名称不能重复']; } foreach ($data['data'] as $key => $value){ if(empty($value['menu_id'])) return [false, '菜单不能为空']; if(empty($value['field_label'])) return [false, '自定义项名称不能为空']; if(empty($value['field_type'])) return [false, '自定义项类型不能为空']; if(! isset(CustomFieldDefinitions::State_Type[$value['field_type']])) return [false, '自定义项类型错误']; $top_depart_id = $user['top_depart_id']; $data['data'][$key]['menu_id'] = $value['menu_id']; $data['data'][$key]['top_depart_id'] = $top_depart_id; $data['data'][$key]['upd_time'] = time(); if($is_add){ $data['data'][$key]['crt_time'] = time(); $fieldKey = 'f_' . substr(md5(microtime() . $value['field_label']), 0, 8); $data['data'][$key]['field_key'] = $fieldKey; $bool = CustomFieldDefinitions::where("field_label", $value['field_label']) ->where('top_depart_id', $top_depart_id) ->where('menu_id', $value['menu_id']) ->where('del_time',0) ->exists(); }else{ if($this->isEmpty($value,'id')) return [false,'id不能为空!']; $bool = CustomFieldDefinitions::where("field_label", $value['field_label']) ->where('top_depart_id', $top_depart_id) ->where('menu_id', $value['menu_id']) ->where('id','<>',$value['id']) ->where('del_time',0) ->exists(); if(isset($value['field_key'])) unset($data['data'][$key]['field_key']); } if($bool) return [false,'自定义设置已存在']; } return [true, $data]; } public static function syncCustomFieldData1($id, $data, $user) { $top_depart_id = $user['top_depart_id']; if (empty($data['menu_id'])) return [true, '']; $definitions = CustomFieldDefinitions::where('menu_id', $data['menu_id']) ->where('top_depart_id', $top_depart_id) ->get(); if(empty($definitions)) return [true, '']; $pendingTasks = []; $time = time(); try { foreach ($definitions as $df) { $key = $df->field_key; // 如果请求数据中没有这个自定义字段的 key,跳过 if (!array_key_exists($key, $data)) continue; $newVal = (string)($data[$key] ?? ''); // --- 附件类型逻辑处理 --- if ($df->field_type === CustomFieldDefinitions::TYPE_TWO) { // 查询数据库中已有的旧路径 $oldVal = DB::table('custom_field_values') ->where('model_id', $id) ->where('definition_id', $df->id) ->value('field_value') ?? ''; if ($newVal !== $oldVal) { //产生一个【删除任务】 if (!empty($oldVal)) { $pendingTasks[] = [ 'type' => SysOssTasks::type_one, // 删除旧文件 'url' => $oldVal, 'top_depart_id' => $top_depart_id, 'crt_time' => $time, ]; } //产生一个【新增同步任务】 if (!empty($newVal)) { $pendingTasks[] = [ 'type' => SysOssTasks::type_two, // 新增同步到 OSS 'url' => $newVal, 'top_depart_id' => $top_depart_id, 'crt_time' => $time, ]; } } } // --- 统一更新业务值表 (文本或附件路径) --- DB::table('custom_field_values')->updateOrInsert( [ 'model_id' => $id, 'definition_id' => $df->id, 'top_depart_id' => $top_depart_id, 'field_type' => $df->field_type ], [ 'field_value' => $newVal, // 如果是删除,这里存入空字符串 'upd_time' => time() ] ); } //需要执行的oss的任务 调用这个方法的地方在 事务结束后触发下队列 if(! empty($pendingTasks)) { SysOssTasks::insert($pendingTasks); ProcessOssTask::dispatch()->onQueue(SysOssTasks::job); } }catch (\Throwable $exception){ return [false, $exception->getMessage()]; } return [true, '']; } public function fillDataCustomField(&$data){ if(! empty($data['custom_field_values'])){ $fileUploadService = new FileUploadService(); foreach ($data['custom_field_values'] as $key => $value){ if($value['field_type'] == CustomFieldDefinitions::TYPE_TWO){ $img_str = $fileUploadService->getFileShow($value['field_value']); $data['custom_field_values'][$key]['field_value_show'] = $img_str; } } } } public static function syncCustomFieldData($modelId, $tableName, $data, $user) { if(empty($tableName)) return [false, '表名不存在']; $top_depart_id = $user['top_depart_id']; $customFields = $data['custom_fields'] ?? []; $time = time(); $pendingTasks = []; // 1. 预校验:过滤掉空标签后,判断剩下的标签是否重复 $labels = array_filter(array_column($customFields, 'field_label')); if (count($labels) !== count(array_unique($labels))) return [false, '自定义字段名称不能重复']; try { // 2. 获取数据库现有的旧数据(仅限未删除的) $oldValues = CustomFieldValue::where('top_depart_id', $top_depart_id) ->where('table_name', $tableName) ->where('model_id', $modelId) ->where('del_time', 0) ->get() ->keyBy('id'); $submittedIds = []; // 3. 处理前端提交的数据 foreach ($customFields as $field) { $fId = (int)($field['id'] ?? 0); $label = trim((string)($field['field_label'] ?? '')); $newVal = (string)($field['field_value'] ?? ''); $type = (int)($field['field_type'] ?? 1); $field_name = (string)($field['field_name'] ?? ''); if ($label === '') continue; // 标签为空的直接跳过,不保存 // --- OSS 附件逻辑 --- if ($type === 2) { $oldVal = isset($oldValues[$fId]) ? $oldValues[$fId]->field_value : ''; if ($newVal !== $oldVal) { if (!empty($oldVal)) $pendingTasks[] = ['type' => SysOssTasks::type_one, 'url' => $oldVal, 'top_depart_id' => $top_depart_id, 'crt_time' => $time]; if (!empty($newVal)) $pendingTasks[] = ['type' => SysOssTasks::type_two, 'url' => $newVal, 'top_depart_id' => $top_depart_id, 'crt_time' => $time]; } } // --- 保存/更新 --- // 如果前端传了 ID,就按 ID 改;没传 ID,就新增(updateOrInsert 在 id 为 0 时会执行插入) $saveData = [ 'top_depart_id' => $top_depart_id, 'table_name' => $tableName, 'model_id' => $modelId, 'field_label' => $label, 'field_value' => $newVal, 'field_type' => $type, 'field_name' => $field_name, ]; if ($fId > 0) { CustomFieldValue::where('id', $fId)->update($saveData); $submittedIds[] = $fId; } else { $saveData['crt_time'] = $time; $newId = CustomFieldValue::insertGetId($saveData); $submittedIds[] = $newId; } } // 4. 清理:如果旧 ID 不在本次提交的 ID 列表中,说明被删除了 foreach ($oldValues as $oldId => $oldRow) { if (!in_array($oldId, $submittedIds)) { // 如果删掉的是附件,加个删除任务 if ($oldRow->field_type == 2 && !empty($oldRow->field_value)) { $pendingTasks[] = ['type' => SysOssTasks::type_one, 'url' => $oldRow->field_value, 'top_depart_id' => $top_depart_id, 'crt_time' => $time]; } CustomFieldValue::where('id', $oldId)->update(['del_time' => $time]); } } // 5. 触发 OSS 任务 if (!empty($pendingTasks)) { SysOssTasks::insert($pendingTasks); ProcessOssTask::dispatch()->onQueue(SysOssTasks::job); } } catch (\Throwable $exception) { return [false, $exception->getMessage()]; } return [true, '']; } }