Files
admin/module/Application/src/Form/item/FormForm.php
2025-09-13 01:22:15 +08:00

463 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Application\Form\item;
use Application\Common\Enum;
use Application\Common\EventEnum;
use Application\Service\DB\AbstractDb;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Event;
use Application\Service\Extension\Events\ItemFormEventHandler;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Validator\ValidatorApplication;
use Laminas\Db\Sql\Predicate\In;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Validator\Exception\InvalidArgumentException;
class FormForm extends \Application\Form\FormForm
{
public function __construct(ValidatorApplication $validator = null)
{
parent::__construct($validator);
Event::on(EventEnum::EVENT_AFTER_ITEM_FORM_CREATE, [ItemFormEventHandler::class, 'afterItemFormCreate']);
}
protected function getForm():AbstractDb
{
return Laminas::$serviceManager->itemForm;
}
protected function getFormField()
{
return Laminas::$serviceManager->itemFormField;
}
protected function getFormRadio()
{
return Laminas::$serviceManager->itemFormFieldRadio;
}
protected function getFormText()
{
return Laminas::$serviceManager->itemFormFieldText;
}
protected function getFormVersion()
{
return Laminas::$serviceManager->itemFormVersion;
}
/**
* 验证AE, SAE, 实验总结, 随机分组类是否已经创建了多个
* @param $value
* @return void|null
*/
public function invalidGroupId($value)
{
if (!in_array($value, [FormGroup::AE, FormGroup::SAE, FormGroup::RANDOM_GROUP])) {
return null;
}
if ($_POST['id']) {
$query = $this->getForm()->fetchOne([
'columns' => ['id'],
'where' => ['is_del' => 0, 'item_id' => $_POST['item_id'], 'group_id' => $value]
]);
if ($query['id'] != $_POST['id']) {
throw new InvalidArgumentException("此类型表单只能设置一个, 请勿重复添加");
}
} else {
if (
Laminas::$serviceManager->itemForm->fetchOne([
'where' => [
'item_id' => $_POST['item_id'],
'group_id' => $value,
'is_del' => 0
]
])
) {
throw new InvalidArgumentException("此类型表单只能设置一个, 请勿重复添加");
}
}
return null;
}
/**
* 验证字典项表单名称是否添加重复
* @param $value
* @return null
*/
public function invalidCreateName($value)
{
$request = Laminas::$app->getMvcEvent()->getRequest();
if ($value !== null) {
// 没 id 说明是新增, 有 id 是编辑
$id = $request->getPost('id');
// 新增
if (!$id) {
$query = $this->getForm()->fetchOne([
'columns' => ['id'],
'where' => ['name' => $request->getPost('name'), 'is_del' => 0, 'item_id' => $request->getPost('item_id')]
]);
if ($query) {
throw new InvalidArgumentException("表单名称 {$value} 已存在, 请勿重复添加。");
}
} else {
$query = $this->getForm()->fetchOne([
'columns' => ['id'],
'where' => ['name' => $request->getPost('name'), 'is_del' => 0, 'item_id' => $request->getPost('item_id')]
]);
if ($query && (count($query) > 1 || $query['id'] != $request->getPost('id'))) {
throw new InvalidArgumentException("表单名称 {$value} 已在其他表单中使用, 请勿重复添加[e-2]。");
}
}
}
return null;
}
/**
* 验证删除表单id
* @return null
*/
public function invalidDeleteId($val)
{
$request = Laminas::$app->getMvcEvent()->getRequest();
$formData = Laminas::$serviceManager->itemForm->fetchOne([
'where' => ['id' => $request->getPost('id')]
]);
if (Laminas::$serviceManager->patientFormContent->fetchOne(['where' => [
'item_id' => $formData['item_id'],
'form_id' => $formData['id'],
'is_del' => 0
]])) {
throw new InvalidArgumentException("当前表单已有受试者填写。无法进行删除操作。", 1001);
}
//查询一下该form下的字段ID
$form_fileids = Laminas::$serviceManager->itemFormField->fetchCol('id',['is_del' => 0,'form_id' => $formData['id']]);
$relation_where = ['form_id' => $formData['id'], 'is_del' => 0, new Operator('relation_form_id', Operator::OP_NE, 0)];
if(!empty($form_fileids)){
$relation_where[] = ['field_id'=> StringHelper::toArray($form_fileids)];
}
if (Laminas::$serviceManager->itemFormRelation->getCount($relation_where)) {
throw new InvalidArgumentException("当前表单下已有其他关联表单。无法进行删除操作。请解除关联关系。", 1001);
}
if (Laminas::$serviceManager->itemFormFieldRadio->getCount([new \Laminas\Db\Sql\Predicate\Expression("FIND_IN_SET('$val',relation_information)")])) {
throw new InvalidArgumentException("当前表单已被其他表单关联。无法进行删除操作。请解除关联关系。", 1001);
}
return null;
}
public function validVarName($val)
{
$request = Laminas::$app->getMvcEvent()->getRequest();
$originData = $this->getForm()->fetchOne([
'where' => ['id' => $request->getPost('id')]
]);
// 如果有受试者填写过数据, 有些数据不允许更改
if ($originData) {
if (Laminas::$serviceManager->itemForm->getIsPatientWrite($request->getPost('id'))) {
$labelMap = [
'type' => '类型',
'group_id' => '表单类型',
];
foreach ($labelMap as $field => $label) {
if ($originData[$field] != $request->getPost($field)) {
throw new \Application\Service\Exceptions\InvalidArgumentException("已有受试者数据。无法更改 `{$label}`");
}
}
}
}
if ($request->getPost('form_type') == FormField::FORM_CONFIG_RADIO && !$val) {
return null;
}
//检查点变量名规则
$isMatched = preg_match('/^[a-zA-Z_]([a-zA-Z0-9_]+)?$/', $val);
if (!$isMatched) {
throw new \Laminas\Validator\Exception\InvalidArgumentException("变量名必须以A-Z不区分大小写或下划线_开始,且不能包括空格和特殊符号。", 1001);
}
if (strlen($val) > 32) {
throw new \Application\Service\Exceptions\InvalidArgumentException("不能超过32个字符", 1001);
}
// 验证变量名不能重复
// 【新系统】变量名,新加不可重复的控制 --李总,白老师
//https://e.gitee.com/yikeen_project/dashboard?issue=I72KSD
// 没 id 说明是新增, 有 id 是编辑
$where = ['item_id' => $request->getPost('item_id'), 'var_name' => $val, 'is_del' => 0];
$condition = $request->getPost('id') ? [new Operator('id', Operator::OP_NE, $request->getPost('id'))] : null;
if ($condition !== null) {
$where = ArrayHelper::merge($where, $condition);
}
$data = $this->getForm()->fetchAll([
'columns' => ['var_name', 'id', 'name'],
'where' => $where
]);
// 新增
if ($request->getPost('id')) {
if (count($data) > 1) {
throw new InvalidArgumentException("变量名 `{$val}` 已与 `{$data['name']}` 中的变量名重复, 请勿重复添加。", 1001);
}
$data = current($data);
if ($data && $data['id'] != $request->getPost('id')) {
throw new InvalidArgumentException("变量名 `{$val}` 已与 `{$data['name']}` 中的变量名重复, 请勿重复添加。", 1001);
}
$c = 1;
} else {
$c = 0;
}
if ($data && (count($data) > $c || current(ArrayHelper::getColumn($data, 'var_name')) != $request->getPost('var_name'))) {
$formName = current($data)['name'];
throw new InvalidArgumentException("变量名 `{$val}` 已与 `{$formName}` 中的变量名重复, 请勿重复添加。", 1001);
}
return null;
}
public function validGcoPool($value)
{
// 编辑
if ($_POST['id']) {
$isWrite = Laminas::$serviceManager->patientForm->fetchAll([
'columns' => ['id'],
'where' => [
'form_id' => ArrayHelper::getColumn(SDMHelper::app()->form->getGcoGroupForm($_POST['id']), 'id'),
'is_del' => 0
]
]);
// 没产生数据随便编辑。
if (!$isWrite) {
return;
}
$originGcoPool = SDMHelper::app()->form->getGcoPool($_POST['id']);
$currentGcoPool = $value;
if ($originGcoPool != $currentGcoPool) {
throw new InvalidArgumentException("已产生数据的表单, 识别分组无法更改。");
}
}
return ;
}
/**
* 进度管理
* 创建项目表单
* @return int
*/
public function createForm(): int
{
$this->event = EventEnum::EVENT_DICTIONARY_FORM_CREATE;
Db::beginTransaction();
// 实验总结类默认勾选所有隶属实验总结类检查点
if ($this->validator->attributes['group_id'] == FormGroup::TEST_SUMMARY) {
$this->validator->attributes['ds_stage'] = FormGroup::DS_STAGE;
}
$formId = Laminas::$serviceManager->itemForm->insert([
'name' => $this->validator->attributes['name'],
'type' => $this->validator->attributes['type'],
'item_id' => $this->validator->attributes['item_id'],
'is_patient' => ($this->validator->attributes['is_patient'] ?? '') ?: '',
'finish_condition' => $this->validator->attributes['finish_condition'],
'is_required' => $this->validator->attributes['is_required'],
'checklist_id' => $this->validator->attributes['checklist_id'],
'create_user_id' => Laminas::$serviceManager->identity->getId(),
'order' => $this->validator->attributes['order'],
'group_id' => $this->validator->attributes['group_id'],
'show_type' => $this->validator->attributes['show_type'],
'reference_file' => $this->validator->attributes['reference_file'],
'rdg_type' => $this->validator->attributes['rdg_type'] ?? 0,
'var_name' => $this->validator->attributes['var_name'] ?: '',
'expression' => $this->validator->attributes['expression'] ?: '',
'code' => $this->validator->attributes['code'] ?? '',
'except_checktime' => $this->getExceptCheckTime(),
'is_handwritten_signature' => $this->validator->attributes['can_patient_write'] ?? 0,
'ds_stage' => $this->validator->attributes['ds_stage'] ?? 1,
'guide' => $this->validator->attributes['guide'] ?? '',
'is_using_score' => $this->validator->attributes['is_using_score'] ?? 0,
'is_through_process_do' => $this->validator->attributes['is_through_process_do'] ?? 0,
'info_collect_type' => $this->validator->attributes['info_collect_type'] ?? 0,
'gco_pool' => $this->validator->attributes['gco_pool'] ?? '',
'is_patient_general_info' => $this->validator->attributes['is_patient_general_info'] ?? '',
'identification_edit' => ArrayHelper::getValue($this->validator->attributes, 'identification_edit', 0),
'is_export' => ArrayHelper::getValue($this->validator->attributes, 'is_export', 0),
'is_more_sdv' => ArrayHelper::getValue($this->validator->attributes, 'is_more_sdv', 0)
]);
// 添加随机分组字段
$this->initRandomGroupField($formId, $this->validator->attributes['rdg_type'] ?? 0);
if ($this->validator->attributes['checklist_id'] || $this->validator->attributes['group_id'] == FormGroup::CHECK_DO) {
$this->initCheckListField($formId);
}
// 医嘱识别
if ($this->validator->attributes['group_id'] == FormGroup::THROUGH_PROCESS && $this->validator->attributes['is_through_process_do'] == 1) {
if ($this->validator->attributes['type'] == 0) {
throw new \Application\Service\Exceptions\InvalidArgumentException('识别医嘱的类型不能为一对一');
}
// 初始化贯穿全程识别医嘱表单字段
$this->initThroughProcessDoField($formId);
}
Event::trigger(EventEnum::EVENT_AFTER_ITEM_FORM_CREATE, [$this]);
Db::commit();
return $formId;
}
/**
* 获取未选中的检查点
* 前端提交过来的是选中的检查点, 需要处理一下
* @return string
*/
private function getExceptCheckTime(): string
{
if (!isset($this->validator->attributes['except_checktime'])) {
return '';
}
$allCheckTime = Laminas::$serviceManager->itemChecktime->fetchAll([
'columns' => ['id'],
'where' => ['item_id' => $this->validator->attributes['item_id']]
]);
$exceptCheckTime = explode(',', $this->validator->attributes['except_checktime']);
if (!$exceptCheckTime) {
return '';
}
foreach ($allCheckTime as $key => $item) {
if (in_array($item['id'], $exceptCheckTime)) {
unset($allCheckTime[$key]);
}
}
return implode(',', array_values(ArrayHelper::getColumn($allCheckTime, 'id')));
}
/**
* 编辑项目表单
* @return array
* @throws \Exception
*/
public function editForm()
{
Db::beginTransaction();
// 随机分组处理
$rdgType = $this->validator->attributes['rdg_type'] ?? 0;
$originData = Laminas::$serviceManager->itemForm->fetchOne([
'where' => ['id' => $this->validator->attributes['id']]
]);
// 随机分组类型 1:手动新增;2:系统随机获取;
$originRdgType = $originData['rdg_type'] ?: 0;
$itemId = $originData['item_id'] ?: 0;
// 修改了随机分组随机号分配类型, 就去处理一些东西
if ($originRdgType && $originRdgType != $rdgType) {
if ($rdgType == 1) {
Laminas::$serviceManager->patient->delGroupAndNumber($itemId,1); // 0手改自1自改手
} elseif ($rdgType == 2) {
Laminas::$serviceManager->patient->delGroupAndNumber($itemId,0); // 0手改自1自改手
}
}
Laminas::$serviceManager->itemForm->save([
'id' => $this->validator->attributes['id'],
'name' => $this->validator->attributes['name'],
'type' => $this->validator->attributes['type'],
'is_patient' => $this->validator->attributes['is_patient'],
'finish_condition' => $this->validator->attributes['finish_condition'],
'is_required' => $this->validator->attributes['is_required'],
'checklist_id' => $this->validator->attributes['checklist_id'],
'order' => $this->validator->attributes['order'],
'group_id' => $this->validator->attributes['group_id'],
'show_type' => $this->validator->attributes['show_type'],
'reference_file' => $this->validator->attributes['reference_file'],
'rdg_type' => $rdgType,
'expression' => $this->validator->attributes['expression'] ?: '',
'var_name' => $this->validator->attributes['var_name'] ?: '',
'can_patient_write' => $this->validator->attributes['can_patient_write'] ?: 0,
'except_checktime' => $this->getExceptCheckTime(),
'is_handwritten_signature' => $this->validator->attributes['is_handwritten_signature'] ?? 0,
'ds_stage' => $this->validator->attributes['ds_stage'] ?: 1,
'guide' => $this->validator->attributes['guide'] ?: '',
'is_using_score' => $this->validator->attributes['is_using_score'] ?: 0,
'info_collect_type' => call_user_func(function () {
$r = $this->validator->attributes['info_collect_type'] ?: 0;
Laminas::$serviceManager->patientFormContentImg->isSetInfo(false)->update(['info_collect_type' => $r], ['form_id' => $this->validator->attributes['id']]);
return $r;
}),
'gco_pool' => $this->validator->attributes['gco_pool'] ?? '',
'is_patient_general_info' => $this->validator->attributes['is_patient_general_info'] ?? '',
'identification_edit' => ArrayHelper::getValue($this->validator->attributes, 'identification_edit', 0),
'is_export' => ArrayHelper::getValue($this->validator->attributes, 'is_export', 0),
'is_more_sdv' => ArrayHelper::getValue($this->validator->attributes, 'is_more_sdv', 0)
]);
$randomGroupId = Laminas::$serviceManager->itemFormField->fetchOne([
'where' => [
'var_name' => ['RANGC', 'RANGCA'],
'form_id' => $this->validator->attributes['id']
]
]);
// 如果当前表单是随机分组表单, 变更了随机分组类型, 需要同步修改生成出来的随即表单的变量和随机分组(研究分组)展示方式。
// 手写是单选, 系统分配是下拉框。
if ($randomGroupId) {
$type = $rdgType == 1 ? Enum::FORM_FIELD_TYPE_RADIO : Enum::FORM_FIELD_TYPE_DROPDOWN;
$varName = $rdgType == 1 ? 'RANGC' : 'RANGCA';
Laminas::$serviceManager->itemFormField->update([
'type' => $type,
'var_name' => $varName
], ['id' => $randomGroupId['id']]);
Laminas::$serviceManager->itemFormFieldText->update([
'var_name' => $varName
], ['field_id' => $randomGroupId['id']]);
}
Laminas::$serviceManager->itemFormVersion->generate($this->validator->attributes['id']);
Db::commit();
return [];
}
}