This commit is contained in:
2025-09-13 01:22:15 +08:00
parent 155e05fd6d
commit 1a4b8551a0
674 changed files with 146276 additions and 0 deletions

View File

@ -0,0 +1,139 @@
<?php
namespace Application\Command;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Queue\jobs\SyncPatientFormJob;
use Application\Service\Extension\Queue\QueueApplication;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Ark 同步脚本
* http://42.192.180.144/arkedc/login.jsp
* username:TEST01 pwd:12345
*
*/
class ArkCommand extends BasicCommand
{
private ?int $itemId = null;
private ?int $itemSignId = null;
private ?int $patientId = null;
private ?int $formId = null;
/**
* 共同页表单类型
*/
const SHARE_PAGE_FORM = [FormGroup::SAE, FormGroup::AE, FormGroup::THROUGH_PROCESS, FormGroup::TEST_SUMMARY];
public function execute(InputInterface $input, OutputInterface $output)
{
// 要同步的项目
$syncItem = [
// 项目id
101 => [ // 中心id
272
]
];
foreach ($syncItem as $itemId => $signArray) {
$this->itemId = $itemId;
foreach ($signArray as $signId) {
$this->itemSignId = $signId;
$patients = $this->getPatients();
foreach ($patients as $patient) {
$this->patientId = $patient;
// 当前受试者所有检查点
$checkTimes = Laminas::$serviceManager->itemPatientchecktime->fetchAll([
'columns' => ['checktime_id'],
'where' => [
'patient_id' => $this->patientId
]
]);
// 共同页
$allCheckTime[] = [
'checktime_id' => 99
];
foreach ($checkTimes as $checkTime) {
if ($checkTime['checktime_id'] == 99) { // 是共同页
$allFormId = Laminas::$serviceManager->itemForm->fetchCol('id', [
'item_id' => $this->itemId,
'group_id' => self::SHARE_PAGE_FORM,
'is_del' => 0
]);
} else {
$allFormId = Laminas::$serviceManager->patientForm->fetchCol('form_id', ['patient_id' => $this->patientId, 'is_del' => 0, 'checktime_id' => $checkTime['checktime_id']]);
}
$allFormId = array_unique(array_values($allFormId));
foreach ($allFormId as $formId) {
$this->formId = $formId;
$form = Laminas::$serviceManager->itemForm->fetchOne([
'where' => ['id' => $this->formId]
]);
if ($checkTime['checktime_id'] != 99) {
if (in_array($form['group_id'], self::SHARE_PAGE_FORM)) {
continue;
}
}
// $model = new SyncPatientFormJob();
// $model->patientId = intval($this->patientId);
// $model->itemSignId = $query['itemsig_id'];
// $model->itemId = intval($query['item_id']);
// $model->formId = $formId; //747 717;
// $model->checkTimeId = intval($checkTime['checktime_id']); //747 717;
// echo "受试者: [{$query['id']}]. 检查点: [{$checkTime['checktime_id']}]. 表单 [{$formId}]. " . PHP_EOL;
$this->push([
'itemId' => $itemId,
'itemSignId' => $signId,
'patientId' => $this->patientId,
'checkTimeId' => $checkTime['checktime_id'],
'formId' => $this->formId,
]);
}
}
}
}
}
parent::execute($input, $output); // TODO: Change the autogenerated stub
}
/**
* 获取所有受试者id
* @return array
*/
private function getPatients(): array
{
$query = Laminas::$serviceManager->patient->fetchCol('id', [
'item_id' => $this->itemId,
'itemsig_id' => $this->itemSignId,
'is_del' => 0
]);
return array_values($query) ?: [];
}
/**
* 投递任务
*/
private function push($params = [])
{
$this->LocalService()->swTaskClient->send([
'svName' => 'itemExport',
'methodName' => 'execute',
'params' => $params
]);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/9 14:31
* @Description
*
*/
namespace Application\Command;
use Interop\Container\Containerinterface;
use Application\Common\Container;
use Application\Service\Extension\Laminas;
class BasicCommand extends \Symfony\Component\Console\Command\Command
{
protected $container;
public function __construct(Containerinterface $container)
{
parent::__construct(null);
$this->container = $container;
if(empty(Laminas::$serviceManager)) {
Laminas::initialize($this->container->get('Application'));
}
date_default_timezone_set('Asia/Chongqing');
}
public function LocalService(){
return new Container($this->container);
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/3/29 15:12
* @Description
*
*/
namespace Application\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class RunCommand extends BasicCommand
{
protected static string $commandName = 'Run:Server';
protected function configure()
{
$this->setName(self::$commandName);
$this->addOption('sv', null, InputOption::VALUE_REQUIRED, 'Server Name');
$this->addOption('method', null, InputOption::VALUE_REQUIRED, 'Server Method');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->LocalService()->{$input->getOption('sv')}->{$input->getOption('method')}();
return 0;
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/19 8:28
* @Description
*
*/
namespace Application\Command\Swoole\Client;
use Application\Service\BaseService;
use Interop\Container\ContainerInterface;
class SwLogClient extends BaseService
{
protected $swClient;
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
$this->swClient = new \Swoole\Client(SWOOLE_SOCK_TCP | SWOOLE_KEEP);
self::connect();
}
/**
* @files.saveConflictResolution: overwriteFileOnDisk
* @Description: 连接swoole服务器
* @Author: llbjj
* @Date: 2022-07-04 20:23:15
* @return {*}
*/
private function connect() {
$svConfigData = [
'ip' => '127.0.0.1',
'port' => 9509,
'timeout' => -1
];
$isConnect = $this->swClient->connect($svConfigData['ip'], $svConfigData['port'], $svConfigData['timeout']);
if(!$isConnect) {
throw new \Exception("connect failed. Error: {".$this->swClient->errCode."}\n");
}
}
/**
* @files.saveConflictResolution: overwriteFileOnDisk
* @Description: 关闭swoole客户端
* @Author: llbjj
* @Date: 2022-07-04 20:25:50
* @return {*}
*/
private function close() {
$this->swClient->close();
}
/**
* Notes: 投递日志异步任务
* User: llbjj
* DateTime: 2022/5/19 8:54
*
*/
public function send($data){
if(is_array($data)) $data = json_encode($data);
$data .= '|PHENOL|';
$this->swClient->send($data);
self::close();
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/19 8:28
* @Description
*
*/
namespace Application\Command\Swoole\Client;
use Application\Service\BaseService;
use Interop\Container\ContainerInterface;
class SwTaskClient extends BaseService
{
protected $swClient;
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
}
/**
* @files.saveConflictResolution: overwriteFileOnDisk
* @Description: 连接swoole服务器
* @Author: llbjj
* @Date: 2022-07-04 20:23:15
* @return {*}
*/
private function connect() {
$this->swClient = new \Swoole\Client(SWOOLE_SOCK_TCP | SWOOLE_KEEP);
$svConfigData = [
'ip' => '127.0.0.1',
'port' => 9511,
'timeout' => -1
];
$isConnect = $this->swClient->connect($svConfigData['ip'], $svConfigData['port'], $svConfigData['timeout']);
if(!$isConnect) {
throw new \Exception("connect failed. Error: {".$this->swClient->errCode."}\n");
}
}
/**
* @files.saveConflictResolution: overwriteFileOnDisk
* @Description: 关闭swoole客户端
* @Author: llbjj
* @Date: 2022-07-04 20:25:50
* @return {*}
*/
private function close() {
$this->swClient->close();
}
/**
* Notes: 投递日志异步任务
* User: llbjj
* DateTime: 2022/5/19 8:54
*
*/
public function send(array $data){
// 是否开启了异步任务
if($this->LocalService()->config['swAsyncTask']['task']) {
$data['token'] = $this->LocalService()->identity->getToken();
$data['domainName'] = $_SERVER['HTTP_HOST'];
$this->connect();
$data = json_encode($data, true);
$data .= '|PHENOL|';
$this->swClient->send($data);
self::close();
}else{
$this->LocalService()->{$data['svName']}->{$data['methodName']}($data['params']);
}
}
}

View File

@ -0,0 +1,55 @@
<?php
/*
* @files.saveConflictResolution: overwriteFileOnDisk
* @Author: llbjj
* @Date: 2022-07-05 08:26:57
* @LastEditTime: 2022-07-05 14:16:46
* @LastEditors: llbjj
* @Description:
* @FilePath: /RemoteWorking/module/Application/src/Command/Swoole/Server/SwItemTipCommand.php
*/
namespace Application\Command\Swoole\Server;
use Application\Command\BasicCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SwItemTipCommand extends BasicCommand {
protected function execute(InputInterface $input, OutputInterface $output)
{
// 开启websock服务
$wsSv = new \Swoole\WebSocket\Server('0.0.0.0', 9590);
// 监听WebSocket连接打开事件
$wsSv->on('open', function(\Swoole\WebSocket\Server $server, $request) use($output) {
// $output->writeln("server: handshake success with fd{$request->fd}".PHP_EOL);
});
// 监听客户端消息事件
$wsSv->on('message', function(\Swoole\WebSocket\Server $server, $frame) use($output) {
$output->writeln("receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}".PHP_EOL);
});
// 利用swoole的定时器定时请求数据实时推送到客户端timer的简单用法
$addProcess = new \Swoole\Process( function($process) use($wsSv, $output) {
\Swoole\Timer::tick(5000, function (int $timer_id, $wsSv) {
foreach ($wsSv->connections as $fd){
// 根据实际情况获取数据,发送给客户端(目前只是测试数据)
$wsSv->push($fd, $fd.":项目总数量:".$this->LocalService()->itemInfo->getCount().' 个 '.time());
}
}, $wsSv);
});
$wsSv->addProcess($addProcess);
// 监听客户端断开链接
$wsSv->on('close', function($server, $fd) use($output) {
$output->writeln("client {$fd} closed".PHP_EOL);
});
// 启动websock服务
$wsSv->start();
return 0;
}
}

View File

@ -0,0 +1,65 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/12 7:13
* @Description
*
*/
namespace Application\Command\Swoole\Server;
use Swoole\Coroutine;
use Swoole\Process;
use Swoole\Server;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Swoole\Coroutine\Server\Connection;
class SwLogCommand extends \Application\Command\BasicCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('APP_PATH'.APP_PATH);
//开启LogTcp服务
$tcpSv = new Server('127.0.0.1', 9509);
$tcpSv->set([
'worker_num' => 2, // 工作进程数量
'task_worker_num' => 4, // 异步任务进程数
'open_eof_check' => true, //打开EOF检测
'package_eof' => '|PHENOL|', //设置EOF
'package_max_length' => 1024 * 1024 * 5
]);
//接收数据
$tcpSv->on('receive', function ($sv, $fd, $reactorId, $data) use($output) {
$sendDataArr = array_filter(explode('|PHENOL|', $data));
if(!empty($sendDataArr)) {
foreach($sendDataArr as $sendData) {
$sv->task($sendData);
}
}
$output->writeln('oprt Logs writing ...'.PHP_EOL);
});
// 定义异步任务
$tcpSv->on('task', function($sv, $task_id, $src_work_id, $data) use ($output){
$output->writeln('start write Log'.PHP_EOL);
$logObj = $this->LocalService()->log;
if(!$logObj->saveLogToDb($data)){
//日志落库失败,将日志数据存缓存文件中
$logObj->saveLogToFile($data);
}
$sv->finish("{$data} -> OK");
});
//处理异步任务的结果(此回调函数在worker进程中执行)
$tcpSv->on('Finish', function ($serv, $task_id, $data) {
echo "AsyncTask[{$task_id}] Finish: {$data}".PHP_EOL;
});
$tcpSv->start();
//parent::execute($input, $output); // TODO: Change the autogenerated stub
return 0;
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/9/1 15:00
* @Description
*
*/
namespace Application\Command\Swoole\Server;
use Application\Command\BasicCommand;
use Application\Service\Extension\ErrorHandler;
use Application\Service\Extension\Laminas;
use Swoole\Server;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SwTaskCommand extends BasicCommand{
function execute(InputInterface $input, OutputInterface $output)
{
error_reporting(0);
$tcpSv = new Server('127.0.0.1', 9511);
$tcpSv->set([
'worker_num' => 4, // 工作进程数量
'task_worker_num' => 8, // 异步任务进程数
'open_eof_check' => true, //打开EOF检测
'package_eof' => '|PHENOL|', //设置EOF
'package_max_length' => 1024 * 1024 * 5,
'dispatch_mode' => 3,
'task_ipc_mode' => 2,
// 'daemonize' => 1, //以守护进程 1或0
// 'open_eof_split' => true, //swoole底层实现自动分包。比较消耗cpu资源
// 'package_eof' => "|PHENOL|", //设置后缀,一般为"
]);
//接收数据
$tcpSv->on('receive', function ($sv, $fd, $reactorId, $data) use($output) {
$sendDataArr = array_filter(explode('|PHENOL|', $data));
if(!empty($sendDataArr)) {
foreach($sendDataArr as $sendData) {
$sv->task($sendData);
}
}
});
// 定义异步任务
$tcpSv->on('task', function($sv, $task_id, $src_work_id, $data) use ($output){
$taskData = json_decode($data, true);
try {
// 设置Token
Laminas::$token = $taskData['token'] ?? '';
// 调用方法,
$result = $this->LocalService()->{$taskData['svName']}->{$taskData['methodName']}($taskData['params']);
$sv->finish("{$data}");
}catch (\Throwable $throwable) {
$this->saveErrLog($throwable, $taskData);
}
});
//处理异步任务的结果(此回调函数在worker进程中执行)
$tcpSv->on('Finish', function ($serv, $task_id, $data) {
$taskData = json_decode($data, true);
// 发送完成通知
$msgData = [
'title' => "{$taskData['domainName']}】异步任务 {$taskData['svName']}->{$taskData['methodName']}() 执行完成!",
'description' => "AsyncTask[{$task_id}] Finish: {$data}",
'url' => '#'
];
$this->LocalService()->wechatWork->sendMesToUser($msgData);
echo "AsyncTask[{$task_id}] Finish: {$data} -> OK".PHP_EOL;
});
$tcpSv->start();
return 0;
}
public function saveErrLog(&$throwable, &$taskData) {
ErrorHandler::log2txt($throwable, '', $taskData);
}
}

View File

@ -0,0 +1,80 @@
<?php
/*
* @Author: llbjj
* @Date: 2022-07-06 16:18:19
* @LastEditTime: 2022-07-12 18:04:12
* @LastEditors: 863465124 863465124@qq.com
* @Description:
*/
namespace Application\Command\Swoole\Server;
use Application\Command\BasicCommand;
use Application\Common\Com;
use Swoole\Process;
use Swoole\Server;
use Swoole\Timer;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class SwTimerCommand extends BasicCommand {
protected static string $commandName = 'sw:timer';
protected InputInterface $input;
protected OutputInterface $output;
protected function configure()
{
$this->setName(self::$commandName);
$this->addOption('sv', '', InputOption::VALUE_REQUIRED, 'Server Name');
$this->addOption('method', '', InputOption::VALUE_REQUIRED, 'Server Method');
$this->addOption('second', '', InputOption::VALUE_REQUIRED, '任务间隔时间');
$this->addOption('startSecond', '', InputOption::VALUE_REQUIRED, '任务启动时间');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->input = $input;
$this->output = $output;
if($this->input->getOption('startSecond')) {
$this->afterTimer();
}else {
$this->swTimer();
}
return 0;
}
protected function afterTimer() {
swoole_timer_after($this->input->getOption('startSecond'), function() {
$this->swTimer();
});
}
public function swTimer() {
swoole_timer_tick($this->input->getOption('second'), function() {
echo date('Y-m-d H:i:s') . ' -> ' . $this->input->getOption('sv') . ' : ' . $this->input->getOption('method') . PHP_EOL;
$this->LocalService()->{$this->input->getOption('sv')}->{$this->input->getOption('method')}();
});
}
/**
* @Description: 开启一个定时任务信息
* @Author: llbjj
* @Date: 2022-07-11 14:47:30
* @param {*} $timer
* @param {*} $timerName
*/
protected function setTimerFun(array &$timer, string $timerName) {
\Swoole\Timer::tick($timer['msec'], function(int $timer_id) use($timer, $timerName){
$timerContent = date('Y-m-d h:i:s')." 开始定时任务【{$timerName}".PHP_EOL;
Com::writeFile("{$timerName}.log", APP_PATH."/data/log/swooleTimer/{$timerName}/", $timerContent);
$this->LocalService()->{$timer['serviceName']}->{$timer['funName']}();
$nowTime = time();
if(!empty($timer['endTime']) and $nowTime > strtotime($timer['endTime'])){
\Swoole\Timer::clear($timer_id);
}
});
}
}

View File

@ -0,0 +1,294 @@
<?php
namespace Application\Command\Swoole\Server;
use Application\Command\BasicCommand;
use Application\Service\Extension\ErrorHandler;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Swoole\Coroutine;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Process;
use Swoole\WebSocket\CloseFrame;
use Swoole\Coroutine\Http\Server;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Swoole\Coroutine\run;
/**
* https://wiki.swoole.com/#/coroutine/ws_server
*/
class WebSocketCommand extends BasicCommand
{
/** @var int 监听的端口 */
const LISTEN_PORT = 9502;
/**
* 监听host
* @var string
*/
public string $host = '0.0.0.0';
public array $serverConfig = [
'daemonize' => true,
'heartbeat_idle_time' => 60 * 20, //允许最大空闲时间
'heartbeat_check_interval' => 60 * 20, //心跳检测间隔
'ssl_cert_file' => APP_PATH . '/config/autoload/ssl.crt',
'ssl_key_file' => APP_PATH . '/config/autoload/ssl.key',
];
/**
* 用来存储 消息模板。用来做缓存
* @var array
*/
protected static array $messageTemplateContext = [];
protected static array $onlineList = [
'user' => [], // 用户对应的socket连接
];
public function execute(InputInterface $input, OutputInterface $output)
{
set_time_limit(0);// 设置超时时间为无限,防止超时
// Process::daemon();
run(function () {
try {
$server = new Server($this->host, self::LISTEN_PORT, true);
$server->set($this->serverConfig);
$server->handle('/', $this->onHandle());
echo "ws服务已开启 {$this->host}:" . self::LISTEN_PORT . PHP_EOL;
$server->start();
} catch (\Throwable $e) {
echo "ws开启失败. {$e->getMessage()}" . PHP_EOL;
}
});
return 0;
}
/**
* 处理首次请求。验证token.
* @param Request $request
* @param Response $ws
*/
public function handleRequest(Request $request, Response $ws)
{
$header = $request->header;
$token = $header['token'] ?? '';
// 设置token
Laminas::setToken($token);
// if ($token) {
// // 用户id => socket连接
// self::$onlineList['user'][$this->getIdentityId()][] = $ws;
// \Co\defer(function() {
// unset(self::$onlineList['user'][$this->getIdentityId()]);
// });
// }
}
/**
* 处理事件
* @return \Closure
*/
public function onHandle(): \Closure
{
return function (Request $request, Response $ws) {
try {
// 首次连接
$this->handleRequest($request, $ws);
// post请求
if (isset($request->post)) {
$this->handleConnect($request, $ws, null);
$ws->close();
} else {
// websocket
$ws->upgrade();
while (true) {
$frame = $ws->recv();
if ($frame === '') {
$ws->close();
break;
} else if ($frame === false && !isset($request->post)) {
// echo 'errorCode: ' . swoole_last_error() . "\n";
$ws->close();
break;
} else {
$this->handleConnect($request, $ws, $frame);
}
}
}
} catch (\Throwable $exception) {
ErrorHandler::log2txt(print_r([
'type' => get_class($exception),
'file' => method_exists($exception, 'getFile') ? $exception->getFile() : '',
'errorMessage' => $exception->getMessage(),
'executeSql' => method_exists($exception, 'getExecuteSql') ? $exception->getExecuteSql() : null,
'line' => $exception->getLine(),
'stack-trace' => explode("\n", $exception->getTraceAsString()),
]), true);
}
};
}
private function handleConnect($request, $ws, $frame)
{
$d = $frame->data ?? $request->post['data'];
// 心跳
if ($d === 'ping') {
$ws->push('pong');
}
if (($data = StringHelper::jsonDecode($d, false)) !== false) {
if ($response = $this->handleMessage($data, $request, $ws)) {
$ws->push(json_encode($response));
}
}
if ($d == 'close' || $request->post || (is_object($frame) && get_class($frame) === CloseFrame::class)) {
$ws->close();
}
}
/**
* ```
* 小程序端拉取所有消息提示 {"action":"pull", "item_id":"项目id"}
* 推送消息 {"action":"publish", "to":"用户id", "item_id":"123"}
* ```
* @param $data
* @param Request $request
* @return array|void
*/
private function handleMessage($data, Request $request, $ws)
{
$action = $data['action'] ?? '';
if ($action === 'pull') { // 小程序主动拉取
self::$onlineList['user'][$this->getIdentityId()][$data['item_id']][] = $ws;
\Co\defer(function() {
unset(self::$onlineList['user'][$this->getIdentityId()]);
});
$allMessage = $this->getAllMessage($data, $request->fd);
return [
'code' => 0,
'data' => $allMessage
];
} elseif ($action === 'publish') { // 广播
if (stripos($data['to'], ',') !== false) {
$list = explode(',', $data['to']);
} else {
$list = (array)$data['to'];
}
foreach ($list as $userId) {
if (isset(self::$onlineList['user'][$userId][$data['item_id']])) {
foreach (self::$onlineList['user'][$userId][$data['item_id']] as $wsConnect) {
if ($tmp = $this->getUserMessageTemplate($userId, $data['item_id'])) {
$wsConnect->push(json_encode([
'code' => 0,
'data' => $tmp
]));
}
}
}
}
return null;
}
}
/**
* 获取所有消息提醒
* @param $request
* @param $fd
* @return array|mixed|\phpDocumentor\Reflection\Types\Mixed
*/
private function getAllMessage($request, $fd)
{
$tmp = $this->getMessageTemplate($request, $fd);
foreach ($tmp as &$item) {
$item['is_message'] = $this->getIsMessage($item['id'], $this->getIdentityId(), $request['item_id']);
}
return $tmp;
}
private function getUserMessageTemplate($userId, $itemId)
{
$template = self::$messageTemplateContext[$userId] ?? null;
if (!$template) {
return null;
}
foreach ($template as &$item) {
$item['is_message'] = $this->getIsMessage($item['id'], $userId, $itemId);
}
return $template;
}
/**
* 获取用户都有哪些模块
* @param $request
* @return array|mixed|\phpDocumentor\Reflection\Types\Mixed
*/
private function getMessageTemplate($request)
{
if (!isset(self::$messageTemplateContext[$this->getIdentityId()])) {
//获取参数
$user_id = Laminas::$serviceManager->identity->getId();
//var_dump('userId', $user_id);
$item_id = $request['item_id'] ?? 0;
//var_dump('$item_id', $item_id);
$user_id = $this->LocalService()->signatoryUser->findsignatoryUser($user_id);
//查询项目
$itemInfoID = $this->LocalService()->itemInfo->getOneFieldVal('fid', "is_del = 0 and id = " . $item_id) ?: 0;
//查询角色下的角色管理用户信息
$roleSignatoryRelationDatas = $this->LocalService()->roleSignatoryRelation->changeUser($itemInfoID, $user_id);
//var_dump('//查询角色下的角色管理用户信息', $roleSignatoryRelationDatas);
if (!empty($roleSignatoryRelationDatas)) {
$role_id_arr = array_unique(array_column($roleSignatoryRelationDatas, 'role_id'));
//获取当前模块在当前用户的角色中是有操作的权限
$whereroleMenuRelation['where'] = "status = 0 and item_id =" . $itemInfoID . " and role_id in (" . implode(',', $role_id_arr) . ")";
$whereroleMenuRelation['columns'] = ['id', 'module_id'];
$roleMenuRelationDatas = $this->LocalService()->realRolemodulerelation->fetchAll($whereroleMenuRelation);
//var_dump('//获取当前模块在当前用户的角色中是有操作的权限', $roleSignatoryRelationDatas);
if (!empty($roleMenuRelationDatas)) {
$module_id_arr = array_unique(array_column($roleMenuRelationDatas, 'module_id'));
//获取模块菜单
if (!empty($type)) {
$whereadminMenu['where'] = "is_del = 0 and menu_name != '' and status = 0 and menu_type = 1 and id in (" . implode(',', $module_id_arr) . ")";
$whereadminMenu['columns'] = ['id', 'applets_menu' => 'menu_name', 'icon', 'url'];
} else {
$whereadminMenu['where'] = "is_del = 0 and applets_menu != '' and status = 0 and menu_type = 1 and id in (" . implode(',', $module_id_arr) . ")";
$whereadminMenu['columns'] = ['id'];
}
$whereadminMenu['order'] = ['menu_order'];
//var_dump($this->LocalService()->adminMenu->fetchAll($whereadminMenu));
self::$messageTemplateContext[$this->getIdentityId()] = $this->LocalService()->adminMenu->fetchAll($whereadminMenu);
\Co\defer(function () {
unset(self::$messageTemplateContext[$this->getIdentityId()]);
});
}
}
}
return self::$messageTemplateContext[$this->getIdentityId()] ?? [];
}
private function getIdentityId(): ?int
{
return Laminas::$serviceManager->identity->getId();
}
private function getIsMessage($menuId, $userId, $itemId): int
{
return Laminas::$serviceManager->redisExtend->setDatabase(6)->getRedisInstance()->getBit("menu:{$itemId}:{$menuId}", $userId) ?: 0;
}
}

View File

@ -0,0 +1,771 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/9 12:25
* @Description
*
*/
namespace Application\Command;
use Application\Common\Container;
use Application\Common\EventEnum;
use Application\Form\ExportModel;
use Application\Form\FieldForm;
use Application\Form\item\ItemFieldForm;
use Application\Form\item\patient\NormalOCRFormModel;
use Application\Form\item\patient\PatientFormModel;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\DB\Item\PatientFormContentImg;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Middleware\components\FlushFormContentLog;
use Application\Service\Extension\Middleware\Middleware;
use Application\Service\Extension\Validator\ValidatorApplication;
use ApplicationTest\PatientFormTest;
use GuzzleHttp\Client;
use Laminas\Db\Sql\Predicate\Between;
use Laminas\Db\Sql\Predicate\Like;
use Laminas\Db\Sql\Predicate\Operator;
use Swoole\Process;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TestCommand extends BasicCommand
{
public $migrateData;
private $formId;
private $mainId = 0;
private $branchMap = [];
/**
* 字段类型映射
*/
public const CONTENT_MAP = [
'1' => FormField::FORM_FIELD_TYPE_TEXT,
'4' => FormField::FORM_FIELD_TYPE_DATE_UK,
'2' => FormField::FORM_FIELD_TYPE_DATE,
'3' => FormField::FORM_FIELD_TYPE_DATE_SECOND,
'13' => FormField::FORM_FIELD_TYPE_DATE_SECOND,
'5' => FormField::FORM_FIELD_TYPE_INTEGER,
'6' => FormField::FORM_FIELD_TYPE_FLOAT_1,
'7' => FormField::FORM_FIELD_TYPE_FLOAT_2,
'8' => FormField::FORM_FIELD_TYPE_RADIO,
'9' => FormField::FORM_FIELD_TYPE_RADIO,
'10' => FormField::FORM_FIELD_TYPE_CHECKBOX,
'11' => FormField::FORM_FIELD_TYPE_CHECKBOX,
'12' => FormField::FORM_FIELD_TYPE_DROPDOWN,
];
public function contab(){
// $iteminfoData = $this->patientattrUpdate($item=107);
$limit = $_POST['limit'] ?: '5000';
$page = $_POST['page'] ?: '1';
$smallItemId = ['105','103','72','74','77'];
$iteminfoData = $this->newLockItemPatientWorkannex(105,$page,$limit);
echo '成功';die;
return true;
}
public function newLockItemPatientWorkannex($smallItemId,$page,$limit,$type=1){
ini_set('memory_limit', -1);
try {
$i = 0;
$j = '';
if (empty($type)){
$this->is_print_sql = true;
$offset = intval(($page - 1) * $limit);
$whereItemIdentificationresultchange['where'] = 'is_del=0 and lock_state=1 and collect_date !=0 and item_id='.$smallItemId;//and patientworkannex_id !=" "
$whereItemIdentificationresultchange['columns'] =['id','collect_date','lock_state','patientworkannex_id','patient_id','checktime_id','form_id','patient_form_id'];
// $whereItemIdentificationresultchange['group'] = ['patient_id','checktime_id','patient_form_id'];
$whereItemIdentificationresultchange['group'] = ['checktime_id','patient_form_id'];
$whereItemIdentificationresultchange['order'] = ['id desc'];
$whereItemIdentificationresultchange['limit'] = $limit;
$whereItemIdentificationresultchange['offset'] = $offset;
// $itemIdentificationresultchangeCount = $this->LocalService()->itemIdentificationresultchange->getCount($whereItemIdentificationresultchange['where']);
$itemIdentificationresultchangeData = $this->LocalService()->itemIdentificationresultchange->fetchAll($whereItemIdentificationresultchange);
foreach ($itemIdentificationresultchangeData as $k => $itemIdentificationresultchangeDatum) {
echo "正在处理第{$k}" . PHP_EOL;
$newWork['collect_date'] = $itemIdentificationresultchangeDatum['collect_date'] != '' ? strtotime($itemIdentificationresultchangeDatum['collect_date']) : '';
$newWork['change_type'] = 1;
$newWork['lock_state'] = 1;
if (empty($itemIdentificationresultchangeDatum['patient_form_id'])) {
echo '<pre>';print_r($itemIdentificationresultchangeDatum);die;
}
// $where = "id in (".$itemIdentificationresultchangeDatum['patientworkannex_id'].")";
$where = 'is_del=0 and patient_id='.$itemIdentificationresultchangeDatum['patient_id'].' and checktime_id='.$itemIdentificationresultchangeDatum['patient_id'].' and patient_form_id='.$itemIdentificationresultchangeDatum['patient_form_id'];
$resultWork = $this->LocalService()->itemPatientworkannex->update($newWork,$where);
if ($resultWork) {
echo '更新成功' . PHP_EOL;
}
// echo '<pre>';print_r($itemIdentificationresultchangeDatum);die;
$j .= '<pre>'.$page.'--'.$resultWork;
$i++;
}
// var_dump($this->LocalService()->itemPatientworkannex::getDbProfile());
echo $i.$j;die;
}else{
$offset = intval(($page - 1) * $limit);
//时间条件
$time = ' and FROM_UNIXTIME(up_annex_date ,"%Y-%m-%d")="2022-09-17"';
// $time = '';
$whereItemPatientworkannex['where'] = 'is_del=0 and item_id =' . $smallItemId.' and annex_type !=2 and lock_state=0'.$time;//annex_type !=3//只查手动写和图片上传的
$whereItemPatientworkannex['group'] = ['checktime_id','patient_form_id','form_id'];
$whereItemPatientworkannex['columns'] =['id','checktime_id','patient_form_id','form_id','patient_id','item_id'];
$whereItemPatientworkannex['order'] = ['id desc'];
$whereItemPatientworkannex['limit'] = $limit;
$whereItemPatientworkannex['offset'] = $offset;
$itemPatientworkannexData = $this->LocalService()->itemPatientworkannex->fetchAll($whereItemPatientworkannex);
if (!empty($itemPatientworkannexData)){
foreach($itemPatientworkannexData as $itemPatientworkannexDataKey => $itemPatientworkannexDataValue){
echo "正在处理第{$itemPatientworkannexDataKey}" . PHP_EOL;
// $where = 'is_del=0 and lock_state=1 and patientworkannex_id !="" and checktime_id ='.$itemPatientworkannexDataValue['checktime_id'].' and patient_form_id='.$itemPatientworkannexDataValue['patient_form_id'].' and item_id='.$smallItemId.' and patient_id='.$itemPatientworkannexDataValue['checktime_id'];
// and patientworkannex_id !=""
$where = 'is_del=0 and lock_state=1 and checktime_id ='.$itemPatientworkannexDataValue['checktime_id'].' and patient_form_id='.$itemPatientworkannexDataValue['patient_form_id'].' and item_id='.$smallItemId.' and patient_id='.$itemPatientworkannexDataValue['patient_id'];
$wheres['where'] = $where;
$wheres['columns'] = ['id','collect_date','checktime_id','patient_form_id','form_id','patient_id','item_id'];
$changeInfo = $this->LocalService()->itemIdentificationresultchange->fetchOne($wheres);
if (!empty($changeInfo)){
$newWork['collect_date'] = $changeInfo['collect_date'] != '' ? strtotime($changeInfo['collect_date']) :'';
// $newWork['change_type'] = 1;
$newWork['lock_state'] = 1;
$upWhere = 'is_del=0 and patient_id='.$changeInfo['patient_id'].' and item_id='.$changeInfo['item_id'].' and patient_form_id='.$changeInfo['patient_form_id'].' and checktime_id='.$changeInfo['checktime_id'];
$resultWork = $this->LocalService()->itemPatientworkannex->update($newWork,$upWhere);
if ($resultWork) {
echo '更新成功' . PHP_EOL;
}
$j .= '<pre>'.$page.'--'.$resultWork;
}
$i++;
}
}
// var_dump($this->LocalService()->itemPatientworkannex::getDbProfile());
// echo $i.$j;die;
}
}catch (\Throwable $exception) {
var_dump($exception->getMessage());die;
}
}
protected function execute(InputInterface $input, OutputInterface $output)
{
//
$a = new ExportModel();
$a->exportLogicError(['item_id' => 220]);
var_dump($a);die;
;
// 290950,291490,291491,291492,291493
// 远大
Laminas::$serviceManager->itemFormField->update(['is_del' => 1], ['id' => [290950,291490,291491,291492,291493]]);
$v = $this->LocalService()->itemForm->buildFieldVersion(87277);
$this->LocalService()->itemFormVersion->update(['field' => $v], ['form_id' => 87277]);
die;
die;
$postValues = array (
'INDYN' => '1',
'DYN' => '',
'PICT' =>
array (
),
'MCO' => '',
// 'DMSTDAT' => '2024-02-21',
'INQU' => '30',
'INDAT' => '2024-08-21',
);
$expression = SDMHelper::app()->expression->setValues($postValues)->setExpression("((210-INQU)/DATEDIF(INDAT,DMSTDAT,'D'))*1")->execute()->getExecuteCompile();
var_dump($expression);die;
$maxFieldId = 350000;
$endTime = '2024-06-20';
$handleCount = 200;
for ($i = 1; $i <= $maxFieldId; $i = $i + $handleCount) {
$query = Laminas::$serviceManager->patientFormContentImg->fetchAll([
'columns' => ['content_id', 'img_src', 'field_id', 'form_id'],
'where' => [
// new Operator('create_time', Operator::OP_LTE, strtotime($endTime . ' 23:59:59')),
'is_del' => 0,
// 'form_id' => 90712,
// 'patient_id' => 2864,
// 'checktime_id' => 1410,
new Between('form_id', $i + 1, $i + $handleCount),
]
]);
if ($query) {
$allImgData = ArrayHelper::index($query, null, [function($el) {
return $el['content_id'];
}, 'field_id']);
foreach ($allImgData as $contentId => $imgDataItem) {
if (!$contentId) {
continue;
}
$contentData = Laminas::$serviceManager->patientFormContent->fetchOne([
'where' => ['id' => $contentId, 'is_del' => 0]
]) ?: false;
if (SDMHelper::app()->form->getGroupId($contentData['form_id']) == FormGroup::NORMAL_OCR) {
continue;
}
if ($contentData === false) {
echo '数据被删除了, 图片没被删????' . PHP_EOL;
}
$fix = false;
foreach ($imgDataItem as $fieldId => $fieldIdItem) {
if (!$fieldId) {
continue;
}
// echo "正在处理 {$contentId} 的 {$fieldId}" . PHP_EOL;
$contentDataRow = StringHelper::jsonDecode($contentData['data']);
$has = false;
$isDelete = false;
foreach ($contentDataRow as $key => $row) {
if (DataHelper::getFieldId($key) == $fieldId) {
$has = true;
$rowImg = StringHelper::jsonDecode($row);
if (count($rowImg) !== count($fieldIdItem)) {
$con = [
'item_id' => $contentDataRow['item_id'],
'itemsig_id' => $contentDataRow['itemsig_id'],
'patient_id' => $contentDataRow['patient_id'],
'form_id' => $contentDataRow['form_id'],
'checktime_id' => $contentDataRow['checktime_id'], // 贯穿全程
'content_id' => $contentData['id'],
// 'field_id' => $fieldId
];
if (SDMHelper::app()->form->getIsProcess($contentDataRow['form_id'])) {
unset($con['content_id']);
unset($con['checktime_id']);
}
if ($isDelete === false) {
// 把所有旧数据都清理掉
Laminas::$serviceManager->patientFormContentImg->update(['is_del' => 1], $con);
$isDelete = true;
}
foreach ($rowImg as $image) {
$src = DataHelper::handleImageSrc($image['url']);
$condition = array_filter([
'item_id' => $contentDataRow['item_id'],
'itemsig_id' => $contentDataRow['itemsig_id'],
'patient_id' => $contentDataRow['patient_id'],
'form_id' => $contentDataRow['form_id'],
'checktime_id' => $contentDataRow['checktime_id'],
'img_src' => $src,
'img_name' => $image['name'],
// 'img_type' => PatientFormContentImg::IMG_TYPE_NORMAL,
'content_id' => $contentData['id'],
// 'field_id' => $fieldId
]);
$hasImg = Laminas::$serviceManager->patientFormContentImg->fetchOne([
'where' => $condition
]);
$getType = function ($versionField) use ($contentDataRow) {
if ($versionField['type'] != FormField::FORM_FIELD_TYPE_UPLOAD_IMAGE) {
return 0;
}
if ($versionField['var_name'] == 'CHECKIMG') {
if (SDMHelper::app()->form->getGroupId($contentDataRow['form_id']) == FormGroup::CHECK_DO) {
return PatientFormModel::ANNEX_TYPE_DO;
}
return 1;
} elseif (in_array($versionField['var_name'], ['OUTPLANCHECK', 'OPCH'])) {
return 2;
}
return 0;
};
// 没有就insert, 有就把is_del 改成0
if (!$hasImg) {
$versionData = SDMHelper::app()->form->getVersionData($contentDataRow['form_id']);
$type = $getType($versionData[$fieldId]);
Laminas::$serviceManager->patientFormContentImg->save(ArrayHelper::merge($condition, [
'img_type' => $type == 0 ? PatientFormContentImg::IMG_TYPE_NORMAL : $type,
'field_id' => $fieldId,
'create_time' => time()
]));
} else {
Laminas::$serviceManager->patientFormContentImg->update([
'is_del' => 0,
'field_id' => $fieldId,
], ['id' => $hasImg['id']]);
}
}
// var_dump($fieldId);
echo "正在处理 {$contentId}{$fieldId}" . PHP_EOL;
var_dump($rowImg);
var_dump($imgDataItem);
$fix = true;
echo '图片数量不符' . PHP_EOL;
}
}
}
if ($has === false) {
Laminas::$serviceManager->patientFormContentImg->update(['is_del' => 1], [
'content_id' => $contentId
]);
}
}
// if ($fix === true) {
// echo '图片数量不符' . PHP_EOL;
// }
}
}
//
// var_dump($query);die;
}
die;
echo "已处理 $id , 共计 $maxCount" . PHP_EOL;
foreach ($query as $item) {
$newData = $item['new_data'] ? unserialize($item['new_data']) : '';
$oldData = $item['old_data'] ? unserialize($item['old_data']) : '';
$note = $item['change_data'];
// if (!$oldData && stripos(explode(':', $note)[0], '新增') !== false) {
//// echo '新增';
// } elseif ($newData && $oldData && stripos(explode(':', $note)[0], '修改') !== false) {
//// echo '编辑';
// }
$helper = SDMHelper::app()->setAttributes(['content_id' => $item['event_id']])->formContent;
if (Laminas::$serviceManager->patientFormContentUpdatedLog->fetchOne([
'where' => ['create_time' => $item['create_time'], 'content_id' => $item['event_id']]
])) {
echo "跳过 content_id {$item['event_id']}" . PHP_EOL;
continue;
}
$contentLog = [
'item_id' => $helper->getItemId(),
'patient_id' => $helper->getPatientId(),
'form_id' => $helper->getFormId(),
'checktime_id' => $helper->getCheckTimeId(),
'content_id' => $helper->getContentId(),
'data' => json_encode($newData),
'source' => 'HISTORY',
'create_time' => $item['create_time'],
'create_user_id' => $item['user_id']
];
// var_dump($contentLog);
Laminas::$serviceManager->patientFormContentUpdatedLog->isSetInfo(false)->save($contentLog);
}
die('处理完了');
$forms = ArrayHelper::getColumn(Laminas::$serviceManager->itemForm->fetchAll([
'where' => [
'type' => Form::FORM_TYPE_SINGLE,
'is_del' => 0
]
]), 'id');
$arr = [];
$query = Laminas::$serviceManager->patientFormContent->fetchAll([
'where' => ['form_id' => $forms]
]);
foreach ($query as $item) {
$arr[$item['patient_id']][$item['form_id']][] = $item;
}
foreach ($arr as $patientId => $arrItem) {
foreach ($arrItem as $formId => $v) {
if (count($v) > 1) {
$lock = $unlock = [];
$lockOperate = Laminas::$serviceManager->patientFormContentUpdatedLog->fetchOne([
'where' => ['event' => 'LOCK_SHARE_FORM_CONTENT', 'form_id' => $formId, 'checktime_id' => 2, 'patient_id' => $patientId]
]);
foreach ($v as $row) {
if (abs($lockOperate['create_time'] - $row['create_time']) < 1000) {
$lock[] = $row['id'];
} else {
$unlock[] = $row['id'];
}
}
var_dump('lockEvent', $lockOperate['create_time']);
var_dump('锁定', $lock);
var_dump('未锁定', $unlock);
Laminas::$serviceManager->patientFormContent->update([
'is_del' => 1
], ['id' => $unlock]);
Laminas::$serviceManager->patientFormContent->update([
'is_del' => 0,
'is_lock' => 1
], ['id' => $lock]);
}
}
}
die;
// $this->LocalService()->itemFormFieldRadio->update([
// 'relation_information' => '301136'
// ], ['field_id' => 277216]);
// relation_classification: 2
//relation_type: 1
//relation_information: 277219
// $this->LocalService()->itemFormFieldRadio->update([
// 'relation_information' => '277219',
// 'relation_type' => '1',
// 'relation_classification' => '2',
// ], ['field_id' => 277217,]);
$forms = $this->LocalService()->itemForm->fetchAll([
'where' => [
'id' => 4,
'is_del' => 0
]
]);
foreach ($forms as $formId) {
$this->LocalService()->itemFormFieldRadio->update([
'is_check' => 0,
], ['form_id' => $formId['id']]);
$v = $this->LocalService()->itemForm->buildFieldVersion($formId['id']);
$this->LocalService()->itemFormVersion->update(['field' => $v], ['form_id' => $formId['id']]);
}
die;
die;
$query = Laminas::$serviceManager->patientFormContent->fetchAll([
'where' => [
// new Between('id', $id, $id + 200)
// 'id' => 239432
// 'itemsig_id' => 377
]
]);
foreach ($query as $item) {
$generateFields = Laminas::$serviceManager->itemForm->getPreviewConfig($item['form_id'], true)['generateFields'];
$score = false;
$scoreStr = [];
$data = StringHelper::jsonDecode($item['data']);
$versionData = Laminas::$serviceManager->itemFormVersion->getField(['form_id' => $item['form_id']], true);
foreach ($data as $k => &$datum) {
$field = stripos($k, '-') !== false ? explode('-', $k)[0] : $k;
// 有分的先不处理
// if (isset($data['score'])) {
// continue;
// }
if (isset($versionData[$field]) && $versionData[$field]['type'] == 10) {
$child = ArrayHelper::index($versionData[$field]['children'] ?? [], 'value');
if ($child && is_array($child) && isset($child[$datum]) && $child[$datum]['is_score'] == 1 && in_array($k, $generateFields)) {
if ($score === false) {
$score = 0;
}
$score += $child[$datum]['score'];
$scoreStr[] = ['prop' => strval($k), 'score' => intval($child[$datum]['score']), 'is_score' => true];
}
}
}
if ($score !== false) {
$data['score'] = strval($score);
$data['scoreStr'] = $scoreStr;
echo "contentId {$item['id']} 分值为 {$score} 分 patient: {$data['patient_id']} checktime_id: {$data['checktime_id']} formId: {$data['form_id']}" . PHP_EOL;
Laminas::$serviceManager->patientFormContent->isSetInfo(false)->update(['data' => json_encode($data), 'update_time' => $item['update_time']], ['id' => $item['id']]);
}
}
// die;
// var_dump(memory_get_usage());
// }
die;
Laminas::$serviceManager->redisExtend->setDatabase(13)->getRedisInstance()->set('1234', 1234);
Laminas::$serviceManager->redisExtend->setDatabase(13)->getRedisInstance()->set('@@@@', 1234);
Laminas::$serviceManager->redisExtend->getRedisInstance()->set('AAA', 1234);
Laminas::$serviceManager->redisExtend->getRedisInstance()->set('BBBB', 1234);
die;
$a = new PatientFormModel();
$a->setPostValues([
'form_id' => 90694,
'patient_id' => 9010,
]);
$val = $a->view();
var_dump($val);die;
// 305557,305556, 305555, 305563, 305558, 305559, 305560, 305561, 305562, 305541, 305542, 305543
Laminas::$serviceManager->itemFormField->update(['is_del' => 1], ['id' => [305557,305556, 305555]]);
$v = $this->LocalService()->itemForm->buildFieldVersion(90699);
$this->LocalService()->itemFormVersion->update(['field' => $v], ['form_id' => 90699]);
die;
// $ocrData = '{"85209": [{"263962": {"id": "263962", "name": "CASS位置", "value": "-7", "ocr_name": "CASS位置", "var_name": "CASS"}, "263970": {"id": "263970", "name": "描述", "value": "B1型病变", "ocr_name": "描述", "var_name": "OTH"}, "263972": {"id": "263972", "name": "狭窄程度", "value": "75%", "ocr_name": "狭窄程度", "var_name": "XZ"}, "263973": {"id": "263973", "name": "病变形态", "value": "节段、偏心、累及分支", "ocr_name": "病变形态", "var_name": "PAMO"}, "263975": {"id": "263975", "name": "病变部位", "value": "1前降支中段", "ocr_name": "介入部位名称", "var_name": "NAME"}}], "85210": [{"263977": {"id": "263977", "name": "支架名称", "value": "药物洗脱冠脉支架系统RSINT", "ocr_name": "支架装置名称", "var_name": "ZNAM"}, "263978": {"id": "263978", "name": "直径", "value": "3.0", "ocr_name": "直径", "var_name": "DIAM"}, "263979": {"id": "263979", "name": "长度", "value": "30", "ocr_name": "长度", "var_name": "LEN"}, "263980": {"id": "263980", "name": "置入部位", "value": "LAD病变处", "ocr_name": "置入/扩张部位", "var_name": "POS"}}], "85211": [{"263982": {"id": "263982", "name": "球囊名称", "value": "一次性使用血管内球囊扩张导管WOTE", "ocr_name": "球囊装置名称", "var_name": "QNAM"}, "263983": {"id": "263983", "name": "直径", "value": "2.0", "ocr_name": "直径", "var_name": "QDIA"}, "263984": {"id": "263984", "name": "长度", "value": "20", "ocr_name": "长度", "var_name": "QLEN"}, "263985": {"id": "263985", "name": "扩张部位", "value": "LAD病变处", "ocr_name": "置入/扩张部位", "var_name": "EXS"}}, {"263982": {"id": "263982", "name": "球囊名称", "value": "冠脉球囊导管Quantum", "ocr_name": "球囊装置名称", "var_name": "QNAM"}, "263983": {"id": "263983", "name": "直径", "value": "3.25", "ocr_name": "直径", "var_name": "QDIA"}, "263984": {"id": "263984", "name": "长度", "value": "15", "ocr_name": "长度", "var_name": "QLEN"}, "263985": {"id": "263985", "name": "扩张部位", "value": "LAD支架内", "ocr_name": "置入/扩张部位", "var_name": "EXS"}}, {"263982": {"id": "263982", "name": "球囊名称", "value": "冠脉球囊导管Quantum", "ocr_name": "球囊装置名称", "var_name": "QNAM"}, "263983": {"id": "263983", "name": "直径", "value": "3.75", "ocr_name": "直径", "var_name": "QDIA"}, "263984": {"id": "263984", "name": "长度", "value": "12", "ocr_name": "长度", "var_name": "QLEN"}, "263985": {"id": "263985", "name": "扩张部位", "value": "LAD支架内", "ocr_name": "置入/扩张部位", "var_name": "EXS"}}]}';
// $params = [
// 'patient_id' => 9316,
// 'form_id' => 90689,
// 'checktime_id' => 202402,
// ];
$model = new \Application\Form\item\patient\NormalOCRFormModel();
$model->importMultiRow(82016);
die;
$handleCount = 200;
$maxCount = Laminas::$serviceManager->patientFormContentUpdatedLog->fetchOne([
'order' => 'id DESC',
])['id'];
for ($id = 0; $id < $maxCount; $id = $id + $handleCount) {
$query = Laminas::$serviceManager->patientFormContentUpdatedLog->fetchAll([
'where' => [
new Between('id', $id + 1, $id + $handleCount),
]
]);
echo "已处理 $id , 共计 $maxCount" . PHP_EOL;
$container = [];
foreach ($query as $item) {
if (!isset($container[$item['patient_id']])) {
$container[$item['patient_id']] = Laminas::$serviceManager->patient->fetchOne([
'where' => [
'id' => $item['patient_id'],
'is_del' => 0
]
])['itemsig_id'] ?? false;
if ($container[$item['patient_id']] === false) {
echo '受试者' . $item['patient_id'] . '有问题??' . PHP_EOL;
continue;
}
}
Laminas::$serviceManager->patientFormContentUpdatedLog->isSetInfo(false)->update([
'sign_id' => $container[$item['patient_id']]
], ['id' => $item['id']]);
}
}
die('处理完了');
return 0;
die;
Laminas::$serviceManager->itemFormField->update(['type' => FormField::FORM_FIELD_TYPE_DATE_UK], ['id' => 301227]);
$v = $this->LocalService()->itemForm->buildFieldVersion(90373);
$this->LocalService()->itemFormVersion->update(['field' => $v], ['form_id' => 90373]);
die;
$query = Laminas::$serviceManager->itemPatientAeContent->fetchAll([
'where' => [
'ae_type' => 6,
'is_del' => 0
]
]);
foreach ($query as $v) {
$has = Laminas::$serviceManager->itemCsaeRelation->fetchAll([
'where' => [
'csae_id' => $v['csae_id'],
'new_ae_list_id' => 0,
'content_id' => $v['id'],
'patient_id' => $v['patient_id'],
'branch' => $v['branch']
]
]);
if (!$has) {
var_dump($v);
}
}
var_dump('ok');die;
$handleCount = 200;
$maxCount = Laminas::$serviceManager->adminLog->fetchOne([
'order' => 'id DESC',
])['id'];
for ($id = 0; $id < $maxCount; $id = $id + $handleCount) {
$query = Laminas::$serviceManager->adminLog->fetchAll([
'where' => [
new Between('id', $id + 1, $id + $handleCount),
'log_url' => '/patient/form/create',
// 'id' => 81566
]
]);
echo "已处理 $id , 共计 $maxCount" . PHP_EOL;
foreach ($query as $item) {
$newData = $item['new_data'] ? unserialize($item['new_data']) : '';
$oldData = $item['old_data'] ? unserialize($item['old_data']) : '';
$note = $item['change_data'];
// if (!$oldData && stripos(explode(':', $note)[0], '新增') !== false) {
//// echo '新增';
// } elseif ($newData && $oldData && stripos(explode(':', $note)[0], '修改') !== false) {
//// echo '编辑';
// }
$helper = SDMHelper::app()->setAttributes(['content_id' => $item['event_id']])->formContent;
if (Laminas::$serviceManager->patientFormContentUpdatedLog->fetchOne([
'where' => ['create_time' => $item['create_time'], 'content_id' => $item['event_id']]
])) {
echo "跳过 content_id {$item['event_id']}" . PHP_EOL;
continue;
}
$contentLog = [
'item_id' => $helper->getItemId(),
'patient_id' => $helper->getPatientId(),
'form_id' => $helper->getFormId(),
'checktime_id' => $helper->getCheckTimeId(),
'content_id' => $helper->getContentId(),
'data' => json_encode($newData),
'source' => 'HISTORY',
'create_time' => $item['create_time'],
'create_user_id' => $item['user_id']
];
// var_dump($contentLog);
Laminas::$serviceManager->patientFormContentUpdatedLog->isSetInfo(false)->save($contentLog);
}
}
die('处理完了');
return 0;
}
private function handleChild($child, $fieldId = null)
{
echo 'FIELD_ID -> ' . $fieldId . PHP_EOL;
// if (isset($child['children'])) {
// $this->handleChild($child['children']);
// }
$itemData = [];
$formType = 'TEXT';
foreach ($child['relation'] ?? $child['children'] as $k => $item) {
if ($item['info_from'] == 0) {
$k = $item['info_id'];
if (!$this->migrateData['batchContents']['content'][$k]) {
if ($item['p']) {
$k = "{$item['info_id']}-{$item['p']}";
if (!$this->migrateData['batchContents']['content'][$k]) {
throw new \Exception("not found info id!!!!{$item['info_id']}-{$item['p']}");
}
}
}
$itemData['parent'] = $item['parent_id'];
$itemData = $this->migrateData['batchContents']['content'][$k];
} elseif ($item['info_from'] == 1) {
$formType = 'RADIO';
if (!$this->migrateData['batchContents']['options'][$item['info_id']]) {
throw new \Exception("not found info id{$item['info_id']}");
}
$itemData = $this->migrateData['batchContents']['options'][$item['info_id']];
$itemData['parent'] = $item['parent_id'];
} elseif ($item['info_from'] == 2) {
if (!$this->migrateData['batchContents']['content']['info_id']) {
throw new \Exception("not found info id###");
}
$itemData = $this->migrateData['content']['info_id'];
}
$itemData['form_id'] = $this->formId;
$itemData['name'] = $itemData['tips'];
unset($itemData['tips']);
if (!$itemData['name']) {
if ($item['info_from'] != 3) {
$itemData['name'] = $itemData['form_option'] ?? '??????????';
} else {
$itemData['name'] = '5555555';
}
}
$itemData['type'] = self::CONTENT_MAP[$itemData['content_type']] ?? 0;
$itemData['parent'] = $this->branchMap[$itemData['parent']] ?? 0;
$itemData['form_type'] = $formType;
$itemData['value'] = $k;
$itemData['relation_classification'] = 2;
$itemData['relation_type'] = 1;
$itemData['relation_information'] = $itemData['parent'];
$itemData['is_list'] = 0;
$itemData['is_anchor'] = $itemData['content_type'] == 13 ? 1 : 0;
$itemData['is_booked_time'] = 0;
$itemData['item_id'] = 2;
$itemData['origin_form_id'] = $itemData['form_id'];
$v = new ValidatorApplication($itemData);
$v->attach(
[['form_id', 'item_id'], 'required'],
[['form_type'], 'default', 'value' => FieldForm::FORM_CONFIG_TEXT],
[['is_list', 'is_booked_time'], 'default', 'value' => 0]
);
$model = new ItemFieldForm($v);
$fieldId = $model->createField();
if ($itemData['type'] != 0) {
if (isset($itemData['parent_id']) && isset($this->branchMap[$itemData['parent_id']])) {
$this->mainId = $this->branchMap[$itemData['parent_id']];
} else {
$this->mainId = $fieldId;
}
$this->branchMap[$item['info_id']] = $fieldId;
}
if (isset($item['children'])) {
if ($item['info_from'] == 3) {
$item['p'] = $item['info_id'];
}
$this->handleChild($item, $fieldId);
}
}
}
}

View File

@ -0,0 +1,59 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/9 12:25
* @Description
*
*/
namespace Application\Command;
use Application\Service\Extension\Helper\ArrayHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Co\run;
class UnitTestCommand extends BasicCommand
{
/**
* 脚本描述.
* @var string
*/
protected static $defaultDescription = '运行单元测试实例。';
protected function configure()
{
$this
->addArgument(
'files',
InputArgument::IS_ARRAY
)
;
}
public function execute(InputInterface $input, OutputInterface $output)
{
$updateFiles = $input->getArguments();
run(function() use ($updateFiles) {
// $ret = \Swoole\Coroutine\System::exec("/usr/bin/php vendor/bin/phpunit module/Application/test/model --coverage-html report");
$unitTestFiles = [
'phpunit.xml.dist',
'module/Application/test/model/BaseTestUnit.php',
'module/Application/test/model/DictionaryFormTest.php',
'module/Application/test/model/HelperTest.php',
'module/Application/test/model/PatientFormTest.php',
'module/Application/test/model/PatientModelTest.php',
];
$file = implode(' ', ArrayHelper::merge($unitTestFiles, $updateFiles['files']));
$ret = \Swoole\Coroutine\System::exec("git fetch && git checkout origin/develop {$file} && /usr/bin/php vendor/bin/phpunit");
echo $ret['output'];
});
return 0;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Application\Common;
class BehaviorsEnum
{
/** @var string 通过进度管理删除表单数据 */
const BEHAVIOR_PATIENT_FORM_DELETE_FROM_PROGRESS_MANAGE = 'BEHAVIOR_PATIENT_FORM_DELETE_FROM_PROGRESS_MANAGE';
const BEHAVIOR_MESSAGE = [
'PROJECT_AE_RESULT_DISCARD' => '断开关联关系'
];
}

View File

@ -0,0 +1,893 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/5 20:27
* @Description
*
*/
namespace Application\Common;
use Application\Exception\UserException;
use Application\Service\DB\Dictionary\FormField;
use Laminas\Db\Sql\Predicate\Like;
use Laminas\Stdlib\ArrayUtils;
class Com
{
/**
* Notes:获取两个日期差多少天
* User: lltyy
* DateTime: 2023/8/22 11:14
*
* @param $str //数值
* @param $digit //小数位数
* @return false|float|string
*/
public static function diffDateDay($date1='',$date2='')
{
$diff_days = 0;
if(!empty($date1) && !empty($date2)){
$date1_str = substr($date1,0,4).'-'.substr($date1,4,2).'-'.substr($date1,6,2);
$date2_str = substr($date2,0,4).'-'.substr($date2,4,2).'-'.substr($date2,6,2);
$time1 = strtotime($date1_str);
$time2 = strtotime($date2_str);
$diff_seconds = abs($time1 - $time2);
$diff_days = floor($diff_seconds / (24 * 60 * 60));
}
return $diff_days;
}
/**
* Notes: 去除无用字符串
* User: lltyy
* DateTime: 2023/6/8 15:07
*
* @param string $str
* @param int $type 类型【0 结果 1 时间 2 识别项 3 识别项 4 识别项拆分末尾数字】
* @return string|string[]|null
*/
public function replaceData($str='',$type=0){
if($str != ''){
if($type == 3){
$str = preg_replace("/\\d+/",'', $str);
}
if($type == 0){
$str = str_replace(',','.',$str);
$str = str_replace(' 。','.',$str);
$str = str_replace("'",'',$str);
$str = str_replace('-','',$str);
$str = str_replace('*','',$str);
$str = str_replace(':','',$str);
$str = str_replace('?','',$str);
}
$delete_result_arr = ["","","","","",":","·","/","","","","","","","","","——","","~","!","@","#","$","%","^","&","*","(",")","-","_","+","{","}",";","|",",","","","","[","]","","……"];
$have_result_arr = ["","","","","",":","·","/","","","","","","","","","——","","~","!","@","#","$","%","^","&","*","(",")","-","_","+","=","{","}",";","|",",","<",">","","","","","","[","]","","……"];
if(!in_array($type,[0,4])){
$delete_result_arr[] = '=';
$delete_result_arr[] = '.';
$delete_result_arr[] = "<";
$delete_result_arr[] = ">";
$delete_result_arr[] = "";
$delete_result_arr[] = "";
$delete_result_arr[] = "";
$delete_result_arr[] = "";
$have_result_arr[] = '.';
$have_result_arr[] = '↑';
$have_result_arr[] = '↓';
}
$chinese_regular = '/([\x80-\xff]*)/i';//汉字正则
$big_letter_regular = '/[A-Z]/';//大写字母正则
$small_letter_regular = '/[a-z]/';//小写字母正则
if($type == 4){
$judge_str = '';
if(strpos($str,'↑')){
$judge_str = '↑';
}
if(strpos($str,'↓')){
$judge_str = '↓';
}
$new_rawname_str = str_replace(['↑','↓'],'',$str);//替换字符串中的特殊字符
$split_name_arr = mb_str_split($new_rawname_str);
$end_chinese = '';//最后一个汉字
$all_number = '';//最后一个汉字之后的数字
$last_number = '';
$chinese_regular = '/[\x7f-\xff]+/';//汉字正则
$end_str_type = 0;
if(!empty($split_name_arr)){
foreach($split_name_arr as $split_name){
//判断字符串类型
$str_type = 0;
if(is_numeric($split_name)){//是数字
$str_type = 1;
}else{
if($split_name == '.'){//是数字
$str_type = 1;
}else{
$new_split_name = str_replace($have_result_arr,'',$split_name);//替换字符串中的特殊字符
if($new_split_name == ''){
$str_type = 3;
}else{
$new_split_name = preg_replace($chinese_regular,'',$split_name);//去除字符串中的汉字
$new_split_name = preg_replace($big_letter_regular,'',$new_split_name);//去除字符串中的大写字母
$new_split_name = preg_replace($small_letter_regular,'',$new_split_name);//去除字符串中的小写字母
if($new_split_name == ''){
$str_type = 2;
}
}
}
}
if($end_chinese != ''){
if($str_type == 1){
$all_number .= $split_name;
}elseif($str_type == 2){
$end_chinese = $split_name;
$all_number = '';
}elseif($str_type == 3){
if($end_str_type != 3 || $last_number == ''){
$last_number = $all_number;
}
$end_chinese = $split_name;
$all_number = '';
}
}else{
if($str_type == 2){
$end_chinese = $split_name;
$all_number = '';
}elseif($str_type == 3){
if($end_str_type != 3 || $last_number == ''){
$last_number = $all_number;
}
$end_chinese = $split_name;
$all_number = '';
}
}
$end_str_type = $str_type;
}
}
if($end_str_type == 3){
$all_number = $last_number;
}
if($all_number != ''){
$all_number .= $judge_str;
}
$str = $all_number;
}else{
if(!in_array($str,$have_result_arr)){
$str = str_replace($delete_result_arr,'',$str);//替换字符串中的特殊字符
if($type != 3){
$str = preg_replace($chinese_regular,'',$str);//去除字符串中的汉字
}
$str = preg_replace($big_letter_regular,'',$str);//去除字符串中的大写字母
$str = preg_replace($small_letter_regular,'',$str);//去除字符串中的小写字母
}else{
$str = '';
}
}
}
$str = $str != '' ? $str : '';
if($str != '' && $type == 1){
if(in_array(substr($str,0,2),['21','22','23'])){
$str = '20'.$str;
}
if(in_array(substr($str,0,3),['020','021','022','023'])){
$str = '2'.$str;
}
if(in_array(substr($str,0,5),['22020','22021','22022','22023'])){
$str = substr_replace($str,'2',0,2);
}
if(in_array(substr($str,0,6),['222020','222021','222022','222023'])){
$str = substr_replace($str,'2',0,3);
}
if(in_array(substr($str,0,7),['2222020','2222021','2222022','2222023'])){
$str = substr_replace($str,'2',0,4);
}
}
unset($delete_result_arr);
unset($have_result_arr);
unset($chinese_regular);
unset($big_letter_regular);
unset($small_letter_regular);
return $str;
}
/**
* Notes: 验证日期
* User: lltyy
* DateTime: 2023/6/25 9:31
*
* @param string $annex_date
* @return array
*/
public static function validAnnexDate($annex_date=''){
$code = 200;
$msg = '';
//截取日期前8位数字
$annex_date = self::replaceData($annex_date,2);
$annex_date = !empty($annex_date) ? substr($annex_date,0,8) : '';
//判断报告时间是否符合要求
if(empty($annex_date)){
$code = 60010;
$msg = '采集时间不能为空!';
}else{
$annex_date_year = substr($annex_date,0,4);
$annex_date_month = substr($annex_date,4,2);
$annex_date_day = substr($annex_date,6,2);
$annex_date_str = $annex_date_year.'-'.$annex_date_month.'-'.$annex_date_day;
$date_reg = "/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/";
//匹配日期格式
if (preg_match ($date_reg, $annex_date_str, $parts)) {
//检测是否为日期,checkdate为月日年
if (checkdate($parts[2], $parts[3], $parts[1])) {
$code = 200;
}else{
$code = 60011;
$msg = '采集时间格式不正确【正确格式如20210607】';
}
}else{
$code = 60011;
$msg = '采集时间格式不正确【正确格式如20210607】';
}
if($code == 200){
$nowYear = date('Y');
if(intval($annex_date_year) > $nowYear){
$code = 60011;
$msg = '采集时间所属年份【'.$annex_date_year.'】不能超过当前年份【'.$nowYear.'】!';
}else{
if(intval($annex_date_year) < 2020){
$code = 60012;
$msg = '采集时间所属年份【'.$annex_date_year.'】不在【2020~~'.$nowYear.'】之间!';
}
}
}
}
return ['code'=>$code,'msg'=>$msg,'date'=>$annex_date];
}
/**
* Notes:验证时间
* User: lltyy
* DateTime: 2024/3/27 11:21
*
* @param string $annex_date
* @param int $type 【0 时分 1 小时】
* @return array
*/
public static function validAnnexDatetime($annex_date='',$type = 0){
$code = 200;
$msg = '';
//截取日期前4位数字
$new_annex_date = !empty($annex_date) ? substr($annex_date,0,4) : '';
if($type == 1){
$new_annex_date = !empty($annex_date) ? substr($annex_date,0,2) : '';
}
//判断报告时间是否符合要求
if(empty($annex_date)){
$code = 60010;
$msg = '不能为空!';
}else{
if($type == 1){
$new_annex_date = !empty($annex_date) ? substr($annex_date,0,2) : '';
$time_hour = substr($new_annex_date,0,2);
$time_str = $time_hour;
$time_reg = "/^([01]?[0-9]|2[0-3])$/";
//匹配日期格式
if (preg_match ($time_reg, $time_str)) {
$code = 200;
}else{
$code = 60011;
$msg = '格式不正确【正确格式如09】';
}
}else{
$time_hour = substr($new_annex_date,0,2);
$time_sceond = substr($new_annex_date,2,2);
$time_str = $time_hour.':'.$time_sceond;
$time_reg = "/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/";
//匹配日期格式
if (preg_match ($time_reg, $time_str)) {
$code = 200;
}else{
$code = 60011;
$msg = '格式不正确【正确格式如0909】';
}
}
}
return ['code'=>$code,'msg'=>$msg,'date'=>$new_annex_date];
}
/**
* Notes:Notes:识别结果去除首尾多余的1
* User: lltyy
* DateTime: 2024/2/18 9:06
*
* 1》上下箭头 在前面且结果大于最大值2倍首位是1去掉1后依然大于最大值则首位1直接去掉
* 2》上下箭头 在后面如果尾数为1且结果大于2两倍最大值去掉尾数1后小于最小值则直接去掉尾数1如果去掉尾数1大于最大值则去掉尾数1
*
* @param string $result
* @param string $min
* @param string $max
* @return string|string[]
*/
public static function cutResultOne($result='',$min='',$max='')
{
$new_result = $result;
if($result != '' && is_numeric($result)){
//首位是1
$firstDigit = substr(strval($new_result), 0, 1);
if($firstDigit == 1){
$first_set_judge = self::getResultSetJudge($new_result,$min,$max);
if(in_array($first_set_judge,[4])){
$firstCheckResult = substr_replace($new_result,'',0,1);
$first_check_set_judge = self::getResultSetJudge($firstCheckResult,$min,$max);
if(in_array($first_check_set_judge,[2,4])){
$new_result = $firstCheckResult;
}
}
}
//尾数为1
$endDigit = substr(strval($new_result), -1);
if($endDigit == 1){
$end_set_judge = self::getResultSetJudge($new_result,$min,$max);
if(in_array($end_set_judge,[4])){
$endCheckResult = substr_replace($new_result,'',-1);
$end_check_set_judge = self::getResultSetJudge($endCheckResult,$min,$max);
if(in_array($end_check_set_judge,[1,3,2,4])){
$new_result = $endCheckResult;
}
}
}
}
return $new_result;
}
/**
* Notes:结果判断异常
* User: lltyy
* DateTime: 2024/2/18 9:06
*
* @param string $result
* @param string $set_min
* @param string $set_max
* @return int
* $set_judge
* 0正常
* 1
* 2
* 3超低【低于最小值的二分之一】
* 4超高【高于最大值的2倍】
*/
public static function getResultSetJudge($result='',$set_min='',$set_max=''){
$result = is_null($result) || $result == '' ? '' : trim($result);
$set_min = is_null($set_min) || $set_min == '' ? '' : trim($set_min);
$set_max = is_null($set_max) || $set_max == '' ? '' : trim($set_max);
$set_judge = 0;
if($result != '' && is_numeric($result)){
if($set_min != ''){
if($result < $set_min){
$set_judge = 1;
//判断是否低于最小值2倍
$set_min_two = $set_min/2;
if($result <= $set_min_two){//超低
$set_judge = 3;
}
}else{
if($set_max != ''){
if(strpos($set_max,'<') !== false){
$set_max_number = str_replace('<','',$set_max);
if($result >= $set_max_number){
$set_judge = 2;
//判断是否高于最大值2倍
$set_max_two = $set_max_number*2;
if($result >= $set_max_two){//超高
$set_judge = 4;
}
}
}else{
if($result >= $set_max){
$set_judge = 2;
//判断是否高于最大值2倍
$set_max_two = $set_max*2;
if($result >= $set_max_two){//超高
$set_judge = 4;
}
}
}
}
}
}else{
if($set_max != ''){
if(strpos($set_max,'<') !== false){
$set_max_number = str_replace('<','',$set_max);
if($result >= $set_max_number){
$set_judge = 2;
//判断是否高于最大值2倍
$set_max_two = $set_max_number*2;
if($result >= $set_max_two){//超高
$set_judge = 4;
}
}
}else{
if($result >= $set_max){
$set_judge = 2;
//判断是否高于最大值2倍
$set_max_two = $set_max*2;
if($result >= $set_max_two){//超高
$set_judge = 4;
}
}
}
}
}
}
return $set_judge;
}
/**
* Notes:保留小数位数【多余直接舍弃】
* User: lltyy
* DateTime: 2023/8/22 11:14
*
* @param $str //数值
* @param $digit //小数位数
* @return false|float|string
*/
public static function numberDigit($str,$digit)
{
$new_str = $str;
if(is_numeric($str)) {
$last_digit = $digit+1;
switch ($digit) {
case 0:
$new_str = floor($str);
break;
default:
$new_str = sprintf("%.".$digit."f",substr(sprintf('%.'.$last_digit.'f',$str),0,-1));
break;
}
}
return $new_str;
}
/**
* Notes: 字符串切片
* User: llbjj
* DateTime: 2023/4/26 10:14
*
* @param string $str
* @return array
*/
public static function cutIntoSlices(string $str)
{
$result = [];
if($str != '') {
$strLen = mb_strlen($str);
for ($i = 0; $i < $strLen; $i++) {
$splitStr = $i ? mb_substr($str, $i) : $str;
for($len = $i ? 2 : 1; $len <= mb_strlen($splitStr); $len++) {
$splitArr = mb_str_split($splitStr, $len);
$result = ArrayUtils::merge($result, $splitArr);
}
}
}
return array_unique($result);
}
public function getTree($data, $pid = 0,$type = 0,$level = 2,$field = 'fid'){
$tree = [];
foreach($data as $k => $v){
$v['icon'] = $v['icon'] ?: 'formOcr';
if (isset($v['parent_id'])){
if(($v['parent_id'] == $pid)){
if (!empty($type) && $v['level'] > $level){
continue;
}
$v['children'] = $this->getTree($data, $v['id'],$type,$level);
$tree[] = $v;
unset($data[$k]);
}
}else{
if(($v[$field] == $pid)){
$v['children'] = $this->getTree($data, $v['id'],$type,$level,$field);
$tree[] = $v;
// unset($data[$k]);
}
}
}
return $tree;
}
/**
* 无限分类
* **/
public function getTreed($arr){
$items = array();
foreach($arr as $v){
$items[$v['id']] = $v;
}
$tree = array();
foreach($items as $k => $item){
if(isset($items[$item['pid']])){
$items[$item['pid']]['children'][] = &$items[$k];
}else{
$tree[] = &$items[$k];
}
}
return $tree;
}
/**
* 无限分类
* **/
public function getTreeall($arr,$pid=0,$step=0,$name='',$pidname=''){
global $tree;
foreach($arr as $key=>$val) {
if($val[$pidname] == $pid) {
$flg = str_repeat("&nbsp;&nbsp;&nbsp;",$step);
$val[$name] = $flg.$val[$name];
$tree[] = $val;
$this->getTreeallAction($arr , $val['id'] ,$step+1);
}
}
return $tree;
}
/**
* Notes: 组合sql WHERE条件
*
* @param array $searchArr
* @param array $formFieldData
* @param int $returnType 0/字符串 1、数组
* @return string
*/
public static function CreateSearchWhere(array $searchArr, array $formFieldData, $returnType = 0){
$popData = ['limit', 'page'];
$search_where_data = ['1'];
foreach($searchArr as $field => $searchVal){
if(!empty($formFieldData[$field]) && $searchVal !== ''){
switch($formFieldData[$field]['type']){
case 'Input':
array_push($search_where_data, new Like($field, "%{$searchVal}%"));
break;
default:
$search_where_data[$field] = $searchVal;
}
}
}
return $returnType ? $search_where_data : implode(' and ', $search_where_data);
}
/**
* Notes: 获取每个表单模块的说明数组select的options数组格式
*
* @return array
*/
public static function getSearchFormEventData(){
$result = [];
$eventFormData = include APP_PATH.'/formData/formMap.php';
if(!empty($eventFormData)){
foreach($eventFormData as $eventCode => $eventLabel){
$result[] = ['label' => $eventLabel, 'value' => $eventCode];
}
}
return $result;
}
/**
* @Description: 获取两个不同时间的相差的毫秒数(暂时不支持结束时间小于开始时间)
* @Author: llbjj
* @Date: 2022-07-11 14:17:11
* @param {string} $startDate 开始时间
* @param {string} $endDate 结束时间
* @return int
*/
public static function getDiffMs(string $startDate, string $endDate):int
{
// 开始时间 大于 结束时间,直接返回 0
if($startDate > $endDate) return 0;
$isMoreThan = false;
$oneDayMs = 86400000;
$diffMs = 0;
$start_time = date_create($startDate);
$end_time = date_create($endDate);
$dateDiffObj = date_diff($end_time, $start_time);
$date_params_arr = ['y', 'm', 'd', 'h', 'i', 's'];
foreach($date_params_arr as $date_param){
$diffVal = $dateDiffObj->{$date_param};
if($diffVal){
switch($date_param) {
case 'h': $diffMs += $diffVal * 60 * 60 * 1000; break;
case 'i': $diffMs += $diffVal * 60 * 1000; break;
case 's': $diffMs += $diffVal * 1000; break;
default: $isMoreThan = true;break;
}
}
}
// 如果日期差超出一天,直接获取相差的天数
if($isMoreThan) $diffMs += floor((strtotime($endDate) - strtotime($startDate)) / 86400) * $oneDayMs;
return $diffMs;
}
/**
* @Description: 将内容写入文件中
* @Author: llbjj
* @Date: 2022-07-12 17:17:11
* @param {string} $fileName 开始时间
* @param {string} $filePath 结束时间
* @param {string} $fileContent 文件内容
*/
public static function writeFile(string $fileName, string $filePath, string $fileContent)
{
try{
if($fileContent !== ''){
if(!file_exists($filePath)) {
mkdir($filePath, 0777, true);
}
if(substr($filePath, -1, 1) != '/') $filePath .= '/';
file_put_contents($filePath.$fileName, $fileContent, FILE_APPEND);
}
}catch(\Exception $e){
return false;
}
}
/**
* 执行树型数据生成
* @param array $data 要进行转化的数据
* @param string $children 子节点下标名称默认为children
* @param string $defaultID ID节点下标名称默认为'id'
* @param string $parentID 父节点下标名称默认为pid
* @param string $defaultTitle title节点下标名称默认为title
*/
public static function get_tree_data(array &$data, $children = 'children', $defaultID = 'id', $parentID = 'pid', $defaultTitle = 'title'){
$collection_data = [];
foreach ($data as $item) {
foreach($item as $field_key=>$field_val){
if($field_key == $defaultID){
$collection_data[$item[$defaultID]]['id'] = $field_val;
}else if($field_key == $defaultTitle){
$collection_data[$item[$defaultID]]['title'] = $field_val;
}else if($field_key == $parentID){
$collection_data[$item[$defaultID]][$parentID] = $field_val;
}else{
$collection_data[$item[$defaultID]][$field_key] = $field_val;
}
}
$collection_data[$item[$defaultID]][$children] = [];
}
foreach ($collection_data as $key => $item) {
if(isset($item[$parentID]) and isset($collection_data[$item[$parentID]])){
if (isset($item[$parentID]) and $item[$parentID] != 0 && count($collection_data[$item[$parentID]]) > 1) {
$collection_data[$item[$parentID]][$children][] = &$collection_data[$key];
if (empty($collection_data[$key][$children])) unset($collection_data[$key][$children]);
}
}
}
$tree = [];
foreach($collection_data as $key => &$item) {
if ($item[$parentID] != 0) unset($collection_data[$key]);
if (empty($item[$children])) unset($item[$children]);
if(isset($collection_data[$key]) and $collection_data[$key]){
$tree[] = $collection_data[$key];
}
}
return $tree;
}
/**
* 执行树型数据生成
* @param array $data 要进行转化的数据
* @param string $children 子节点下标名称默认为children
* @param string $defaultID ID节点下标名称默认为'id'
* @param string $parentID 父节点下标名称默认为pid
* @param string $defaultTitle title节点下标名称默认为title
*/
public static function get_treeoption_data(array &$data, $children = 'children', $defaultID = 'value', $parentID = 'pid', $defaultTitle = 'label'){
$collection_data = [];
foreach ($data as $item) {
foreach($item as $field_key=>$field_val){
if($field_key == $defaultID){
$collection_data[$item[$defaultID]][$defaultID] = $field_val;
}else if($field_key == $defaultTitle){
$collection_data[$item[$defaultID]][$defaultTitle] = $field_val;
}else if($field_key == $parentID){
$collection_data[$item[$defaultID]][$parentID] = $field_val;
}else{
$collection_data[$item[$defaultID]][$field_key] = $field_val;
}
}
$collection_data[$item[$defaultID]][$children] = [];
}
foreach ($collection_data as $key => $item) {
if(isset($item[$parentID]) and isset($collection_data[$item[$parentID]])){
if (isset($item[$parentID]) and $item[$parentID] != 0 && count($collection_data[$item[$parentID]]) > 1) {
$collection_data[$item[$parentID]][$children][] = &$collection_data[$key];
//if (empty($collection_data[$key][$children])) unset($collection_data[$key][$children]);
}
}
}
$tree = [];
foreach($collection_data as $key => &$item) {
if ($item[$parentID] != 0) unset($collection_data[$key]);
//if (empty($item[$children])) unset($item[$children]);
if(isset($collection_data[$key]) and $collection_data[$key]){
$tree[] = $collection_data[$key];
}
}
return $tree;
}
/**
* 执行树型数据生成
* @param array $data 要进行转化的数据
* @param string $children 子节点下标名称默认为children
* @param string $defaultID ID节点下标名称默认为'id'
* @param string $parentID 父节点下标名称默认为pid
* @param string $defaultTitle title节点下标名称默认为title
*/
public static function get_newtree_data(array &$data, $children = 'children', $defaultID = 'id', $parentID = 'pid', $defaultTitle = 'title'){
$collection_data = [];
foreach ($data as $item) {
foreach($item as $field_key=>$field_val){
if($field_key == $defaultID){
$collection_data[$item[$defaultID]]['id'] = $field_val;
}else if($field_key == $defaultTitle){
$collection_data[$item[$defaultID]]['title'] = $field_val;
}else if($field_key == $parentID){
$collection_data[$item[$defaultID]][$parentID] = $field_val;
}else{
$collection_data[$item[$defaultID]][$field_key] = $field_val;
}
}
$collection_data[$item[$defaultID]][$children] = [];
}
foreach ($collection_data as $key => $item) {
if(isset($item[$parentID]) and isset($collection_data[$item[$parentID]])){
if (isset($item[$parentID]) and $item[$parentID] != 0 && count($collection_data[$item[$parentID]]) > 1) {
$collection_data[$item[$parentID]][$children][] = &$collection_data[$key];
if (empty($collection_data[$key][$children])) unset($collection_data[$key][$children]);
}
}
}
$tree = [];
foreach($collection_data as $key => &$item) {
if ($item[$parentID] != 0) unset($collection_data[$key]);
if (empty($item[$children])) unset($item[$children]);
if (empty($item[$children])) unset($item['disabled']);
if(isset($collection_data[$key]) and $collection_data[$key]){
$tree[] = $collection_data[$key];
}
}
return $tree;
}
/**
* Notes:转换化验单识别结果
* @param array $ocrResult
*/
public static function changeOcrResult(array &$ocrResult) : array
{
$keyMap = [
'项目名称/编码' => 'item_name',
'项目名称' => 'item_name',
'结果' => 'result',
'单位' => 'unit',
'参考值' => 'reference_range',
'采样时间' => 'collect_date',
'参考范围' => 'reference_range',
'检验结果' => 'result',
'计量单位' => 'unit',
];
$result = [];
// 将结果存放到表中
if(!empty($ocrResult)) {
foreach($ocrResult as &$item) {
$row = [];
foreach($item as $key => &$val) {
if(!isset($keyMap[$key])) continue;
$row[$keyMap[$key]] = $val;
if($key === '参考值') {
$reference_range = str_ireplace(['--', '~'], '-', $val);
$rangeData = explode('-', $reference_range);
$row['reference_range_min'] = $rangeData[0] ?? '';
$row['reference_range_max'] = $rangeData[1] ?? '';
}
}
$result[] = $row;
}
}
return $result;
}
/**
* Notes: 获取图片的大小
* User: llbjj
* DateTime: 2024/5/28 17:02
*
* @param string $file
* @return false|int|mixed
*/
public static function customFilesize(string $file) {
$isHttp = strpos($file, '://');
if($isHttp) {
$header = get_headers($file, 1);
return $header['Content-Length'];
}else return filesize($file);
}
/**
* @note 字符串脱敏
* @param string|null $str
* @return string
*/
public static function maskingPhoneNumber( ?string $str): string
{
$replacement = '****';
$start = 3;
$end = -2;
$length = mb_strlen($str, 'UTF-8');
if($length < 6) {
return $replacement;
}
return mb_substr($str, 0, $start, 'UTF-8') . $replacement . mb_substr($str, $length + $end, $length, 'UTF-8');
}
/**
* @note 验证表单字段类型是否是日期类型
* @return bool
*/
public static function isValidDateField($formFieldType): bool
{
return in_array ($formFieldType, [
FormField::FORM_FIELD_TYPE_DATE_UK, // 日期(UK)
FormField::FORM_FIELD_TYPE_DATE, // 日期(年月日)
FormField::FORM_FIELD_TYPE_DATETIME, // 日期(年月日时分秒)
FormField::FORM_FIELD_TYPE_DATE_SECOND, // 日期(年月日时分)
FormField::FORM_FIELD_TYPE_DATETIME_UK, // 日期(年月日时分UK)
FormField::FORM_FIELD_TYPE_DATETIME_SECOND_UK, // 日期(年月日时分秒UK)
FormField::FORM_FIELD_TYPE_TIME_UK, // 日期(时分UK)
FormField::FORM_FIELD_TYPE_TIME_SECOND_UK, // 日期(时分秒Uk)
]);
}
}

View File

@ -0,0 +1,713 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/6 10:25
* @Description
*
*/
namespace Application\Common;
use Application\Command\Swoole\Client\SwLogClient;
use Application\Command\Swoole\Client\SwTaskClient;
use Application\SdmWork\WorkUser;
use Application\Service\Baidu\Ocr as BaiduOcr;
use Application\Service\DB\Admin\Appletsmenu;
use Application\Service\DB\Admin\Appletsrolemenurelation;
use Application\Service\DB\Admin\Configtable;
use Application\Service\DB\Admin\Log;
use Application\Service\DB\Admin\Menu;
use Application\Service\DB\Admin\Realrole;
use Application\Service\DB\Admin\Realrolesignatoryrelation;
use Application\Service\DB\Admin\Role;
use Application\Service\DB\Admin\Rolemenurelation;
use Application\Service\DB\Admin\Send;
use Application\Service\DB\Admin\User;
use Application\Service\DB\Admin\Userrolerelation;
use Application\Service\DB\Admin\Websitefiling;
use Application\Service\DB\Collect\Annex as CollectAnnex;
use Application\Service\DB\Collect\Category as CollectCategory;
use Application\Service\DB\Collect\Cost as CollectCost;
use Application\Service\DB\Collect\Ct as CollectCt;
use Application\Service\DB\Collect\Custom as CollectCustom;
use Application\Service\DB\Collect\Drug as CollectDrug;
use Application\Service\DB\Collect\Drugcategory as CollectDrugcategory;
use Application\Service\DB\Collect\Ecg as CollectEcg;
use Application\Service\DB\Collect\Hospital as CollectHospital;
use Application\Service\DB\Collect\Inspect as CollectInspect;
use Application\Service\DB\Collect\Itemcost as CollectItemcost;
use Application\Service\DB\Collect\Itemct as CollectItemct;
use Application\Service\DB\Collect\Itemdrug as CollectItemdrug;
use Application\Service\DB\Collect\Itemecg as CollectItemecg;
use Application\Service\DB\Collect\Itemhospital as CollectItemhospital;
use Application\Service\DB\Collect\Itemkeyword as CollectItemkeyword;
use Application\Service\DB\Collect\Itemout as CollectItemout;
use Application\Service\DB\Collect\Itemreport as CollectItemreport;
use Application\Service\DB\Collect\Keyword as CollectKeyword;
use Application\Service\DB\Collect\Keywordcat as CollectKeywordcat;
use Application\Service\DB\Collect\Medicaltake as CollectMedicaltake;
use Application\Service\DB\Collect\Medicalword as CollectMedicalword;
use Application\Service\DB\Collect\Out as CollectOut;
use Application\Service\DB\Collect\Patient as CollectPatient;
use Application\Service\DB\Collect\Patientct as CollectPatientct;
use Application\Service\DB\Collect\Patientecg as CollectPatientecg;
use Application\Service\DB\Collect\Patienthospital as CollectPatienthospital;
use Application\Service\DB\Collect\Patientmedical as CollectPatientmedical;
use Application\Service\DB\Collect\Patientmedicalblack as CollectPatientmedicalblack;
use Application\Service\DB\Collect\Patientmedicaldrug as CollectPatientmedicaldrug;
use Application\Service\DB\Collect\Patientmedicallock as CollectPatientmedicallock;
use Application\Service\DB\Collect\Patientmedicalwhite as CollectPatientmedicalwhite;
use Application\Service\DB\Collect\Patientout as CollectPatientout;
use Application\Service\DB\Collect\Patientraw as CollectPatientraw;
use Application\Service\DB\Collect\Patientrawblack as CollectPatientrawblack;
use Application\Service\DB\Collect\Patientrawlock as CollectPatientrawlock;
use Application\Service\DB\Collect\Patientrawmate as CollectPatientrawmate;
use Application\Service\DB\Collect\Patientreport as CollectPatientreport;
use Application\Service\DB\Collect\Rawword as CollectRawword;
use Application\Service\DB\Collect\Report as CollectReport;
use Application\Service\DB\Collect\Sighospital as CollectSighospital;
use Application\Service\DB\Collect\Sigkeyword as CollectSigkeyword;
use Application\Service\DB\Collect\Sigout as CollectSigout;
use Application\Service\DB\Collect\Table as CollectTable;
use Application\Service\DB\Collect\Text as CollectText;
use Application\Service\DB\Dictionary\Checkcategory;
use Application\Service\DB\Dictionary\Checkname;
use Application\Service\DB\Dictionary\Checknameattr;
use Application\Service\DB\Dictionary\Checknameweight;
use Application\Service\DB\Dictionary\Csset;
use Application\Service\DB\Dictionary\Detectblackword as DictionaryDetectblackword;
use Application\Service\DB\Dictionary\Detectkeyword as DictionaryDetectkeyword;
use Application\Service\DB\Dictionary\Detectname as DictionaryDetectname;
use Application\Service\DB\Dictionary\Document;
use Application\Service\DB\Dictionary\Drug as DictionaryDrug;
use Application\Service\DB\Dictionary\Drugcategory as DictionaryDrugcategory;
use Application\Service\DB\Dictionary\Region as DictionaryRegion;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\DB\Dictionary\FormRelation;
use Application\Service\DB\Dictionary\FormVersion;
use Application\Service\DB\Dictionary\Genercsetinfo;
use Application\Service\DB\Dictionary\Genercsetinfotype;
use Application\Service\DB\Dictionary\ItemForm;
use Application\Service\DB\Dictionary\ItemFormField;
use Application\Service\DB\Dictionary\ItemFormFieldRadio;
use Application\Service\DB\Dictionary\ItemFormFieldText;
use Application\Service\DB\Dictionary\ItemFormGroup;
use Application\Service\DB\Dictionary\Itemjob;
use Application\Service\DB\Dictionary\Medicaltake as DictionaryMedicaltake;
use Application\Service\DB\Dictionary\Medicalword as DictionaryMedicalword;
use Application\Service\DB\Dictionary\Patientattr;
use Application\Service\DB\Dictionary\Patientattrselect;
use Application\Service\DB\Dictionary\Questionanswer;
use Application\Service\DB\Dictionary\Questionconfig;
use Application\Service\DB\Dictionary\Unblinding;
use Application\Service\DB\Dictionary\Leverform;
use Application\Service\DB\Dictionary\Levervalue;
use Application\Service\DB\Export\Sas as ExportSas;
use Application\Service\DB\Item\Allowpatientwrite;
use Application\Service\DB\Item\Answer;
use Application\Service\DB\Item\Appletsdata;
use Application\Service\DB\Item\Blindmethodlog;
use Application\Service\DB\Item\Blockgroup;
use Application\Service\DB\Item\Checktime;
use Application\Service\DB\Item\Confirm;
use Application\Service\DB\Item\Downpicture;
use Application\Service\DB\Item\Eventwatchdog;
use Application\Service\DB\Item\Export;
use Application\Service\DB\Item\Exportpdf;
use Application\Service\DB\Item\File;
use Application\Service\DB\Item\Formmodel;
use Application\Service\DB\Item\Formpatientsign;
use Application\Service\DB\Item\Imgtxtdiscern;
use Application\Service\DB\Item\Info;
use Application\Service\DB\Item\Informedconsent;
use Application\Service\DB\Item\Informedconsentsign;
use Application\Service\DB\Item\ItemDrugbatch as ItemDrugbatch;
use Application\Service\DB\Item\ItemFormVersion;
use Application\Service\DB\Item\ItemInfosign;
use Application\Service\DB\Item\ItemLogicErrorReportBlack;
use Application\Service\DB\Item\ItemPatientdrugbatch as ItemPatientdrugbatch;
use Application\Service\DB\Item\ItemPatientdrugset as ItemPatientdrugset;
use Application\Service\DB\Item\ItemRemarks;
use Application\Service\DB\Item\ItemResultidentify as ItemResultidentify;
use Application\Service\DB\Item\ItemSigdrugbatch as ItemSigdrugbatch;
use Application\Service\DB\Item\ItemSigdrugset as ItemSigdrugset;
use Application\Service\DB\Item\Jobstaff;
use Application\Service\DB\Item\Lock;
use Application\Service\DB\Item\Logtype;
use Application\Service\DB\Item\Medication;
use Application\Service\DB\Item\Patient;
use Application\Service\DB\Item\PatientAeContent;
use Application\Service\DB\Item\Patientattrs;
use Application\Service\DB\Item\PatientCard;
use Application\Service\DB\Item\Patientchecktime;
use Application\Service\DB\Item\PatientChecktimeList;
use Application\Service\DB\Item\PatientForm;
use Application\Service\DB\Item\PatientFormContent;
use Application\Service\DB\Item\PatientFormContentCm;
use Application\Service\DB\Item\PatientFormContentDelete;
use Application\Service\DB\Item\PatientFormContentImg;
use Application\Service\DB\Item\Patientformimgcontent as ItemPatientformimgcontent;
use Application\Service\DB\Item\PatientFormLogicError;
use Application\Service\DB\Item\PatientFormLogicErrorLog;
use Application\Service\DB\Item\PatientFormLogicErrorPointer;
use Application\Service\DB\Item\PatientFormLogicErrorQuery;
use Application\Service\DB\Item\PatientFormUnlock;
use Application\Service\DB\Item\PatientWorkCount;
use Application\Service\DB\Item\Question;
use Application\Service\DB\Item\Randblock;
use Application\Service\DB\Item\Randgroup;
use Application\Service\DB\Item\Randnumber;
use Application\Service\DB\Item\Random;
use Application\Service\DB\Item\Randomdetails;
use Application\Service\DB\Item\Reply;
use Application\Service\DB\Item\Researchstage;
use Application\Service\DB\Item\Rolemodulerelation;
use Application\Service\DB\Item\Sign;
use Application\Service\DB\Item\Signatory as itemSignatory;
use Application\Service\DB\Item\SignatoryCollecttypeocr;
use Application\Service\DB\Item\Signatorypatient;
use Application\Service\DB\Item\Urgentunblind;
use Application\Service\DB\Item\Vicecopy;
use Application\Service\DB\Log\LogLogin;
use Application\Service\DB\Medical\Lock as MedicalLock;
use Application\Service\DB\Medical\Mateblack as MedicalMateblack;
use Application\Service\DB\Medical\Matedrug as MedicalMatedrug;
use Application\Service\DB\Medical\Matewhite as MedicalMatewhite;
use Application\Service\DB\Medical\Ocrdata as MedicalOcrdata;
use Application\Service\DB\Ocr\Annextype as OcrAnnextype;
use Application\Service\DB\Ocr\Caseremark as OcrCaseremark;
use Application\Service\DB\Ocr\Changetype as OcrChangetype;
use Application\Service\DB\Ocr\Ct as OcrCt;
use Application\Service\DB\Ocr\Ctcase as OcrCtcase;
use Application\Service\DB\Ocr\Ctreplace as OcrCtreplace;
use Application\Service\DB\Ocr\Deletename as OcrDeletename;
use Application\Service\DB\Ocr\Drug as OcrDrug;
use Application\Service\DB\Ocr\Drugcategory as OcrDrugcategory;
use Application\Service\DB\Ocr\Keyword as OcrKeyword;
use Application\Service\DB\Ocr\Loseannex as OcrLoseannex;
use Application\Service\DB\Ocr\Mateblack as OcrMateblack;
use Application\Service\DB\Ocr\Matedata as OcrMatedata;
use Application\Service\DB\Ocr\Matedrug as OcrMatedrug;
use Application\Service\DB\Ocr\Matewhite as OcrMatewhite;
use Application\Service\DB\Ocr\Medical as OcrMedical;
use Application\Service\DB\Ocr\Medicallock as OcrMedicallock;
use Application\Service\DB\Ocr\Medicalword as OcrMedicalword;
use Application\Service\DB\Ocr\Ocrannex as OcrOcrannex;
use Application\Service\DB\Ocr\Ocrannexnew as OcrOcrannexnew;
use Application\Service\DB\Ocr\OcrMatesearch as OcrMatesearch;
use Application\Service\DB\Ocr\Rawblack as OcrRawblack;
use Application\Service\DB\Ocr\Rawdata as OcrRawdata;
use Application\Service\DB\Ocr\Rawlock as OcrRawlock;
use Application\Service\DB\Ocr\Rawlockunique as OcrRawlockunique;
use Application\Service\DB\Ocr\Rawword as OcrRawword;
use Application\Service\DB\Ocr\Replace as OcrReplace;
use Application\Service\DB\Ocr\Sigkeyword as OcrSigkeyword;
use Application\Service\DB\Ocr\Sigpatient as OcrSigpatient;
use Application\Service\DB\Ocr\Specialmedical as OcrSpecialmedical;
use Application\Service\DB\Ocr\Take as OcrTake;
use Application\Service\DB\Odm\OdmSyncRecord;
use Application\Service\DB\Pay\Recharge;
use Application\Service\DB\Project\Backupschange;
use Application\Service\DB\Project\Changesendlog;
use Application\Service\DB\Project\Csae;
use Application\Service\DB\Project\Doctoridea;
use Application\Service\DB\Project\Identificationexport;
use Application\Service\DB\Project\Identificationresult;
use Application\Service\DB\Project\Identificationresultchange;
use Application\Service\DB\Project\Identificationresultdestroy;
use Application\Service\DB\Project\Patientworkannex;
use Application\Service\DB\Project\Setocrfield;
use Application\Service\DB\Signatory\Department;
use Application\Service\DB\Signatory\Info as signatoryInfo;
use Application\Service\DB\Signatory\User as signatoryUser;
use Application\Service\DB\Temple\checklist;
use Application\Service\DB\Tmp\Annex as TmpAnnex;
use Application\Service\DB\Tmp\Ctreplace as TmpCtreplace;
use Application\Service\DB\Tmp\Custom as TmpCustom;
use Application\Service\DB\Tmp\Deletename as TmpDeletename;
use Application\Service\DB\Tmp\Doctoradviceannex as TmpDoctoradviceannex;
use Application\Service\DB\Tmp\Doctoradviceformal as TmpDoctoradviceformal;
use Application\Service\DB\Tmp\Doctoradvicelock as TmpDoctoradvicelock;
use Application\Service\DB\Tmp\Doctoradvicemateblack as TmpDoctoradvicemateblack;
use Application\Service\DB\Tmp\Doctoradvicematedrug as TmpDoctoradvicematedrug;
use Application\Service\DB\Tmp\Doctoradvicematewhite as TmpDoctoradvicematewhite;
use Application\Service\DB\Tmp\Doctoradviceoriginal as TmpDoctoradviceoriginal;
use Application\Service\DB\Tmp\Doctoradvicepatient as TmpDoctoradvicepatient;
use Application\Service\DB\Tmp\Doctoradvicereplace as TmpDoctoradvicereplace;
use Application\Service\DB\Tmp\Doctoradvicetable as TmpDoctoradvicetable;
use Application\Service\DB\Tmp\Drug as TmpDrug;
use Application\Service\DB\Tmp\Drugcategory as TmpDrugcategory;
use Application\Service\DB\Tmp\Hospital as TmpHospital;
use Application\Service\DB\Tmp\Inspect as TmpInspect;
use Application\Service\DB\Tmp\Intervene as TmpIntervene;
use Application\Service\DB\Tmp\Intervene0 as TmpIntervene0;
use Application\Service\DB\Tmp\Intervene1 as TmpIntervene1;
use Application\Service\DB\Tmp\Intervene2 as TmpIntervene2;
use Application\Service\DB\Tmp\Keyword as TmpKeyword;
use Application\Service\DB\Tmp\Medical as TmpMedical;
use Application\Service\DB\Tmp\Medicalblack as TmpMedicalblack;
use Application\Service\DB\Tmp\Medicaldrug as TmpMedicaldrug;
use Application\Service\DB\Tmp\Medicallock as TmpMedicallock;
use Application\Service\DB\Tmp\Medicaltake as TmpMedicaltake;
use Application\Service\DB\Tmp\Medicalwhite as TmpMedicalwhite;
use Application\Service\DB\Tmp\Medicalword as TmpMedicalword;
use Application\Service\DB\Tmp\Outmedical as TmpOutmedical;
use Application\Service\DB\Tmp\Patient as TmpPatient;
use Application\Service\DB\Tmp\Patientct as TmpPatientct;
use Application\Service\DB\Tmp\Patienthospital as TmpPatienthospital;
use Application\Service\DB\Tmp\Rawblack as TmpRawblack;
use Application\Service\DB\Tmp\Rawdata as TmpRawdata;
use Application\Service\DB\Tmp\Rawlock as TmpRawlock;
use Application\Service\DB\Tmp\Rawmate as TmpRawmate;
use Application\Service\DB\Tmp\Rawword as TmpRawword;
use Application\Service\DB\Tmp\Replace as TmpReplace;
use Application\Service\DB\Tmp\Report as TmpReport;
use Application\Service\DB\Tmp\Sigkeyword as TmpSigkeyword;
use Application\Service\DB\Tmp\Table as TmpTable;
use Application\Service\DB\Tmp\Text as TmpText;
use Application\Service\DB\Item\ItemMedicaltake;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Identity\Identity;
use Application\Service\Extension\Sms\SmsApplication;
use Application\Service\Extension\Uploader\ImageUploader;
use Application\Service\Extension\Wechat\Wechat;
use Application\Service\Extension\Wechat\WechatWork;
use Application\Service\HttpSv;
use Application\Service\Logic\form\CheckFormLogic;
use Application\Service\Login\LoginClient;
use Application\Service\Logs;
use Application\Service\OA\OaClient;
use Application\Service\Project\OcrCasePatientSpecialdetail as ItemOcrCasePatientSpecialdetail;
use Application\Service\Project\OcrCasePatientSpecialdetailNew as ItemOcrCasePatientSpecialdetailNew;
use Application\Service\Project\OcrCsaePatientDetail as ItemOcrCsaePatientDetail;
use Application\Service\Project\OcrCsaePatientDetailNew as ItemOcrCsaePatientDetailNew;
use Application\Service\Redis\RedisExtend;
use Application\Service\ToolSys\SyncOcrAnnex;
use Application\Service\ToolSys\ToolSys;
use Laminas\Http\Request;
use Psr\Container\ContainerInterface;
use Application\Service\DB\Doctoradvice\DoctoradviceOriginal as DoctoradviceOriginal;
use Application\Service\DB\Item\Patientinfo as ItemPatientinfo;
use Application\Service\DB\Item\Signaturebatch AS ItemSignaturebatch;
use Application\Service\DB\Item\Signaturedetail AS ItemSignaturedetail;
use Application\Service\DB\Item\Detectpatient AS ItemDetectpatient;
use Application\Service\DB\Dictionary\Ocrreplace AS DictionaryOcrreplace;
use Application\Service\DB\Item\Cissclass AS ItemCissclass;
use Application\Service\DB\Item\Cissoption AS ItemCissoption;
use Application\Service\DB\Item\Patientciss AS ItemPatientciss;
use Application\Service\DB\Dictionary\Fixednametype;
use Application\Service\DB\Dictionary\Fixedname;
use Application\Service\DB\Project\Msgset AS ProjectMsgset;
use Application\Service\DB\Project\Msginfo AS ProjectMsginfo;
use Application\Service\DB\Project\Msgsend AS ProjectMsgsend;
use Application\Service\DB\Item\Planviolate;
use Application\Service\DB\Admin\Weblink;
use Application\Service\DB\Admin\Workbatch AS AdminWorkbatch;
use Application\Service\DB\Admin\Workinfo AS AdminWorkinfo;
use Application\Service\DB\Dictionary\Eventset as DictionaryEventset;
use Application\Service\DB\Dictionary\Eventsttr as DictionaryEventattr;
use Application\Service\DB\Admin\Medicallock AS AdminMedicallock;
use Application\Service\DB\Item\Patientevent AS ItemPatientevent;
use Application\Service\DB\Item\Patienteventannex AS ItemPatienteventannex;
use Application\Service\DB\Item\Patienteventset AS ItemPatienteventset;
use Application\Service\DB\Project\Patientwork AS ProjectPatientwork;
use Application\Service\DB\Item\Randomsecondary AS ItemRandomsecondary;
use Application\Service\DB\Project\Medicalquestion AS ProjectMedicalquestion;
use Application\Service\DB\Project\Medicalquestioninfo AS ProjectMedicalquestioninfo;
use Application\Service\DB\Project\Medicalconfirm AS ProjectMedicalconfirm;
use Application\Service\DB\Project\Medicalconfirminfo AS ProjectMedicalconfirminfo;
use Application\Service\DB\Project\Medicalset AS ProjectMedicalset;
use Application\Service\DB\Item\Checkdate AS ItemCheckdate;
use Application\Service\DB\Project\Patientworkbatch AS ProjectPatientworkbatch;
use Application\Service\DB\Project\Patientworkinfo AS ProjectPatientworkinfo;
use Application\Service\DB\Dictionary\Region AS Region;
use Application\Service\DB\Item\PatientFormContentUpdatedLog as PatientFormContentUpdatedLog;
use Application\Service\DB\Project\Exceedswindow;
use Application\Service\DB\Project\Cmdrugset AS ProjectCmdrugset;
use Application\Service\DB\Collect\Patientdrug AS CollectPatientdrug;
use Application\Service\DB\Dictionary\Itemcategory AS DictionaryItemcategory;
use Application\Service\DB\Item\Package AS ItemPackage;
/**
*
* Class Container
* @package Application\Common
*
* ----------------------- ↓↓↓组件↓↓↓ ---------------------------
* @property Request $request
* @property RedisExtend $redisExtend redis组件
* @property ImageUploader $imageUploader 文件上传组件
* @property Wechat $wechat wechat组件
* @property SmsApplication $sms sms组件
* @property Identity $identity identity
* @property Logs $log log
* @property Formatter $formatter
* @property HttpSv $httpSv
* @property WorkUser $workUser
* @property WechatWork $wechatWork
* @property BaiduOcr $ocr 百度文字识别
* @property ToolSys $toolSys
* @property SyncOcrAnnex $syncOcrAnnex
* @property SDMHelper $SDMHelper
* @property OaClient $OAClient
* @property CheckFormLogic $CheckFormLogic
* @property LoginClient $loginClient
* ----------------------- ↓↓↓Swoole客户端↓↓↓ --------------------
* @property SwLogClient $swLogClient
* @property SwTaskClient $swTaskClient
* ----------------------- ↓↓↓数据库↓↓↓ --------------------------
* @property Info $itemInfo
* @property itemSignatory $itemSignatory
* @property Superrole $itemSuperrole
* @property Menu $adminMenu
* @property User $adminUser
* @property Role $adminRole
* @property Rolemenurelation $roleMenuRelation
* @property Userrolerelation $userRoleRelation
* @property Checkcategory $dictionaryCheckcategory
* @property Checkname $dictionaryCheckname
* @property Checknameattr $dictionaryChecknameattr
* @property Csset $dictionaryCsset
* @property Document $dictionaryDocument
* @property Genercsetinfo $dictionaryGenercsetinfo
* @property Genercsetinfotype $dictionaryGenercsetinfotype
* @property Itemjob $dictionaryItemjob
* @property Unblinding $dictionaryUnblinding
* @property Leverform $dictionaryLeverform
* @property Levervalue $dictionaryLevervalue
* @property Ocr $dictionaryOcr
* @property Patientattr $dictionaryPatientattr
* @property Patientattrselect $dictionaryPatientattrselect
* @property Realrole $realRole
* @property Log $adminLog
* @property signatoryInfo $signatoryInfo
* @property signatoryUser $signatoryUser
* @property Department $signatoryDepartment
* @property Patient $patient
* @property PatientForm $patientForm
* @property PatientFormContent $patientFormContent
* @property PatientFormContentImg $patientFormContentImg 表单填写化验单图片表
* @property Patientattrs $patientattrs
* @property Form $dictionaryForm
* @property Region $dictionaryRegion
* @property FormRelation $dictionaryFormRelation
* @property FormVersion $dictionaryFormVersion
* @property FormGroup $dictionaryFormGroup
* @property PatientCard $patientCard
* @property Randblock $itemRandblock
* @property Randgroup $itemRandgroup
* @property Randnumber $itemRandnumber
* @property Randomdetails $itemRandomdetails
* @property Random $itemRandom
* @property Blockgroup $itemBlockgroup
* @property Medication $itemMedication
*
* @property FormField $dictionaryFormField
* @property ItemFormFieldText $dictionaryFormFieldText
* @property FormField $dictionaryFormFieldRadio
* @property ItemForm $itemForm
* @property PatientFormContentCm $patientFormContentCm
* @property ItemFormVersion $itemFormVersion
* @property ItemFormGroup $itemFormGroup
* @property ItemFormField $itemFormField
* @property ItemFormFieldRadio $itemFormFieldRadio
* @property ItemFormFieldText $itemFormFieldText
* @property Rolemodulerelation $realRolemodulerelation
* @property ItemDrugbatch $itemDrugbatch
* @property ItemSigdrugbatch $itemSigdrugbatch
* @property ItemSigdrugset $itemSigdrugset
* @property ItemPatientdrugbatch $itemPatientdrugbatch
* @property ItemPatientdrugset $itemPatientdrugset
* @property Jobstaff $itemJobstaff
* @property Patientchecktime $itemPatientchecktime
* @property Informedconsent $itemInformedconsent
* @property Patientworkannex $itemPatientworkannex
* @property Identificationresult $itemIdentificationresult
* @property Identificationresultchange $itemIdentificationresultchange
* @property Unblinding $itemUnblinding
* @property Checkname $itemCheckname
* @property Imgtxtdiscern $itemImgtxtdiscern
* @property Urgentunblind $itemUrgentunblind
* @property File $itemFile
* @property Setocrfield $dictionarySetocrfield
* @property Question $itemQuestion
* @property Reply $itemReply
* @property Export $itemExport
* @property Csae $itemCsae
* @property Appletsmenu $adminAppletsmenu
* @property Appletsrolemenurelation $adminAppletsrolemenurelation
* @property Appletsdata $itemAppletsdata
* @property Vicecopy $itemVicecopy
* @property Researchstage $itemResearchstage
* @property Checktime $itemChecktime
* @property Informedconsentsign $itemInformedconsentsign
* @property Downpicture $itemDownpicture
* @property Answer $itemQuestionanswer
* @property Signatorypatient $signatoryPatient
* @property Realrolesignatoryrelation $roleSignatoryRelation
* @property PatientAeContent $itemPatientAeContent
* @property DictionaryRule $dictionaryRule
* @property DictionaryFormtype $dictionaryFormtype
* @property DictionaryFormtyperule $dictionaryFormtyperule
* @property ItemAgecountset $itemAgecountset
* @property DictionaryWorkset $dictionaryWorkset
* @property WorklistItemworklist $worklistItemworklist
* @property WorklistItemcustomname $worklistItemcustomname
* @property WorklistItemworklistset $worklistItemworklistset
* @property WorklistSigworklist $worklistSigworklist
* @property WorklistSigcustomname $worklistSigcustomname
* @property WorklistSigworklistset $worklistSigworklistset
* @property WorklistPatientinfo $worklistPatientinfo
* @property WorklistPatientconnect $worklistPatientconnect
* @property WorklistPatientworklist $worklistPatientworklist
* @property Formpatientsign $itemFormpatientsign
* @property DictionaryListset $dictionaryListset
* @property ListsetItemlist $listsetItemlist
* @property ListsetSiglist $listsetSiglist
* @property ListsetOperate $listsetOperate
* @property ListsetAnnex $listsetAnnex
* @property ListsetAnnexcat $listsetAnnexcat
* @property ListsetFlow $listsetFlow
* @property BusinessCategory $businessCategory
* @property BusinessRecord $businessRecord
* @property BusinessRecordannex $businessRecordannex
* @property Backupschange $itemBackupschange
* @property Questionanswer $dictionaryQuestionanswer
* @property Changesendlog $itemChangesendlog
* @property OdmSyncRecord $odmSyncRecord
* @property ItemInfosign $itemInfosign
* @property Logtype $itemLogtype
* @property Exportpdf $itemExportpdf
* @property Identificationresultdestroy $itemIdentificationresultdestroy
* @property PatientWorkCount $patientWorkCount
* @property Websitefiling $adminWebsitefiling
* @property Doctoridea $itemDoctoridea
* @property Questionconfig $itemQuestionconfig
* @property Configtable $adminConfigtable
* @property Send $adminSend
* @property PatientChecktimeList $patientChecktimeList
* @property OcrKeyword $ocrKeyword
* @property OcrRawdata $ocrRawdata
* @property OcrMatedata $ocrMatedata
* @property OcrMedicalword $ocrMedicalword
* @property OcrMatewhite $ocrMatewhite
* @property OcrMateblack $ocrMateblack
* @property OcrSigpatient $ocrSigpatient
* @property OcrMedical $ocrMedical
* @property OcrOcrannex $ocrOcrannex
* @property OcrRawword $ocrRawword
* @property OcrRawblack $ocrRawblack
* @property Formmodel $itemFormmodel
* @property OcrRawlock $ocrRawlock
* @property OcrMedicallock $ocrMedicallock
* @property OcrChangetype $ocrChangetype
* @property OcrDeletename $ocrDeletename
* @property OcrReplace $ocrReplace
* @property OcrAnnextype $ocrAnnextype
* @property OcrSigkeyword $ocrSigkeyword
* @property OcrCt $ocrCt
* @property Blindmethodlog $blindMethodLog
* @property OcrLoseannex $ocrLoseannex
* @property Checknameweight $dictionaryChecknameweight
* @property OcrMatesearch $ocrMatesearch
* @property Checknameweight $itemChecknameweight
* @property Sign $itemSign
* @property ItemOcrCsaePatientDetail $itemOcrCsaePatientDetail
* @property ItemOcrCasePatientSpecialdetail $itemOcrCasePatientSpecialdetail
* @property ItemRemarks $itemRemarks
* @property OcrCtcase $ocrCtcase
* @property OcrCaseremark $ocrCaseremark
* @property ItemOcrCsaePatientDetailNew $itemOcrCsaePatientDetailNew
* @property ItemOcrCasePatientSpecialdetailNew $itemOcrCasePatientSpecialdetailNew
* @property OcrOcrannexnew $ocrOcrannexnew
* @property OcrDrug $ocrDrug
* @property OcrTake $ocrTake
* @property OcrCtreplace $ocrCtreplace
* @property OcrMatedrug $ocrMatedrug
* @property OcrDrugcategory $ocrDrugcategory
* @property DictionaryMedicaltake $dictionaryMedicaltake
* @property DictionaryMedicalword $dictionaryMedicalword
* @property DictionaryDrugcategory $dictionaryDrugcategory
* @property DictionaryDrug $dictionaryDrug
* @property Confirm $itemConfirm
* @property Lock $itemLock
* @property MedicalMatewhite $medicalMatewhite
* @property MedicalMateblack $medicalMateblack
* @property MedicalMatedrug $medicalMatedrug
* @property MedicalOcrdata $medicalOcrdata
* @property MedicalLock $medicalLock
* @property Allowpatientwrite $Allowpatientwrite
* @property Recharge $Recharge
* @property Recharge $Transfer
* @property TmpDeletename $tmpDeletename
* @property TmpDrug $tmpDrug
* @property TmpDrugcategory $tmpDrugcategory
* @property TmpKeyword $tmpKeyword
* @property TmpMedical $tmpMedical
* @property TmpMedicalblack $tmpMedicalblack
* @property TmpMedicaldrug $tmpMedicaldrug
* @property TmpMedicallock $tmpMedicallock
* @property TmpMedicaltake $tmpMedicaltake
* @property TmpMedicalwhite $tmpMedicalwhite
* @property TmpMedicalword $tmpMedicalword
* @property TmpRawblack $tmpRawblack
* @property TmpRawdata $tmpRawdata
* @property TmpRawlock $tmpRawlock
* @property TmpRawmate $tmpRawmate
* @property TmpRawword $tmpRawword
* @property TmpReplace $tmpReplace
* @property TmpSigkeyword $tmpSigkeyword
* @property TmpHospital $tmpHospital
* @property TmpInspect $tmpInspect
* @property TmpPatienthospital $tmpPatienthospital
* @property TmpReport $tmpReport
* @property TmpAnnex $tmpAnnex
* @property TmpPatient $tmpPatient
* @property TmpPatientct $tmpPatientct
* @property TmpCustom $tmpCustom
* @property TmpTable $tmpTable
* @property TmpText $tmpText
* @property TmpOutmedical $tmpOutmedical
* @property TmpIntervene $tmpIntervene
* @property TmpIntervene0 $tmpIntervene0
* @property TmpIntervene1 $tmpIntervene1
* @property TmpIntervene2 $tmpIntervene2
* @property OcrRawlockunique $ocrRawlockunique
* @property TmpCtreplace $tmpCtreplace
* @property TmpDoctoradviceoriginal $tmpDoctoradviceoriginal
* @property TmpDoctoradviceannex $tmpDoctoradviceannex
* @property TmpDoctoradvicereplace $tmpDoctoradvicereplace
* @property TmpDoctoradvicematewhite $tmpDoctoradvicematewhite
* @property TmpDoctoradvicemateblack $tmpDoctoradvicemateblack
* @property TmpDoctoradvicematedrug $tmpDoctoradvicematedrug
* @property TmpDoctoradvicetable $tmpDoctoradvicetable
* @property TmpDoctoradvicepatient $tmpDoctoradvicepatient
* @property TmpDoctoradvicelock $tmpDoctoradvicelock
* @property TmpDoctoradviceformal $tmpDoctoradviceformal
* @property CollectCategory $collectCategory
* @property CollectInspect $collectInspect
* @property CollectHospital $collectHospital
* @property CollectItemhospital $collectItemhospital
* @property CollectOut $collectOut
* @property CollectItemout $collectItemout
* @property CollectDrugcategory $collectDrugcategory
* @property CollectDrug $collectDrug
* @property CollectMedicaltake $collectMedicaltake
* @property CollectMedicalword $collectMedicalword
* @property CollectItemdrug $collectItemdrug
* @property CollectEcg $collectEcg
* @property CollectItemecg $collectItemecg
* @property CollectCt $collectCt
* @property CollectItemct $collectItemct
* @property CollectReport $collectReport
* @property CollectItemreport $collectItemreport
* @property CollectKeywordcat $collectKeywordcat
* @property CollectKeyword $collectKeyword
* @property CollectRawword $collectRawword
* @property CollectItemkeyword $collectItemkeyword
* @property CollectCost $collectCost
* @property CollectItemcost $collectItemcost
* @property CollectPatienthospital $collectPatienthospital
* @property CollectPatientecg $collectPatientecg
* @property CollectPatientct $collectPatientct
* @property CollectPatientreport $collectPatientreport
* @property CollectPatientraw $collectPatientraw
* @property CollectPatientrawmate $collectPatientrawmate
* @property CollectPatientrawblack $collectPatientrawblack
* @property CollectPatientrawlock $collectPatientrawlock
* @property CollectPatientmedical $collectPatientmedical
* @property CollectPatientmedicalwhite $collectPatientmedicalwhite
* @property CollectPatientmedicalblack $collectPatientmedicalblack
* @property CollectPatientmedicaldrug $collectPatientmedicaldrug
* @property CollectPatientmedicallock $collectPatientmedicallock
* @property CollectPatientout $collectPatientout
* @property OcrSpecialmedical $ocrSpecialmedical
* @property CollectPatient $collectPatient
* @property CollectAnnex $collectAnnex
* @property ExportSas $exportSas
* @property CollectSighospital $collectSighospital
* @property CollectSigout $collectSigout
* @property CollectSigkeyword $collectSigkeyword
* @property DictionaryDetectname $dictionaryDetectname
* @property DictionaryDetectblackword $dictionaryDetectblackword
* @property DictionaryDetectkeyword $dictionaryDetectkeyword
* @property CollectTable $collectTable
* @property CollectText $collectText
* @property CollectCustom $collectCustom
* @property ItemPatientformimgcontent $itemPatientformimgcontent
* @property Identificationexport $itemIdentificationexport
* @property ItemResultidentify $itemResultidentify
* @property ItemEventwatchdog $itemEventwatchdog
* @property \Application\Service\DB\Temple\Annex $templeAnnex
* @property checklist $templeChecklist
* @property ItemMedicaltake $itemMedicaltake
* @property DoctoradviceOriginal $doctoradviceOriginal
* @property ItemPatientinfo $itemPatientinfo
* @property ItemSignaturebatch $itemSignaturebatch
* @property ItemSignaturedetail $itemSignaturedetail
* @property SignatoryCollecttypeocr $itemSignatoryCollecttypeocr
* @property ItemDetectpatient $itemDetectpatient
* @property DictionaryOcrreplace $dictionaryOcrreplace
* @property ItemCissclass $itemCissclass
* @property ItemCissoption $itemCissoption
* @property ItemPatientciss $itemPatientciss
* @property PatientFormLogicError $itemPatientFormLogicError
* @property PatientFormLogicErrorPointer $itemPatientFormLogicErrorPointer
* @property PatientFormLogicErrorLog $itemPatientFormLogicErrorLog
* @property PatientFormLogicErrorQuery $itemPatientFormLogicErrorQuery
* @property ItemLogicErrorReportBlack $itemLogicErrorReportBlack
* @property Fixednametype $fixednametype
* @property Fixedname $fixedname
* @property ProjectMsgset $projectMsgset
* @property ProjectMsginfo $projectMsginfo
* @property ProjectMsgsend $projectMsgsend
* @property Planviolate $itemPlanviolate
* @property Weblink $adminWeblink
* @property AdminWorkbatch $adminWorkbatch
* @property AdminWorkinfo $adminWorkinfo
* @property DictionaryEventset $dictionaryEventset
* @property DictionaryEventattr $dictionaryEventattr
* @property AdminMedicallock $adminMedicallock
* @property ItemPatientevent $itemPatientevent
* @property ItemPatienteventannex $itemPatienteventannex
* @property ItemPatienteventset $itemPatienteventset
* @property ProjectPatientwork $projectPatientwork
* @property ItemRandomsecondary $itemRandomsecondary
* @property ProjectMedicalquestion $projectMedicalquestion
* @property ProjectMedicalquestioninfo $projectMedicalquestioninfo
* @property ProjectMedicalconfirm $projectMedicalconfirm
* @property ProjectMedicalconfirminfo $projectMedicalconfirminfo
* @property ProjectMedicalset $projectMedicalset
* @property ItemCheckdate $itemCheckdate
* @property PatientFormContentDelete $itemPatientFormContentDelete
* @property ProjectPatientworkbatch $projectPatientworkbatch
* @property ProjectPatientworkinfo $projectPatientworkinfo
* @property LogLogin $logLogin
* @property PatientFormContentUpdatedLog $patientFormContentUpdatedLog
* @property Exceedswindow $projectExceedswindow
* @property ProjectCmdrugset $projectCmdrugset
* @property PatientFormUnlock $patientFormUnlock
* @property CollectPatientdrug $collectPatientdrug
* @property DictionaryItemcategory $dictionaryItemcategory
* @property ItemPackage $itemPackage
*/
class Container
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function __get($name)
{
// TODO: Implement __get() method.
return $this->container->get($name);
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/5 18:20
* @Description
*
*/
namespace Application\Common;
use Laminas\Crypt\BlockCipher;
use Laminas\Crypt\Key\Derivation\Pbkdf2;
use Laminas\Crypt\Key\Derivation\Scrypt;
use Laminas\Crypt\Password\Bcrypt;
use Laminas\Crypt\Password\BcryptSha;
use Laminas\Math\Rand;
class Crypt
{
/**
* Notes: 对称加解密 使用例子Crypt::blockCipher()->encrypt($data) Crypt::blockCipher()->decrypt($data)
* User: llbjj
* DateTime: 2022/5/5 18:48
*
* @return BlockCipher
*/
static function blockCipher() {
$blockCipher = BlockCipher::factory('openssl', ['algo' => 'aes', 'mode' => 'gcm']);
$blockCipher->setKey('ae60e54db83a30ea985fcd77b14c063320922864a584c5dfb96e77d84e7317aa');
return $blockCipher;
}
/**
* Notes: 获取加密字符串
* User: llbjj
* DateTime: 2022/5/5 19:12
*
* @param string $data
* @return string
*/
static function createKey(string $data = 'YikeenEDC') {
$salt = Rand::getBytes(32, true);
$key = Scrypt::calc($data, $salt, 2048, 3, 1, 32);
return bin2hex($key);
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Application\Common;
/**
* 字典项字段。
* 有些字段的子集是通过字典项设置的, 无法通过表单配置读取选项内容。
*/
class DictionaryVarNameEnum
{
public const COLLECT_MEDICAL_TAKE_CMINDC = 'CMINDC100';
}

View File

@ -0,0 +1,91 @@
<?php
namespace Application\Common;
use Application\Service\DB\Dictionary\FormField;
class Enum
{
/**
* 这里应该删了
* 都转移到 @var FormField 类中了
*/
public const FORM_FIELD_TYPE_TEXT = '1';
public const FORM_FIELD_TYPE_DATE_UK = '2';
public const FORM_FIELD_TYPE_DATE = '3';
public const FORM_FIELD_TYPE_DATETIME = '5';
public const FORM_FIELD_TYPE_INTEGER = '6';
public const FORM_FIELD_TYPE_FLOAT_1 = '7';
public const FORM_FIELD_TYPE_FLOAT_2 = '8';
public const FORM_FIELD_TYPE_FLOAT_3 = '9';
public const FORM_FIELD_TYPE_RADIO = '10';
public const FORM_FIELD_TYPE_CHECKBOX = '11';
public const FORM_FIELD_TYPE_DROPDOWN = '12';
public const FORM_FIELD_TYPE_UPLOAD_FILE = '13';
public const FORM_FIELD_TYPE_UPLOAD_IMAGE = '14';
public const FORM_FIELD_TYPE_EDITOR = '15';
public const FORM_FIELD_TYPE = [
['value' => FormField::FORM_FIELD_TYPE_TEXT, 'label' => '文本'],
['value' => FormField::FORM_FIELD_TYPE_TEXTAREA, 'label' => '文本域'],
['value' => FormField::FORM_FIELD_TYPE_DATE_UK, 'label' => '日期(UK)'],
['value' => FormField::FORM_FIELD_TYPE_DATE, 'label' => '日期(年月日)'],
['value' => FormField::FORM_FIELD_TYPE_DATE_SECOND, 'label' => '日期(年月日时分)'],
['value' => FormField::FORM_FIELD_TYPE_DATETIME, 'label' => '日期(年月日时分秒)'],
['value' => FormField::FORM_FIELD_TYPE_DATETIME_UK, 'label' => '日期(年月日时分UK)'], // DateTimeUK
['value' => FormField::FORM_FIELD_TYPE_DATETIME_SECOND_UK, 'label' => '日期(年月日时分秒UK)'], // DateTimeSecondUK
['value' => FormField::FORM_FIELD_TYPE_TIME_UK, 'label' => '日期(时分UK)'], // TimeUK
['value' => FormField::FORM_FIELD_TYPE_TIME_SECOND_UK, 'label' => '日期(时分秒Uk)'], // TimeSecondUK
['value' => FormField::FORM_FIELD_TYPE_INTEGER, 'label' => '整数'],
['value' => FormField::FORM_FIELD_TYPE_FLOAT_1, 'label' => '小数(保留一位)'],
['value' => FormField::FORM_FIELD_TYPE_FLOAT_2, 'label' => '小数(保留二位)'],
['value' => FormField::FORM_FIELD_TYPE_FLOAT_3, 'label' => '小数(保留三位)'],
['value' => FormField::FORM_FIELD_TYPE_RADIO, 'label' => '单选'],
['value' => FormField::FORM_FIELD_TYPE_CHECKBOX, 'label' => '多选'],
['value' => FormField::FORM_FIELD_TYPE_DROPDOWN, 'label' => '下拉'],
['value' => FormField::FORM_FIELD_TYPE_UPLOAD_FILE, 'label' => '上传文件'],
['value' => FormField::FORM_FIELD_TYPE_UPLOAD_IMAGE, 'label' => '上传图片'],
['value' => FormField::FORM_FIELD_TYPE_EDITOR, 'label' => '编辑器'],
['value' => FormField::FORM_FIELD_TYPE_LABEL, 'label' => '文本(不可编辑)'],
['value' => FormField::FORM_FIELD_TYPE_SPAN, 'label' => '纯文本'],
['value' => FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE, 'label' => '上传共享图片'],
['value' => FormField::FORM_FIELD_TYPE_ITEM_FORM_SOURCE, 'label' => '项目表单数据'],
['value' => FormField::FORM_FIELD_TYPE_REGION_OPTION, 'label' => '级联选择'],
];
// 中心角色信息
public const SIGNATORY_ROLE_DATA = [
['value' => '1', 'label' => '研究医生','code'=>'yjys'],
['value' => '2', 'label' => '研究助理','code'=>'yjzl'],
['value' => '3', 'label' => 'PM','code'=>'pm'],
['value' => '4', 'label' => 'CRA','code'=>'cra'],
['value' => '5', 'label' => 'CRC','code'=>'crc'],
['value' => '6', 'label' => 'DM','code'=>'dm']
];
public const LOG_EVENT_SDV = 'SDV';
public const LOG_EVENT_UNSDV = 'Un-SDV';
public const LOG_EVENT_REVIEW = 'Review';
public const LOG_EVENT_UNREVIEW = 'Un-Review';
public const LOG_EVENT_LOCK = 'Lock';
public const LOG_EVENT_UNLOCK = 'Un-Lock';
public const LOG_EVENT_SIGN = 'Sign';
public const LOG_EVENT_UNSIGN = 'Un-Sign';
public const LOG_EVENT = [
self::LOG_EVENT_SDV => 'SDV',
self::LOG_EVENT_UNSDV => '取消SDV',
self::LOG_EVENT_REVIEW => 'Review',
self::LOG_EVENT_UNREVIEW => '取消Review',
self::LOG_EVENT_LOCK => 'Lock',
self::LOG_EVENT_UNLOCK => '解锁',
self::LOG_EVENT_SIGN => '签名',
self::LOG_EVENT_UNSIGN => '取消签名',
'More-SDV'=>'批量SDV',
'More-Lock'=>'批量锁定',
'More-Review'=>'批量Review',
'MoreUn-SDV'=>'批量取消SDV',
'MoreUn-Review'=>'批量取消Review',
'MoreUn-Lock'=>'批量解锁',
'MoreUn-Sign'=>'批量取消签名'
];
}

View File

@ -0,0 +1,72 @@
<?php
namespace Application\Common;
use Application\Form\item\FormForm;
class EventEnum {
/** @var string 字典项表单创建 */
const EVENT_DICTIONARY_FORM_CREATE = 'DICTIONARY_FORM_CREATE';
/**
* @var string 表单内容创建 【已迁移】
* @see EventEnumV2 已迁移至这里
*/
const EVENT_FORM_CONTENT_CREATE = 'FORM_CONTENT_CREATE';
/** @var string 表单字段创建 */
const AFTER_EVENT_FORM_FIELD_CREATE = 'AFTER_EVENT_FORM_FIELD_CREATE';
const AFTER_EVENT_CM_FORM_EDIT = 'AFTER_EVENT_CM_FORM_EDIT';
/** @var string 在CM列表中添加了AE表单。 */
const EVENT_CM_AE_FORM_CONTENT_CREATE = 'EVENT_CM_AE_FORM_CONTENT_CREATE';
const EVENT_CM_AE_FORM_CONTENT_EDIT = 'EVENT_CM_AE_FORM_CONTENT_EDIT';
/** @var string 项目表单创建 */
/** @see FormForm::createForm() */
const EVENT_AFTER_ITEM_FORM_CREATE = 'BEFORE_ITEM_FORM_CREATE';
/** @var string 表单内容编辑 [已迁移] */
/** @see EventEnumV2 已迁移至这里 **/
const EVENT_FORM_CONTENT_EDIT = 'FORM_CONTENT_EDIT';
/** @var string 通过质疑沟通来修改表单内容 [已迁移] */
/** @see EventEnumV2 */
const EVENT_FORM_CONTENT_EDIT_BY_QUESTION = 'FORM_CONTENT_EDIT_BY_QUESTION';
/** @var string 表单字段编辑 */
const AFTER_EVENT_FORM_FIELD_EDIT = 'AFTER_EVENT_FORM_FIELD_EDIT';
/** @var string 表单字段删除 */
const EVENT_FORM_FIELD_DELETE = 'EVENT_FORM_FIELD_DELETE';
/** @var string 表单字段删除 */
const AFTER_EVENT_FORM_FIELD_DELETE = 'AFTER_EVENT_FORM_FIELD_DELETE';
/** @var string 表单内容预览 */
const EVENT_FORM_CONTENT_VIEW = 'FORM_CONTENT_VIEW';
/** @var string 提交锚点时间 */
const BEFORE_EVENT_SUBMIT_ANCHOR_TIME = 'BEFORE_EVENT_SUBMIT_ANCHOR_TIME';
/** @var string 提交随机时间 */
const BEFORE_EVENT_SUBMIT_RANDOM_TIME = 'BEFORE_EVENT_SUBMIT_RANDOM_TIME';
/** @var string 更新完成状态之后 */
const AFTER_EVENT_SUBMIT_PATIENT_FORM = 'AFTER_EVENT_SUBMIT_PATIENT_FORM';
/** @var string 表单内容暂存 */
const EVENT_FORM_CONTENT_TEMP_STORAGE = 'FORM_CONTENT_TEMP_STORAGE';
/** @var string 表单内容重置 */
const EVENT_FORM_CONTENT_FLUSH = 'FORM_CONTENT_FLUSH';
/** @var string 锁定常规识别类表单 */
const EVENT_LOCK_SHARE_FORM_CONTENT = 'LOCK_SHARE_FORM_CONTENT';
/** @var string 解锁常规识别类表单 */
const EVENT_UNLOCK_SHARE_FORM_CONTENT = 'UNLOCK_SHARE_FORM_CONTENT';
}

View File

@ -0,0 +1,51 @@
<?php
namespace Application\Common;
/**
* 新的枚举类型
* @method static string getVal($key) 获取常量值
* @method static string getDesc($key) 获取常量描述
*/
class EventEnumV2
{
const
// 应该是通过进度管理来编辑
EVENT_FORM_CONTENT_EDIT = ['val' => 'FORM_CONTENT_EDIT', 'desc' => '编辑表单内容'],
// 应该是通过进度管理来创建
EVENT_FORM_CONTENT_CREATE = ['val' => 'FORM_CONTENT_CREATE', 'desc' => '填写表单内容'],
// 表单删除(一对多)
EVENT_FORM_CONTENT_DELETE = ['val' => 'FORM_CONTENT_DELETE', 'desc' => '表单内容删除' ],
// 恢复删除的表单内容
EVENT_FORM_CONTENT_RECOVERY = ['val' => 'FORM_CONTENT_RECOVERY', 'desc' => '表单内容恢复' ],
// 表单申请解锁
EVENT_FORM_CONTENT_APPLY_UNLOCK = ['val' => 'EVENT_FORM_CONTENT_APPLY_UNLOCK', 'desc' => '表单申请解锁'],
// 申请解锁后又取消了
EVENT_FORM_CONTENT_REVOKE_UNLOCK = ['val' => 'EVENT_FORM_CONTENT_REVOKE_UNLOCK', 'desc' => '取消表单申请解锁'],
// 通过质疑沟通来修改表单内容
EVENT_FORM_CONTENT_EDIT_BY_QUESTION = ['val' => 'FORM_CONTENT_EDIT_BY_QUESTION', 'desc' => '通过质疑沟通来修改表单内容'],
// 通过逻辑核查回复修改表单内容
EVENT_FORM_CONTENT_EDIT_BY_LOGIC_REPLY = ['val' => 'EVENT_FORM_CONTENT_EDIT_BY_LOGIC_REPLY', 'desc' => '常规识别类型的表单, 通过逻辑核查回复修改表单内容'],
EVENT_MULTI_SHARE_FORM_UPLOAD_IMAGE = ['val' => 'EVENT_MULTI_SHARE_FORM_UPLOAD_IMAGE', 'desc' => '常规识别类型一对多的表单, 上传图片。'],
EVENT_MULTI_SHARE_FORM_UPDATE_IMAGE = ['val' => 'EVENT_MULTI_SHARE_FORM_UPDATE_IMAGE', 'desc' => '常规识别类型一对多的表单, 修改图片。'],
EVENT_FORM_CONTENT_CONFIRM_APPLY_UNLOCK = ['val' => 'EVENT_FORM_CONTENT_CONFIRM_APPLY_UNLOCK', 'desc' => '确认表单解锁申请'];
public static function __callStatic($name, $arguments)
{
if ($name === 'getVal') {
return (current($arguments)['val']);
} elseif ($name === 'getDesc') {
return (current($arguments)['desc']);
}
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace Application\Common;
class Exportenum
{
public const Not_AE = [['INVSITE', 'PT', 'SUBNAM', 'FORM_SEQ', 'FORM_SEQ', '', '', '', ''], ['项目ID', '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '指标', '非AE类型', '备注']];
// SAE类
public const Experimentsummary = [['INVSITE', 'PT', 'SUBNAM', 'FORM_SEQ', ''], ['项目ID', '中心编号', '筛选号', '受试者姓名', '表单序号']];
//AE类
public const AE = [['INVSITE', 'PT', 'SUBNAM', 'FORM_SEQ', ''], ['项目ID', '中心编号', '筛选号', '受试者姓名', '表单序号']];
//指标AE
public const CheckAE = [['INVSITE', 'PT', 'SUBNAM', 'CPEVENT', 'FORM_SEQ', '', '',], ['项目ID', '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '指标名称']];
//随机分组和检查类
public const RAND_CHECK = [['INVSITE', 'PT', 'SUBNAM', 'CPEVENT', 'FORM_SEQ', ''], ['项目ID', '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号']];
//默认
public const DEFAULT = [['INVSITE', 'PT', 'SUBNAM', 'CPEVENT', 'FORM_SEQ', ''], ['项目ID', '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号']];
//随机号
public const RandNumber = [['分层名称', '方案分组', '区组号', '研究中心', '随机号码', '药物分组名称', '药物信息', '是否被调用', '是否作废']];
//随机号-非盲
public const RandNumber_01 = [['分层名称', '区组号', '研究中心', '随机号码', '是否被调用', '是否作废']];
//用药信息导出--无药物分类
public const Doctoradvice = [['项目号','中心','受试者','访视','药物名称','开始日期','结束日期','剂量','剂量单位','服用频率','服用方式','出院带药']];
//用药信息导出--有药物分类
public const Doctoradvice_category = [['项目号','中心','受试者','访视','药物分类','药物名称','开始日期','结束日期','剂量','剂量单位','服用频率','服用方式','出院带药']];
// 导出自定义表单
public const EXPORT_CUSTOM_FORM = [
[
'value' => 0,
'label' => '受试者基本信息[ PATIENT_BASIC ]'
],
[
'value' => 'DC',
'label' => '脱离完成[ DC ]'
],
[
'value' => 'AENE',
'label' => 'AE【非AE解释】[ AENE ]'
],
[
'value' => 'AETE',
'label' => 'AE【指标相关】[ AETE ]'
]
];
// 导出自定义表单日志
public const EXPORT_LOG_CUSTOM_FORM = [
[
'value' => 0,
'label' => '受试者基本信息[ PATIENT_BASIC ]'
],
[
'value' => 'Itempatientbreak',
'label' => '受试者中止/完成[ Itempatientbreak ]'
]
];
public const EXPORT_TYPE_MAP_CUSTOM_FORM = [
0 => self::EXPORT_LOG_CUSTOM_FORM,
1 => self::EXPORT_CUSTOM_FORM,
];
}

View File

@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/**
* @authorllbjj
* @DateTime2023/4/25 14:00
* @Description
*/
namespace Application\Common;
use Gumlet\ImageResize;
use Gumlet\ImageResizeException;
use function imagecolorallocate;
use function imagecolorallocatealpha;
use function imagecopy;
use function imagecreatetruecolor;
use function imagefilledrectangle;
use function imagerotate;
use function imagesx;
use function imagesy;
use function imagettfbbox;
use function imagettftext;
use function max;
use function min;
use const Application\Utils\APP_PATH;
class ImageResizeExtends extends ImageResize
{
/**
* Notes:
*
* DateTime: 2023/5/26 9:36
*
* @param float $angle 正数向左旋转,负数向右旋转
* @return $this
*/
public function rotate(float $angle): ImageResizeExtends
{
if (! $angle) {
return $this;
}
// 设置旋转后的背景色
$transparentBlack = imagecolorallocatealpha($this->source_image, 0, 0, 0, 127);
$this->source_image = imagerotate($this->source_image, $angle, $transparentBlack);
// 重新获取原图片的宽
$this->original_w = imagesx($this->source_image);
// 重新获取原图片的高
$this->original_h = imagesy($this->source_image);
$this->resize($this->getSourceWidth(), $this->getSourceHeight());
return $this;
}
public function outputLength($image_type = null, $quality = null, $filesize = 0)
{
$image_type = $image_type ?: $this->source_type;
header('Content-Type: ' . image_type_to_mime_type($image_type));
header('Content-Length: '. $filesize);
$this->save(null, $image_type, $quality);
}
public static function createFromString($image_data)
{
if (empty($image_data) || $image_data === null) {
throw new ImageResizeException('image_data must not be empty');
}
$resize = new self('data://application/octet-stream;base64,' . base64_encode($image_data));
return $resize;
}
}

View File

@ -0,0 +1,204 @@
<?php
namespace Application\Common;
use \baidu\AipOcr;
use Laminas\Config\Config;
use Application\Service\Extension\Laminas;
class Ocr
{
public static function ocr_result($imgPath = '', $templateSign = '', $delimit = '', &$setocrfield_data = [])
{
$_result = [];
$baidu_config = new Config(include realpath(__DIR__).'/../../../../config/autoload/zend-baidu.global.php');
$client = new \AipOcr($baidu_config['baidu']['app_id'], $baidu_config['baidu']['api_key'], $baidu_config['baidu']['aecret_key']);
$image = file_get_contents($imgPath);
if ($templateSign == '-1') {
//通用文字识别接口
$text = $options = array();
$options['probability'] = "true";
$result = $client->basicGeneralUrl($imgPath,$options);
if($result['error_code'] != 0){
return $result;
}
foreach ($result['words_result'] as $item) {
array_push($text, $item['words']);
}
$_result['item_name'] = 'text';
$_result['user']['result'] = implode(',', $text);
$_result['user']['result_type'] = 1;
}else if($templateSign == '-2'){
//通用医疗检查单
$result = $client->medicalReportDetection($image);
if($result['error_code'] != 0){
return $result;
}
if($result['Item_row_num'] && !empty($setocrfield_data)){
foreach($result['words_result'] as $itemKey => &$itemVal){
switch ($itemKey){
case 'Item':
foreach($itemVal as $fieldKey => &$fieldData){
foreach($fieldData as &$item){
if(!empty($setocrfield_data[1][$item['word_name']])){
$_result['user']['info'][$fieldKey][$setocrfield_data[1][$item['word_name']]] = $item['word'];
if($setocrfield_data[1][$item['word_name']] == 'reference_range'){
$item['word'] = str_ireplace(['~', '--'], '-', $item['word']);
$word_value_arr = explode('-', $item['word']);
if (count($word_value_arr) > 1) {
$word_value_arr = array_filter($word_value_arr);
$reference_range_max = floatval(array_pop($word_value_arr));
$reference_range_min = floatval(array_pop($word_value_arr));
} else {
$reference_range_max = '';
$reference_range_min = '';
}
$_result['user']['info'][$fieldKey]['reference_range_min'] = $reference_range_min;
$_result['user']['info'][$fieldKey]['reference_range_max'] = $reference_range_max;
}
}
}
}
break;
case 'CommonData':
foreach($itemVal as &$item){
if(!empty($setocrfield_data[0][$item['word_name']])) {
$_result['user'][$setocrfield_data[0][$item['word_name']]] = $item['word'];
}
}
break;
}
}
}
} else {
if ($delimit == 1) {
$delimiter = '-';
}elseif($delimit == 2) {
$delimiter = '~';
}elseif($delimit == 3) {
$delimiter = '--';
}
$result = $client->custom($image, array('templateSign' => $templateSign));
if($result['error_code'] != 0){
return $result;
}
foreach ($result['data']['ret'] as $key => &$val) {
$word_name_arr = explode('#', $val['word_name']);
if (count($word_name_arr) == 3) {
$_result['user']['info'][$word_name_arr[1]][$word_name_arr[2]] = $val['word'];
if (in_array($word_name_arr[2], array('reference_range', 'reference_range-1'))) {
$word_value_arr = explode($delimiter, $val['word']);
if (count($word_value_arr) > 1) {
$word_value_arr = array_filter($word_value_arr);
$reference_range_max = floatval(array_pop($word_value_arr));
$reference_range_min = floatval(array_pop($word_value_arr));
} else {
$reference_range_max = '';
$reference_range_min = '';
}
$_result['user']['info'][$word_name_arr[1]][$word_name_arr[2] . '_min'] = $reference_range_min;
$_result['user']['info'][$word_name_arr[1]][$word_name_arr[2] . '_max'] = $reference_range_max;
}
} else {
$word_value_arr = explode(':', $val['word']);
if (count($word_value_arr) == 2) {
$_result['user'][$val['word_name']] = $word_value_arr[1];
} else {
$_result['user'][$val['word_name']] = $val['word'];
}
}
}
}
foreach ($_result['user']['info'] as $k => $v) {
$two_col_data = [];
foreach ($v as $k1 => $v1) {
if (strpos($k1, "-1")) {
unset($_result['user']['info'][$k][$k1]);
if($v1 !== ''){
$two_col_data[str_ireplace('-1', '', $k1)] = $v1;
}
}
}
if(count($two_col_data)){
$_result['user']['info'][] = $two_col_data;
}
}
$collect_date = '';
if($_result['user']['collect_date']){
$collect_date = strtotime($_result['user']['collect_date']);
if ($collect_date > time() || $collect_date < 0) {
$collect_date = '';
}
}
$_result['user']['collect_date'] = $collect_date;
if(isset($_result['user']['result'])){
$_result['user']['result_type'] = 1;
}
return $_result;
}
/**
* Notes: 识别身份证信息
* User: lltyy
* DateTime: 2021/8/2 10:00
*
* @param string $imgPath
* @param string $templateSign
* @return array
*/
public static function ocr_card($imgPath = '', $templateSign = '')
{
$baidu_config = new Config(include realpath(__DIR__).'/../../../../config/autoload/zend-baidu.global.php');
$client = new \AipOcr($baidu_config['baidu']['app_id'], $baidu_config['baidu']['api_key'], $baidu_config['baidu']['aecret_key']);
$image = file_get_contents($imgPath);
$front_result = $client->custom($image, array('templateSign'=>$templateSign));
$field_arr = [
'姓名' => 'form_name',
'公民身份号码' => 'form_card',
'年龄' => 'form_age',
'出生' => 'form_birth',
'性别' => 'form_sex',
'民族' => 'form_nation',
'住址' => 'form_address',
];
$result = [
'code' => $front_result['error_code'],
'message' => $front_result['error_msg'],
'data' => []
];
if($front_result['error_code'] == 0){
$ocrContent = $front_result['data']['ret'];
foreach($ocrContent as $rowInfo){
//$fieldName = iconv('utf-8', 'gbk', $rowInfo['word_name']);
$fieldName = $rowInfo['word_name'];
$fieldValue = $rowInfo['word'];
$fieldId = $field_arr[$fieldName];
$newValue = $fieldValue;
if($fieldId == 'form_birth'){//年龄、出生
$date = strtotime($fieldValue); //获得出生年月日的时间戳
$newValue = date('Y-m-d',$date);
$today = strtotime('today'); //获得今日的时间戳
$diff = floor(($today - $date) / 86400 / 365); //得到两个日期相差的大体年数
//strtotime加上这个年数后得到那日的时间戳后与今日的时间戳相比
$ageValue = strtotime(substr($fieldValue, 6,8) . ' +' . $diff . 'years') > $today ? ($diff + 1) : $diff;
$result['data']['form_age'] = $ageValue;
}elseif($fieldId == 'form_sex'){
//$newValue = iconv('utf-8', 'gbk', $fieldValue) == '男' ? '0' : '1';
$newValue = $fieldValue == '男' ? '0' : '1';
}
$result['data'][$fieldId] = $newValue;
}
}
return $result;
}
}
?>

View File

@ -0,0 +1,43 @@
<?php
namespace Application\Common;
class RedisEnum
{
const USER_TOKEN = 'token:';
// 生成的临时key, 判断登陆二维码是否过期
const TMP_CODE = 'code:';
/**
* 登录用的状态
*/
const USER_STATUS = 'status:';
/**
* 存储用户绑定验证码
* sms:{$mobile}
*/
const SMS = 'sms:';
/**
* 存储用户登录验证码
* sms:login:{$mobile}
*/
const SMS_LOGIN = 'sms:login';
/**
* 短信速率验证
* smsLimit:{$mobile}
*/
const SMS_LIMIT = 'smsLimit:';
/**
* 项目充值验证
* smsRecharge{$mobile}
*/
const SMS_Recharge = 'smsRecharge:';
const PATIENT_FORM_TEMP_STORAGE = 'patientFormTempStorage:';
}

View File

@ -0,0 +1,62 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 14:08
* @Description
*
*/
namespace Application\Common;
class StatusCode{
const SUCCESS = [
'code' => 200,
'msg' => ''
],
NO_TOKEN = [
'code' => 60001,
'msg' => '非法访问'
],
NO_BIND_USER = [
'code' => 60002,
'msg' => '请绑定用户信息'
],
NO_USER = [
'code' => 60003,
'msg' => '用户不存在'
],
NO_LOGIN = [
'code' => 401,
'msg' => '请重新登录'
],
E_FIELD_VALIDATOR = [
'code' => 60011,
'msg' => '表单字段验证失败'
],
E_LOGIN_CODE_EXPIRE = [
'code' => 60012,
'msg' => '登录二维码过期'
],
E_RUNTIME = [
'code' => -1,
'msg' => '服务器异常'
],
E_ACCESS = [
'code' => 60013,
'msg' => '不合法访问'
],
E_RAND_NUMBER = [
'code' => 600110,
'msg' => '随机号码有误'
];
/**------------------ 短信模块 ----------------- */
const E_SMS_RATE_LIMIT = [
'code' => 61000,
'msg' => '短信发送过于频繁',
];
}

View File

@ -0,0 +1,59 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/5 20:27
* @Description
*
*/
namespace Application\Common;
use Application\Common\Crypt;
use Laminas\Stdlib\ArrayUtils;
class Token
{
/**
* Notes: 创建Token值
* User: llbjj
* DateTime: 2022/5/6 9:02
*
* @param array $data
* @return string
*/
static function createToken(array $data) {
$data['ip'] = $_SERVER['REMOTE_ADDR'];
return rtrim(Crypt::blockCipher()->encrypt(json_encode($data)), '==');
}
/**
* Notes: 验证Token是否为有效值
* User: llbjj
* DateTime: 2022/5/6 9:03
*
* @param string $token
* @return bool
*/
static function verifyToken(string $token) {
$decryptData = self::decryptToken($token);
return !empty($decryptData);
}
/**
* Notes: 解密token值
* User: llbjj
* DateTime: 2022/5/6 9:03
*
* @param string $data
* @return mixed|void
*/
static function decryptToken(string $data) {
try {
$data = $data.'==';
return json_decode(Crypt::blockCipher()->decrypt($data));
}catch (\Exception $e){
}
}
}

View File

@ -0,0 +1,473 @@
<?php
namespace Application\Controller;
use Application\Common\DictionaryVarNameEnum;
use Application\Common\EventEnum;
use Application\Common\StatusCode;
use Application\Form\CmAEModel;
use Application\Form\item\patient\PatientFormModel;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\Form;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Event;
use Application\Service\Extension\Events\FormEventHandler;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Exception;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\Sql\Expression;
use Laminas\Db\Sql\Select;
use Laminas\Db\Sql\Sql;
use Laminas\Db\Sql\Where;
use Laminas\View\Model\JsonModel;
class CmController extends BasicController
{
/**
* @url /cm
* @behavior CM_INDEX
* @return JsonModel
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function indexAction(): JsonModel
{
$this->validator->attach(
[['item_id', 'itemsig_id'], 'required'],
[['patient_id', 'operate_user', 'status'], 'default', 'value' => 0],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$this->validator->attributes['form_id'] = Laminas::$serviceManager->itemFormField->fetchOne(['where' => ['var_name' => DictionaryVarNameEnum::COLLECT_MEDICAL_TAKE_CMINDC, 'item_id' => $this->validator->attributes['item_id'], 'is_del' => 0]])['form_id'];
if (!$this->validator->attributes['form_id']) {
return $this->RenderApiJson()->Success();
}
$model = new PatientFormModel($this->validator);
$model->setScenario($model::SCENARIO_CM_LIST);
$where = new Where();
$where->equalTo('cm.is_del', 0)->equalTo('cm.item_id', $this->validator->attributes['item_id'])->equalTo('cm.sign_id', $this->validator->attributes['itemsig_id'])->equalTo('cm.status', $this->validator->attributes['status']);
if ($this->validator->attributes['patient_id']) {
$searchStr = $this->validator->attributes['patient_id'];
$searchPatientId = Laminas::$serviceManager->patient->fetchCol('id', [
'item_id' => $this->validator->attributes['item_id'],
"(patient_number LIKE '%{$searchStr}%' OR AES_DECRYPT( UNHEX( `patient_name` ), 'ykeEdc' ) LIKE '%{$searchStr}%')"
]);
$where->nest()
->in('cm.patient_id', $searchPatientId)->or
->in('cm.update_user_id', [$this->validator->attributes['patient_id']])
->unnest();
}
//药物名称检索
$serch_drug = isset($this->validator->attributes['serch_drug']) && $this->validator->attributes['serch_drug'] != '' ? trim($this->validator->attributes['serch_drug']) : '';
if ($serch_drug != '') {
$where->expression("JSON_SEARCH(content.data, 'all', ?)", "%$serch_drug%");
}
unset($serch_drug);
$limit = $this->validator->attributes['limit'] ?: 10;
$select = (new Select())
->from(['cm' => Laminas::$serviceManager->patientFormContentCm->getTableName()])
->join(['content' => Laminas::$serviceManager->patientFormContent->getTableName()], 'content.id = cm.content_id', ['id', 'update_user_id', 'update_time', 'data', 'checktime_id'], Select::JOIN_LEFT)
->where($where);
$totalSqlObject = clone $select;
$select->limit($limit)
->offset($limit * (Laminas::$app->getRequest()->getPost('page', 1) - 1));
$res = function ($sqlObject) {
$sql = new Sql(Laminas::$app->getServiceManager()->get('dbAdapter'));
$statement = $sql->prepareStatementForSqlObject($sqlObject);
$resultSet = new ResultSet();
return $resultSet->initialize($statement->execute())->toArray();
};
$totalSqlObject->columns([new Expression('COUNT(`cm`.`id`) as `count`')]);
$totalCount = intval($res($totalSqlObject)[0]['count'] ?? 0);
$query = $res($select);
$getCMINDCStatus = function($val) {
if ($val == 0) {
return '未判断>>';
} elseif ($val == 1) {
return '属于新增AE>>';
} elseif ($val == 2) {
return '属于已有AE>>';
}
return '非AE>>';
};
foreach ($query as &$item) {
$operateUser = $item['update_user_id'];
$updatedAt = $item['update_time'];
$patientId = $item['patient_id'];
$item = ArrayHelper::merge(current($model->getMultiView('', [$item])), [
'patient_id_str' => SDMHelper::app()->patient->getPatientName($patientId) . ' [' . SDMHelper::app()->patient->getPatientNumber($patientId) . '] ',
'operate_data' => $operateUser ? SDMHelper::app()->user->getRealName($operateUser) . ' / ' . date('Y-m-d H:i:s', $updatedAt) : date('Y-m-d H:i:s', $updatedAt),
'cmindc_status_str' => $item['status'] == 0 ? '未判断' : $getCMINDCStatus($item['cmindc_status']),
// 'patient_id_str' => $item['status'] == 0 ? '未判断' : $getCMINDCStatus($item['cmindc_status']),
'sign_id_str' => SDMHelper::app()->sign->getSignName($item['sign_id'])
]);
$item['checktime_id_str'] = $item['checktime_id'] ? SDMHelper::app()->checkTime->getCheckName($item['checktime_id']) : '';
}
$table = ArrayHelper::remove(ArrayHelper::merge([
["label" => "受试者", "prop" => "patient_id_str"],
], Laminas::$serviceManager->itemForm->getPreviewConfig($this->validator->attributes['form_id'])['table'] ?? []), 'width');
if ($this->validator->attributes['status'] == 1) {
$table = ArrayHelper::merge($table, [
["label" => "操作人/操作时间", "prop" => "operate_data"],
]);
}
return $this->RenderApiJson()->Success($query, 'ok', [
'total' => $totalCount,
'table' => ArrayHelper::merge($table, [
["label" => "CM判断", "prop" => "cmindc_status_str"],
])
]);
}
/**
* @url /cm/create
* @behavior CM_CREATE
* @return JsonModel
* @throws Exception
*/
public function createAction(): JsonModel
{
$this->validator->attach(
[['patient_id', 'form_id', 'item_id', 'checktime_id', 'itemsig_id'], 'required'],
[['patient_id', 'form_id', 'item_id', 'checktime_id', 'itemsig_id'], 'integer'],
);
$cmId = SDMHelper::app()->form->getCMINDCId($this->validator->attributes['form_id']);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
// 受试者新增AE必须要添加数据
if ($this->validator->attributes[$cmId] == 1 && !StringHelper::jsonDecode($this->validator->attributes['ae'], false)) {
throw new InvalidArgumentException('请添加AE数据。');
}
if (!isset($this->validator->attributes[$cmId]) || !$this->validator->attributes[$cmId]) {
throw new InvalidArgumentException(SDMHelper::app()->form->field->getName($cmId) . '不能为空。');
}
// 当用药原因CM判断结果不是其他备注清空
if( !$this->LocalService()->collectMedicaltake->isCmOptionsOther($this->validator->attributes[$cmId])) {
$this->validator->setAttributes([
'note' => ''
]);
}
$save_log_data = $this->validator->attributes;
Event::on(EventEnum::AFTER_EVENT_CM_FORM_EDIT, [FormEventHandler::class, 'afterEventCmFormEdit']);
$model = new PatientFormModel();
$model->setPostValues($this->validator->attributes);
$postData = DataHelper::handleFormData($this->validator->attributes, $this->params()->fromPost('form_id'));
$model->setBeforeCommit(function() use ($model) {
Event::trigger(EventEnum::AFTER_EVENT_CM_FORM_EDIT, [$model]);
})->editForm($postData);
$AEModel = new CmAEModel();
// 属于新增AE
if ($this->validator->attributes[$cmId] == 1) {
$AEModel->createNewPatientAE();
} elseif ($this->validator->attributes[$cmId] == 2) {
if (!isset($this->validator->attributes['checked_content_id']) && !$this->validator->attributes['checked_content_id']) {
throw new InvalidArgumentException('请选择关联的AE。');
}
$AEModel->setPostValues(ArrayHelper::merge([
'cm_content_id' => $this->validator->attributes['id']
], $this->validator->attributes));
$AEModel->createAlreadyHaveAE();
} elseif (Laminas::$serviceManager->collectMedicaltake->fetchOne(['where' => ['id' => $this->validator->attributes[$cmId]]])['english'] === 'CMINDC4') {
// 选的其他, 备注原因要必填
if (!isset($this->validator->attributes['note']) && !$this->validator->attributes['note']) {
throw new InvalidArgumentException('请填写原因。');
}
$AEModel->setPostValues(ArrayHelper::merge(['cm_content_id' => $this->validator->attributes['id']], ['note' => $this->validator->attributes['note']]));
// 更新选中其他的有原因
$AEModel->updateNote();
}
//日志存储
if(!empty($this->validator->attributes['id'])){
$this->LocalService()->log->saveFileLog($this->validator->attributes['id'],'ItemPatientformcontentcmlog',$save_log_data,1,'修改cm判断',$this->validator->attributes['item_id'],' ',['item_id'=>$this->validator->attributes['item_id']]);
}
unset($save_log_data);
return $this->RenderApiJson()->Success([]);
}
/**
* @url /cm/preview
* @behavior CM_PREVIEW
* @return JsonModel
* @throws Exception
*/
public function previewAction(): JsonModel
{
// 生成表单令牌 存储进redis 设置过期时间
$only_keys1 = bin2hex(random_bytes(32));
$redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
$redis->setex($only_keys1,3600,1);
$this->validator->attach(
[['id'], 'required'],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$val = Laminas::$serviceManager->itemForm->setPreviewScenario(Form::SCENARIO_CM_LIST_VIEW)->getPreviewConfig($this->validator->attributes['id']);
return $this->RenderApiJson()->Success($val,'OK',['only_keys1' => $only_keys1]);
}
/**
* @url /cm/view
* @behavior CM_VIEW
* @return JsonModel
* @throws Exception
*/
public function viewAction(): JsonModel
{
$this->validator->attach(
[['id'], 'required'],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new PatientFormModel();
$val = $model->setScenario($model::SCENARIO_CM_LIST_VIEW)->viewById($this->validator->attributes['id']);
// 如果选项是其他, 要把备注内容带出来
$query = Laminas::$serviceManager->patientFormContentCm->fetchOne(['where' => ['content_id' => $this->validator->attributes['id']]]);
if ($query && SDMHelper::app()->form->field->compareMedicalTake($query['cmindc_status'], 'CMINDC4')) {
$val['note'] = $query['note'];
}
return $this->RenderApiJson()->Success($val);
}
/**
* @url /cm/ae/index
* @behavior CM_AE_INDEX
* @return JsonModel
* @throws Exception
*/
public function aeListAction(): JsonModel
{
$this->validator->attach(
[['item_id'], 'required'],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new CmAEModel();
$model->setPostValues($this->validator->attributes);
$val = $model->getNewAEList();
return $this->RenderApiJson()->Success($val);
}
/**
* @url /cm/ae/view
* @behavior CM_AE_VIEW
* @return JsonModel
* @throws Exception
*/
public function aeListViewAction(): JsonModel
{
$this->validator->attach(
[['id', 'item_id', 'patient_id', 'ae_type'], 'required']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(
StatusCode::E_FIELD_VALIDATOR,
$this->validator->getFirstErrorToString()
);
}
$model = new PatientFormModel();
$model->setPostValues($this->validator->attributes);
$res = [];
if ($this->validator->attributes['ae_type'] == 2) {
$query = Laminas::$serviceManager->itemCsaeRelation->fetchAll([
'where' => [
'patient_id' => $this->validator->attributes['patient_id'],
'is_del' => 0
]
]);
} elseif ($this->validator->attributes['ae_type'] == 1) {
$query = Laminas::$serviceManager->itemCsaeRelation->fetchAll([
'where' => [
'cm_content_id' => $this->validator->attributes['id'],
'is_del' => 0
]
]);
}
foreach ($query as $item) {
$res[] = [
'data' => Laminas::$serviceManager->itemPatientAeContent->fetchOne(['where' => ['branch' => $item['branch'], 'is_del' => 0]])['data'],
'id' => $item['content_id'],
'branch' => $item['branch']
];
}
$data = $res;
$res = [];
if ($data) {
$res = $model->viewAe($data);
if ($this->validator->attributes['ae_type'] == 2) {
foreach ($res as &$resItem) {
$resItem['is_bind'] = Laminas::$serviceManager->itemCsaeChecked->fetchOne([
'where' => [
'is_del' => 0,
'branch' => $resItem['branch'],
'cm_content_id' => $this->validator->attributes['id']
]
]) ? 1 : 0;
}
}
}
return $this->RenderApiJson()->Success($res, 'OK');
}
/**
* @url /cm/ae/viewRow
* @behavior CM_AE_VIEW_ROW
* @return JsonModel
* @throws Exception
*/
public function aeViewRowAction(): JsonModel
{
$data = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
'where' => ['id' => $this->params()->fromPost('id')]
]);
$data['content_id'] = $this->LocalService()->itemPatientAeContent->getOneFieldVal('id', [
'branch' => $data['branch']
]);
$model = new PatientFormModel($this->validator);
$res = json_decode($data['data'], true);
$res['id'] = $this->params()->fromPost('id');
return $this->RenderApiJson()->Success($model->viewById(0, $data));
}
/**
* @url /cm/ae/edit
* @behavior CM_AE_EDIT
* @return JsonModel
* @throws Exception
*/
public function aeEditAction(): JsonModel
{
$this->validator->attach(
[['id'], 'required'],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new CmAEModel();
// $model->setPostValues($this->validator->attributes);
$model->editAEForm();
return $this->RenderApiJson()->Success([]);
}
/**
* @url /cm/ae/delete
* @behavior CM_AE_DELETE
* @return JsonModel
* @throws Exception
*/
public function aeDeleteAction()
{
$this->validator->attach(
[['content_id', 'cm_content_id'], 'required'],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
Db::beginTransaction();
$cmindcStatus = Laminas::$serviceManager->patientFormContentCm->fetchOne([
'where' => ['content_id' => $this->validator->attributes['cm_content_id']]
]);
// 已有AE
if ($cmindcStatus['cmindc_status'] == 2) {
// 删除已有AE
if (SDMHelper::app()->ae->discardCMListIsAlreadyAE($this->validator->attributes['content_id'], $this->validator->attributes['cm_content_id']) === false) {
// 如果都删除干净了, 就要弄到带判断列表内
SDMHelper::app()->ae->setCMAEEstimate($this->validator->attributes['cm_content_id']);
SDMHelper::app()->ae->flushCMINDCContent($this->validator->attributes['cm_content_id']);
}
} elseif($cmindcStatus['cmindc_status'] == 1) {
// 新增AE
SDMHelper::app()->ae->discardCMNewAE($this->validator->attributes['cm_content_id'], $this->validator->attributes['content_id']);
if (!Laminas::$serviceManager->itemCsaeRelation->fetchAll([
'where' => ['cm_content_id' => $this->validator->attributes['cm_content_id'], 'is_del' => 0]
])) {
SDMHelper::app()->ae->setCMAEEstimate($this->validator->attributes['cm_content_id']);
SDMHelper::app()->ae->flushCMINDCContent($this->validator->attributes['cm_content_id']);
}
}
Db::commit();
//异步处理访视进度情况信息
$this->LocalService()->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => $cmindcStatus['item_id'],
'itemsig_id' => $cmindcStatus['sign_id'],
'patient_id' => $cmindcStatus['patient_id'],
'checktime_id' => 0,
'form_id' => $cmindcStatus['form_id'],
'operate_type'=>11,
'content_arr' => !empty($this->validator->attributes['cm_content_id']) ? [$this->validator->attributes['cm_content_id']] : [],
'user_id' => $this->LocalService()->identity->getId()
]
]);
return $this->RenderApiJson()->Success([]);
}
}

View File

@ -0,0 +1,706 @@
<?php
namespace Application\Controller;
use Application\Common\Com;
use Application\Common\ImageResizeExtends;
use Application\Common\StatusCode;
use Application\Form\CommonModel;
use Application\Service\Extension\Helper\CurlHelper;
use Application\Service\Extension\Helper\FormHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Uploader\adapter\Oss;
use Application\Service\Extension\Uploader\ImageUploader;
use EasyWeChat\Kernel\Exceptions\HttpException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use Gumlet\ImageResizeException;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\MvcEvent;
use Laminas\Stdlib\ArrayUtils;
use Laminas\View\Model\JsonModel;
class CommonController extends AbstractActionController
{
/** @var string 上传附件接口地址 */
public const UPLOAD_URL = '/common/upload';
/** @var string 上传图片接口地址 */
public const UPLOAD_IMG_URL = '/common/uploadImg';
/** @var string 加密参数 */
public const SECRET_KEY = 'yikeen';
/** @var string[] 需要token验证的接口 */
public const AUTH_ACTION = [
'upload', // 上传附件
'showPic', // 图片预览
'signFileUrl', // 下载附件路径签名
];
protected function attachDefaultListeners()
{
$event = $this->getEventManager();
$event->attach(MvcEvent::EVENT_DISPATCH, [$this, 'checkLogin'], 99);
parent::attachDefaultListeners(); // TODO: Change the autogenerated stub
}
/**
* 检查是否登录
* @param MvcEvent $event
*/
function checkLogin(MvcEvent $event)
{
// $host = "{$_SERVER['REQUEST_SCHEME']}://{$this->getRequest()->getHeader('host')->getFieldValue()}/";
if (in_array($event->getRouteMatch()->getParam('action'), self::AUTH_ACTION)) {
if( ( $_COOKIE['thirdAppId'] ?? time() ) != ( $this->LocalService()->config['toolSys']['appId'] ?? '' ) ) {
if( ( $_REQUEST['bucket'] ?? '' ) != 'login_url'){
Laminas::$serviceManager->identity->getIdentityData();
}
}
}
}
public function errormsgAction() {
$code = $this->params()->fromQuery('code');
// $errData = explode('|', Crypt::blockCipher()->decrypt($code));
$errData = explode('|', $code);
echo "<pre>";print_r(file_get_contents(APP_PATH.'/runtime/'.$errData[1].'/'.str_ireplace(':','_', $errData[2]).'_'.$errData[0].'.log'));exit;
}
public function qrcodeAction() {
$filePath = APP_PATH . '/data/qrcode_258.jpg';
ImageResizeExtends::createFromString(file_get_contents($filePath))->output();
die;
}
/**
* 上传附件
* @url http://xxx.com/common/upload
* @return JsonModel
* @throws \League\Flysystem\FilesystemException
* @throws \OSS\Core\OssException
*/
public function uploadAction(): JsonModel
{
$uploader = new ImageUploader();
$config = Laminas::$app->getConfig();
$uploader->setConfig([
'allowExtensions' => ArrayUtils::merge($config['image_uploader']['allowFileExtensions'] ?? [], $config['image_uploader']['allowExtensions'] ?? []),
'maxSize' => $config['image_uploader']['fileMaxSize'],
'driver' => ImageUploader::DRIVER_OSS,
]);
return $this->RenderApiJson()->Success($uploader->save($uploader::getInstanceByName('file')));
}
/**
* 显示图片
* @throws ImageResizeException
*/
public function showPicAction()
{
if($this->request->isPost()){
$imgPath = $this->params()->fromPost('path');
$bucket = $_POST['bucket'] ?: 'yikeen';
$style = $_POST['style'] ?: 'thumb';
//******************正则匹配 path、bucket 和 style 参数 【后端先做兼容,前端后续会拆分传输相应的参数】*****************
preg_match_all('/(?:\?|&)([^&=]+)=([^&]+)/', $imgPath, $matches, PREG_SET_ORDER);
if(!empty($matches)) {
$params = [];
foreach ($matches as $match) {
$key = urldecode($match[1]);
$value = urldecode($match[2]);
if(empty($value)) continue;
$params[$key] = $value;
}
$imgPath = $params['path'];
if(isset($params['bucket'])) $bucket = $params['bucket'];
if(isset($params['style']) && $params['style'] != 'thumb') $style = $params['style'];
}
//******************************************************************************************************
}else{
$imgPath = trim($this->params()->fromQuery("path", ''), '/');
$bucket = $this->params()->fromQuery("bucket", 'yikeen');
$style = $this->params()->fromQuery("style", 'thumb');
}
$bucket = $bucket == 'tmp' || $bucket == 'login_url' ? 'yikeen' : $bucket;
$fileUpLoader = new Oss(Laminas::$app->getConfig()['image_uploader'], $bucket);
// style => ['iphone' => 最不清楚的, 'sample' => 还挺清楚的, 'origin' => 原图, 'thumb' => 高度为100的缩略图]
$imgUrl = $fileUpLoader->getSignUrl($imgPath, $style);
$imgContent = file_get_contents($imgUrl);
if(!$imgContent) {
$imgUrl = $fileUpLoader->getOriginUrl($imgPath);
$imgContent = file_get_contents($imgUrl);
if(!in_array($style, ['origin', 'ocr'])) {
$imgStyleMapWidth = [
'sample' => '1000',
'thumb' => '80',
'iphone' => '400',
];
$imageResizeExtends = ImageResizeExtends::createFromString($imgContent);
// 压缩图片
$imageResizeExtends = $imageResizeExtends->resizeToWidth($imgStyleMapWidth[$style]);
$imageResizeExtends->output();
exit;
}
}
if($_COOKIE['thirdAppId'] ?? '') {
$imageResizeExtends = ImageResizeExtends::createFromString($imgContent);
// 原图显示,检测图片的大小
$imgSize = Com::customFilesize($imgUrl);
if ($imgSize / 1024 / 1024 > 20) {
// 压缩图片
$imageResizeExtends = $imageResizeExtends->resizeToWidth(3000);
}
$imageResizeExtends->outputLength(null, null, get_headers($imgUrl, 1)['Content-Length']);
exit;
}
echo $imgContent;die;
}
/**
* Notes: 在线文件下载
* User: llbjj
* DateTime: 2024/5/31 9:11
*
* @throws \OSS\Core\OssException
* @throws \OSS\Http\RequestCore_Exception
*/
public function downloadAction() {
$filePath = trim($this->params()->fromQuery('path', ''), '/');
$fileName = $this->params()->fromQuery('fileName', '');
$bucket = $this->params()->fromQuery('bucket', 'yikeen');
$fileUpLoader = new Oss(Laminas::$app->getConfig()['image_uploader'], $bucket);
$fileUpLoader->downloadOnline($filePath, $fileName);
}
/**
* @note 文件签名
* @return JsonModel
*/
public function signFileUrlAction(): JsonModel
{
$filePath = $this->params()->fromPost('path');
$bucket = $this->params()->fromPost('bucket', 'yikeen');
$filePath = str_ireplace(Oss::getUploadDomain(), '', $filePath);
$fileUpLoader = new Oss(Laminas::$app->getConfig()['image_uploader'], $bucket);
return $this->RenderApiJson()->Success([
'signUrl' => $fileUpLoader->getSignUrl($filePath),
]);
}
/**
* 上传图片
* @url http://xxx.com/common/uploadImg
* @return JsonModel
* @throws \League\Flysystem\FilesystemException
* @throws \OSS\Core\OssException
*/
public function uploadImgAction(): JsonModel
{
$uploader = new ImageUploader();
$config = Laminas::$app->getConfig();
$uploader->setConfig([
'allowExtensions' => $config['image_uploader']['allowExtensions'],
'maxSize' => $config['image_uploader']['imgMaxSize'],
'driver' => ImageUploader::DRIVER_OSS,
]);
return $this->RenderApiJson()->Success($uploader->save($uploader::getInstanceByName('file')));
}
/**
* 渲染表单组件
* - TableButton (表格按钮)
*/
public function renderFormComponentAction(): JsonModel
{
$componentName = $this->params()->fromPost('component', '');
$item_id = $this->params()->fromPost('item_id',0);//副项目ID
//获取该项目下设置的化验单采集时间类型
$dateType = 1;
if(!empty($item_id)){
$dateType = Laminas::$serviceManager->itemCheckdate->getOneFieldVal('date_type','is_del = 0 and item_id = '.$item_id);
$dateType = empty($dateType) ? 1 : $dateType;
}
$dateType = intval($dateType);
$model = new CommonModel();
$datas = $model->render($componentName,$dateType);
return $this->RenderApiJson()->Success($datas,'',['dateType'=>$dateType]);
}
/**
* 验证公式格式
* @return JsonModel
*/
public function formatExpressionAction(): JsonModel
{
// 表单变量 //计算符号
list($constVar, $condition) = FormHelper::getCalculateConditionWithClass();
$expression = str_replace(' ', '', $_POST['expression']);
// 正则验证
$pregConst = implode('|', $constVar);
preg_match("/^($pregConst)=(.*)/", $expression, $match);
if (!$match || count($match) != 3 && $match[2] == '') {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "语法错误 `a = b + c` 才是正确的格式, 或者你没有定义好的变量当作开头!!");
}
$expressionLen = strlen($expression);
$res = [];
for ($i = 0; $i < $expressionLen; $i++) {
if ($expression[$i] === '(') {
$res[] = $expression[$i];
} elseif ($expression[$i] === ')') {
$res[] = $expression[$i];
} elseif (in_array($expression[$i], $condition)) {
$res[] = $expression[$i];
} else {
$res[] = "$expression[$i]";
}
}
$parseExpression = (implode('', $res));
$exStr = array_filter(explode(' ', $parseExpression));
return $this->RenderApiJson()->Success([
'expression' => implode('', $exStr)
]);
}
/**
* @return JsonModel
*/
public function calculateExpressionAction(): JsonModel
{
// 防止被除数写0, eval报错好像try catch抓不到。
register_shutdown_function(function () {
$err = error_get_last();
if (isset($err['message']) && $err['message'] == 'Division by zero') {
$msg = ['code' => 60011, 'msg' => '请输入正确的数字'];
die(json_encode($msg));
}
});
try {
$formId = $this->params()->fromPost('id');
$expression = $this->LocalService()->itemForm->fetchOne([
'where' => ['id' => $formId]
])['expression'];
if (!$expression) {
return $this->RenderApiJson()->Success([], '该表单暂未设置公式。');
}
$expression = FormHelper::getFormatFormExpression($expression);
$runStr = $runExpression = '';
$constVar = FormHelper::getCalculateConditionWithClass()[0];
foreach ($expression['expression'] as $v) {
if (in_array($v, $constVar)) {
$runStr .= '$' . "$v = " . floatval($this->params()->fromPost($v) ?: 0) . '; ';
$runExpression .= '$' . $v;
} else {
$runExpression .= $v;
}
}
$func = <<<EOL
function run() {
$runStr;
return $runExpression;
}
EOL;
eval($func);
$res = round(run(), 2);
} catch (\Throwable $e) {
$res = -1;
}
return $this->RenderApiJson()->Success([
'res' => $res
]);
}
/**
* 计算公式
* @url: http://xxx.com/common/v2/calculateExpression
* @return JsonModel
*/
public function calculateExpressionV2Action(): JsonModel
{
$values = $this->params()->fromPost();
$expression = Laminas::$serviceManager->itemForm->fetchOne([
'where' => ['id' => $this->params()->fromPost('id')]
])['expression'];
$expressionArr = explode('=', $expression);
unset($expressionArr[0]);
$expression = implode('=', $expressionArr);
$exec = SDMHelper::app()->expression->setExpression($expression)->setValues($values)->execute();
return $this->RenderApiJson()->Success([
'res' => $exec->getExecuteVal(),
'message' => '',
'exStr' => $exec->getExecuteCompile(),
'values' => $values
]);
}
/**
* 获取上一个小程序版本
* @url http://xxx.com/common/miniVersion
* @return JsonModel
* @throws HttpException
* @throws InvalidArgumentException
* @throws InvalidConfigException
* @throws RuntimeException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function miniVersionAction(): JsonModel
{
$platform = $this->getRequest()->getPost('platform');
$refresh = $this->getRequest()->getPost('refresh');
$token = Laminas::$serviceManager->wechat->getMiniApp($platform)->access_token->getToken();
$cacheKey = "applets:" . $platform;
if (($cache = Laminas::$serviceManager->redisExtend->getRedisInstance()->get($cacheKey)) && !$refresh) {
$data = StringHelper::jsonDecode($cache);
return $this->RenderApiJson()->Success([
'last_version' => $data['version_list'][0]['user_version'],
'cached_at' => $data['cached_at']
]);
} else {
$response = CurlHelper::getMiniAppHistoryVersion($token['access_token']);
if (!$response) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "获取版本数据出错啦!");
}
$data = StringHelper::jsonDecode($response);
if ($data['errcode'] == 0) {
$data['cached_at'] = time();
Laminas::$serviceManager->redisExtend->getRedisInstance()->setex($cacheKey, 60*60*2, json_encode($data)); // 缓存两个小时
return $this->RenderApiJson()->Success([
'last_version' => $data['version_list'][0]['user_version'] ?? 99999, // 取不到给个默认值
'cached_at' => $data['cached_at']
]);
} else {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $data['errmsg']);
}
}
}
/**
* 用于微信公众号和受试者手机号绑定
* @url xxx.com/common/patient-mobile
*/
public function patientMobileAction()
{
$mobile = $this->params()->fromQuery('mobile');
$openid = $this->params()->fromQuery('openid');
$sign = $this->params()->fromQuery('sign');
if ($sign !== md5($mobile . self::SECRET_KEY)) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, 'sign error.');
}
// 不传openid 是查询当前手机号是否属于受试者
if (!$openid) {
if ($query = Laminas::$serviceManager->patient->fetchOne([
'where' => ['patient_tel' => $mobile, 'is_del' => 0]
])) {
if ($query['openid']) {
die('-1'); // 已经绑定用户了
} else {
die('1'); // 找不到手机号
}
}
die('0');
}
Laminas::$serviceManager->patient->isSetInfo(false)->update(['openid' => $openid], ['patient_tel' => $mobile]);
return $this->RenderApiJson()->Success();
}
public function editSendAction() {
$com = new Com();
// $id = $_POST['id'] ?:1;
$item_id = $_POST['item_id'] ?: 0;
$patient_id = $_POST['patient_id'] ?: 0;
$itemsig_id = $_POST['itemsig_id'] ?: 0;
$date = $_POST['date'] ? : 0;
if (empty($item_id) || empty($patient_id)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');
//验证链接
if((strtotime(date('Y-m-d',$date)) != strtotime(date('Y-m-d'))) || empty($date)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
}
$whereMess['where'] = [
'is_del' => 0,
'item_id' => $item_id,
];
$whereMess['columns'] = ['item_id','content'];
$itemMessageSendInfos = $this->LocalService()->itemMessageSend->fetchOne($whereMess);
if (empty($itemMessageSendInfos)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '后台推送新增表单还未设置');
// if (empty($itemMessageSendInfos)){
// return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
// }
// $current_time = date('G');
// if ($current_time < $itemMessageSendInfos['send_time']){
// return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
// }
$fieldId = implode(',',array_column(json_decode($itemMessageSendInfos['content'],true),'id'));
$itemMessageFieldData = $this->LocalService()->itemMessageField->fetchAll(['where' => 'is_del=0 and item_id='.$item_id.' and (id in('.$fieldId.') or parent in('.$fieldId.'))','order' => ['mess_order']]);
$relation = [];
if(!empty($itemMessageFieldData)){
$relationFieldDatas = [];
$relationFieldData = [];
$relationIdArr = [];
$relationId = array_filter(array_column($itemMessageFieldData,'relation_id'));
if (!empty($relationId)){
$relationIds = implode(',',$relationId);
$relationFieldData = $this->LocalService()->itemMessageField->fetchAll(['where' => 'is_del=0 and item_id='.$item_id.' and (id in('.$relationIds.') or parent in('.$relationIds.'))','order' => ['mess_order']]);
}
if(!empty($relationFieldData)){
$relationFieldData = $com->getTree($relationFieldData,0,0,2,'parent');
$relationIdArr = array_column($relationFieldData,'id');
}
$relationFieldDatas = $this->LocalService()->itemMessageSend->getPatientattrTemplate($relationFieldData);
$unsetArr = [];
foreach ($itemMessageFieldData as $itemMessageFieldDataK=>$itemMessageFieldDataV){
if (!empty($itemMessageFieldDataV['relation_id'])){
$relationIdData = explode(',',$itemMessageFieldDataV['relation_id']);
foreach ($relationFieldDatas as $relationFieldDatasK=>$relationFieldDatasV) {
if (in_array($relationFieldDatasV['id'],$relationIdData)){
// $relationFieldDatasV['prop'] = $getTypeCode[$itemMessageFieldDataV['id']];
$relationFieldDatasV['prop'] = $relationFieldDatasV['id'];//$itemMessageFieldDataV['parent'].'-'.$itemMessageFieldDataV['id'].'-'.$relationFieldDatasV['id'];
$relation[$itemMessageFieldDataV['parent']][$itemMessageFieldDataV['id']][] = $relationFieldDatasV;
}
}
}
if (in_array($itemMessageFieldDataV['id'],$relationIdArr)){
unset($itemMessageFieldData[$itemMessageFieldDataK]);
}
}
}
!empty($itemMessageFieldData) && $itemMessageFieldData = $com->getTree($itemMessageFieldData,0,0,2,'parent');
$FormFileDatas = $this->LocalService()->itemMessageSend->getPatientattrTemplate($itemMessageFieldData);
$FormFileData =array_values($this->Introduce('MessageSend',['item_id'=>$item_id,'messageSend'=>$FormFileDatas,'MINI_PATIENT'=>1]));
$itemMessageSendPatientWhere = [
'where' => 'is_del=0 and is_write=0 and item_id='.$item_id.' and patient_id='.$patient_id.' and FROM_UNIXTIME(create_time ,"%Y-%m-%d")="'.date('Y-m-d').'"',
'columns'=>['item_id','content','itemsig_id','patient_id','id'],
];
$itemMessageSendInfo = $this->LocalService()->itemMessageSendPatient->fetchOne($itemMessageSendPatientWhere);
if (!empty($itemMessageSendInfo)){
$itemInfoName = $this->LocalService()->itemInfo->getOneFieldVal('name','id='.$item_id)?:'';
$patientInfo = $this->LocalService()->patient->fetchOne(['where'=>'is_del=0 and id='.$patient_id,'columns'=>['id','patient_name','patient_number']]);
$itemMessageSendInfo['itemInfoName'] = $itemInfoName;
$itemMessageSendInfo['patient_name'] = '';
if (!empty($patientInfo)){
if (!empty($patientInfo['patient_name'])){
$itemMessageSendInfo['patient_name'] = $patientInfo['patient_name'];
}
if (!empty($patientInfo['patient_number'])){
$itemMessageSendInfo['patient_name'] .= '【'.$patientInfo['patient_number'].'】';
}
}
if (!empty($itemMessageSendInfo['content'])){
$itemMessageSendInfo['content'] = json_decode($itemMessageSendInfo['content'],true);
}else{
$itemMessageSendInfo['content'] = [];
}
}else{
$itemMessageSendInfo = ['is_write'=>1];
}
// if (empty($itemMessageSendInfo)){
// $whereMess['where'] = 'is_del=0 and item_id = ' . $item_id;
// $whereMess['columns'] = ['item_id','content'];
// $itemMessageSendInfo = $this->LocalService()->itemMessageSend->fetchOne($whereMess);
// if (!empty($itemMessageSendInfo)){
// $itemMessageSendInfo['id'] = 0;
// $itemMessageSendInfo['patient_id'] = $patient_id;
// $itemInfoName = $this->LocalService()->itemInfo->getOneFieldVal('name','id='.$item_id)?:'';
// $patientInfo = $this->LocalService()->patient->fetchOne(['where'=>'is_del=0 and id='.$patient_id,'columns'=>['id','patient_name','patient_number']]);
//
// $itemMessageSendInfo['itemInfoName'] = $itemInfoName;
// $itemMessageSendInfo['patient_name'] = '';
// if (!empty($patientInfo)){
// if (!empty($patientInfo['patient_name'])){
// $itemMessageSendInfo['patient_name'] = $patientInfo['patient_name'];
// }
// if (!empty($patientInfo['patient_number'])){
// $itemMessageSendInfo['patient_name'] .= '【'.$patientInfo['patient_number'].'】';
// }
// }
//
// if (!empty($itemMessageSendInfo['content'])){
// $itemMessageSendInfo['content'] = json_decode($itemMessageSendInfo['content'],true);
// }else{
// $itemMessageSendInfo['content'] = [];
// }
// }else{
// $itemMessageSendInfo = [];
// }
// }else{
// $itemMessageSendInfo = ['is_write'=>1];
// }
$data['itemMessageSendInfo'] = $itemMessageSendInfo;
$data['FormFileData'] =$FormFileData;
$data['relation'] =$relation;
return $this->RenderApiJson()->Success($data);
}
public function savePatientSendAction() {
$id = $newData['id'] = $_POST['id'] ?: 0;
$newData['item_id'] = $_POST['item_id'] ?: 0;
$newData['patient_id'] = $_POST['patient_id'] ?: 0;
$newData['itemsig_id'] = $_POST['itemsig_id'] ?: 0;
$newData['content'] = $_POST['content'] ?: '';
$newData['create_user_id'] = $newData['update_user_id'] = $_POST['user_id'] ?: 0;
$date = $_POST['date'] ? : 0;
$com = new Com();
if (empty($newData['item_id']) || empty($newData['content']) || empty($newData['patient_id'])){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');
}
//验证链接
if((strtotime(date('Y-m-d',$date)) != strtotime(date('Y-m-d'))) || empty($date)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
}
$itemMessageSendInfo = $this->LocalService()->itemMessageSend->fetchOne(['where'=>'is_del=0 and item_id='.$newData['item_id']]);
if (empty($itemMessageSendInfo)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
}
$current_time = date('G');
// if ($current_time < $itemMessageSendInfo['send_time']){
// return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
// }
$checkSave = [
'item_id'=>$newData['item_id'],
'sendPatientData'=>$newData['content'],
];
//没有填写数据
// $resultCheckSave = $this->LocalService()->itemMessageSend->checkSend($checkSave);
// if (empty($resultCheckSave)) return $this->RenderApiJson()->Success();
$itemMessageSendPatientWhere = [
'where' => 'is_del=0 and item_id='.$newData['item_id'].' and patient_id='.$newData['patient_id'].' and FROM_UNIXTIME(create_time ,"%Y-%m-%d")="'.date('Y-m-d').'"',
'columns'=>['item_id','content','itemsig_id','patient_id','id'],
];
$itemMessageSendPatientInfo = $this->LocalService()->itemMessageSendPatient->fetchOne($itemMessageSendPatientWhere);
if(empty($itemMessageSendPatientInfo) || !empty($itemMessageSendPatientInfo['is_write'])) return $this->RenderApiJson()->Success();
$itemMessageFieldData = $this->LocalService()->itemMessageField->fetchAll(['where' => 'is_del=0 and item_id='.$newData['item_id'],'order' => ['mess_order']]);
$itemMsgParent = [];
$itemMsgParents = [];
if (!empty($itemMessageFieldData)){
$itemMsgParents = array_column($itemMessageFieldData,null,'id');
foreach ($itemMessageFieldData as $itemMessageFieldDataK=>$itemMessageFieldDataV){
if (empty($itemMessageFieldDataV['parent']) && $itemMessageFieldDataV['is_required'] == 1){
$itemMsgParent[] = $itemMessageFieldDataV['id'];
}
}
$itemMessageFieldData = $com->getTree($itemMessageFieldData,0,0,2,'parent');
}
// !empty($itemMessageFieldData) && $itemMessageFieldData = $com->getTree($itemMessageFieldData,0,0,2,'parent');
$FormFileDatas = $this->LocalService()->itemMessageSend->getPatientattrTemplate($itemMessageFieldData);
$contentField = $newData;
if (!empty($newData['content'])){
$newContentData = json_decode($newData['content'],true);
foreach ($newContentData as $newContentDataK=>$newContentDataV){
$var_name = isset($itemMsgParents[$newContentDataV['id']]['var_name'])?$itemMsgParents[$newContentDataV['id']]['var_name']:'';
$names = isset($itemMsgParents[$newContentDataV['id']]['name'])?$itemMsgParents[$newContentDataV['id']]['name']:'';
if (in_array($newContentDataV['id'],$itemMsgParent) && empty($newContentDataV['value'])){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '【'.$names.'】:不能为空');
}
$contentField[$var_name] = $newContentDataV['value'];
}
//必填写都填写则为已完成
// $newData['is_complete'] = 1;
$newData['is_write'] = 1;
unset($contentField['content']);
}
// echo '<pre>';print_r($contentField);die;
$FormFileData =$this->Introduce('MessageSendPatient',['item_id'=>$newData['item_id'],'messageSend'=>$FormFileDatas]);
// $newData['update_user_id'] = $newData['user_id'];
// $newData['create_user_id'] = $newData['user_id'];
empty($newData['id']) && $newData['id'] = $itemMessageSendPatientInfo['id'];
$newData['write_time'] = time();
// echo '<pre>';print_r($FormFileData);die;
$result = $this->LocalService()->itemMessageSendPatient->save($newData);
unset($newData['write_time']);
unset($newData['update_user_id']);
$realname = $this->LocalService()->adminUser->getOneFieldVal('realname','is_del=0 and id='.$newData['create_user_id'])?:'';
// unset($newData['create_user_id']);
$contentField['realname'] = $realname;
$contentField['data_type_flag'] = 1;
if (!empty($result)) $this->LocalService()->log->saveFileLog($newData['id'],'MessageSendPatient',$contentField,0,'暂无说明',$newData['item_id'],'',['item_id'=>$newData['item_id'],'messageSend'=>$FormFileData]);
return $this->RenderApiJson()->Success();
}
//引入
private function Introduce($formValidator, array $params = []){
$path=APP_PATH.'/formData/';
$fromMap=include $path.'formMap.php';
$fromData=include $path.ucfirst($formValidator).'Data.php';
if (!empty($fromData)){
if(is_callable($fromData)) return $fromData($params);
return $fromData;
}else{
return [];
}
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace Application\Controller;
use Application\Common\StatusCode;
use Application\Form\project\AeForm;
use Application\Mvc\Controller\BasicController;
use Application\Common\Com;
use Application\Service\Log;
use Application\Common\Ocr;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Mvc\Controller\AbstractActionController;
class CrontabController extends AbstractActionController {
private $ossPath = 'http://yikeen.oss-cn-beijing.aliyuncs.com';
//批量识别数据
public function manyReidentificationAction()
{
//附件===未锁定
$whereItemPatientworkannex['where'] = [
'lock_state' => 0,
'ocr_state' => 0,
'confirm_state' => 0,
'is_result' => 0,
'annex_type' => 1,
new Operator('ocr_id', Operator::OP_NE, 0)
];
$itemPatientworkannexData = $this->LocalService()->itemPatientworkannex->fetchAll($whereItemPatientworkannex);
if (empty($itemPatientworkannexData)){
return false;
}
$dictionarySetocrfieldData = $this->LocalService()->dictionarySetocrfield->getAllGroupType();
foreach ($itemPatientworkannexData as $itemPatientworkannexDataKey=>$itemPatientworkannexDataValue) {
//识别数据
$whereItemIdentificationresult['where'] = ['is_del' => 0, 'workannex_id' => $itemPatientworkannexDataValue['id']];
$itemIdentificationresultInfo = $this->LocalService()->itemIdentificationresult->fetchOne($whereItemIdentificationresult);
//识别模板设置数据
$whereDictionaryOcr['where'] = ['is_del' => 0, 'id' => $itemPatientworkannexDataValue['ocr_id']];
$whereDictionaryOcr['columns'] = ['id','name','key_val','separator'];
$dictionaryOcrInfo = $this->LocalService()->dictionaryOcr->fetchOne($whereDictionaryOcr);
if (empty($dictionaryOcrInfo) || empty($dictionaryOcrInfo['key_val']) || empty($dictionaryOcrInfo['separator']) || empty($itemPatientworkannexDataValue['annex_path'])){
continue;
}
$imgPath = $this->ossPath.$itemPatientworkannexDataValue['annex_path'];
$result = Ocr::ocr_result($imgPath, $dictionaryOcrInfo['key_val'], $dictionaryOcrInfo['separator'], $dictionarySetocrfieldData);
if ($result['error_code'] != 0) {
continue;
}
$upWorkannex['ocr_state'] = 1;
$upWorkannex['is_result'] = 1;
$upWorkannex['confirm_state'] = 1;
$upWorkannex['id'] = $itemPatientworkannexDataValue['id'];
$resultItemPatientworkannex = $this->LocalService()->itemPatientworkannex->save($upWorkannex);
$arr['content'] = json_encode($result);
$arr['workannex_id'] = $itemPatientworkannexDataValue['id'];
if (!empty($itemIdentificationresultInfo)){
$resultId = $arr['id'] = $itemIdentificationresultInfo['id'];
$resultItemIdentificationresult = $this->LocalService()->itemIdentificationresult->save($arr);
}else{
$resultId = $this->LocalService()->itemIdentificationresult->save($arr);
}
}
return true;
}
}

View File

@ -0,0 +1,211 @@
<?php
namespace Application\Controller;
use Application\Form\item\LogicModel;
use Application\Form\LogicFormModel;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\components\AnalysisHelper;
use Application\Service\Extension\Helper\FileHelper;
use Application\Service\Extension\Laminas;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
class DashboardController extends AbstractActionController // BaseController
{
public function __construct()
{
// if (isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] === '/dashboard') {
// return;
// }
//
// Laminas::$serviceManager->identity->getId();
}
public function indexAction()
{
$view = new ViewModel();
$view->setTemplate('dashboard/index');
$view->setVariables([
'filesCount' => count(FileHelper::getFiles(APP_PATH . '/runtime/' . date('Y-m-d')))
]);
return $view;
}
public function fileTimestampAction(): ViewModel
{
$view = new ViewModel();
$view->setTemplate('dashboard/fileTimestamp');
$view->setVariables([
'files' => FileHelper::getFiles(APP_PATH . '/config')
]);
return $view;
}
public function apiFileTimestampAction()
{
$path = $this->params()->fromPost('path');
$files = FileHelper::getFiles(APP_PATH . '/' . trim($path, '/'));
$r = [];
foreach ($files as $file) {
$r[] = [
'path' => $file,
'timestamp' => date("Y-m-d H:i:s", filemtime($file))
];
}
return $this->RenderApiJson()->Success($r);
}
public function exceptionAction(): ViewModel
{
$view = new ViewModel();
$view->setTemplate('dashboard/exception');
$view->setVariables([
'files' => FileHelper::getFiles(APP_PATH . '/runtime/' . date('Y-m-d'))
]);
return $view;
}
public function apiExceptionAction(): ViewModel
{
$path = $this->params()->fromPost('date');
$files = FileHelper::getFiles(APP_PATH . '/runtime/' . trim($path, '/'));
return $this->RenderApiJson()->Success($files);
}
public function apiExceptionDetailAction(): ViewModel
{
$file = $this->params()->fromPost('path');
return $this->RenderApiJson()->Success([file_get_contents($file)]);
}
public function unitTestAction(): ViewModel
{
$view = new ViewModel();
$view->setTemplate('dashboard/unitTest');
// $view->setVariables([
// 'files' => FileHelper::getFiles(APP_PATH . '/runtime/' . date('Y-m-d'))
// ]);
return $view;
}
public function apiUnitTestAction(): ViewModel
{
system('php' . ' -d memory_limit=-1 ' . APP_PATH . '/vendor/bin/phpunit');die;
$view = new ViewModel();
$view->setTemplate('dashboard/unitTest');
// $view->setVariables([
// 'files' => FileHelper::getFiles(APP_PATH . '/runtime/' . date('Y-m-d'))
// ]);
return $view;
}
public function redisAction(): ViewModel
{
$view = new ViewModel();
$view->setTemplate('dashboard/redis');
// $view->setVariables([
// 'files' => FileHelper::getFiles(APP_PATH . '/runtime/' . date('Y-m-d'))
// ]);
return $view;
}
public function apiRedisAction()
{
$method = $this->params()->fromPost('params');
$params = explode(' ', $method);
$redisMethod = array_shift($params);
$val = Laminas::$serviceManager->redisExtend->getRedisInstance()->{$redisMethod}(...$params);
return $this->RenderApiJson()->Success(!is_array($val) ? array($val) : $val);
}
public function formLogAction()
{
$view = new ViewModel();
$view->setTemplate('dashboard/formLog');
return $view;
}
public function apiFormLogAction()
{
$contentId = $this->params()->fromPost('params');
$query = Laminas::$serviceManager->patientFormContentUpdatedLog->fetchAll([
'where' => [
'content_id' => $contentId
]
]) ?: [];
return $this->RenderApiJson()->Success($query);
}
public function analysisAction()
{
$view = new ViewModel();
$view->setTemplate('dashboard/analysis');
$val = $this->getAnalysisData();
$view->setVariables([
'data' => $val,
'title' => ArrayHelper::getColumn($val, 'name')
]);
return $view;
}
public function analysisResponseTimeAction()
{
$view = new ViewModel();
$view->setTemplate('dashboard/analysisResponseTime');
$val = $this->getAnalysisData();
$view->setVariables([
'data' => $val,
'title' => ArrayHelper::getColumn($val, 'name'),
]);
return $view;
}
private function getAnalysisData()
{
$res = $data = [];
for ($i = 0; $i < 24; $i++) {
$value = Laminas::$serviceManager->redisExtend->getRedisInstance()->hGetAll(AnalysisHelper::getRequestTimesKey($i));
foreach ($value as $url => $item) {
if (!isset($data[$url])) {
$data[$url] = array_fill(0, 24, 0);
}
$data[$url][$i] = $item;
}
}
foreach ($data as $url => $item) {
$slow = Laminas::$serviceManager->redisExtend->getRedisInstance()->lLen(AnalysisHelper::getResponseTimeKey() . ':' . $url);
$total = array_sum($item);
$res[] = [
'name' => $url,
'data' => $item,
'total' => $total,
'slow' => $slow,
'normal' => $total - $slow
];
}
return $res;
}
public function apiAnalysisResponseTimeAction()
{
$url = $this->params()->fromQuery('url');
$val = Laminas::$serviceManager->redisExtend->getRedisInstance()->lRange(AnalysisHelper::getResponseTimeKey() . ':' . $url, 0, -1);
return $this->RenderApiJson()->Success($val);
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/2/2 13:27
* @Description
*
*/
namespace Application\Controller\Drug;
use Laminas\Config\Factory;
class DrugController extends \Laminas\Mvc\Controller\AbstractActionController
{
public function patientDrugAction() {
return $this->RenderApiJson()->Success(
$this->LocalService()->tmpDoctoradvicelock->getpatientdrug()
);
}
public function drugLockAction() {
$patient_id = $this->params()->fromPost('patient_id', 0);
$drug_id = $this->params()->fromPost('drug_id', 0);
if(empty($patient_id) || empty($drug_id)) return $this->RenderApiJson()->Success();
return $this->RenderApiJson()->Success(
$this->LocalService()->tmpDoctoradvicelock->getlockdrugData($patient_id, $drug_id)
);
}
public function drugDayAction() {
$patient_id = $this->params()->fromPost('patient_id', 0);
$drug_id = $this->params()->fromPost('drug_id', 0);
if(empty($patient_id) || empty($drug_id)) return $this->RenderApiJson()->Success();
return $this->RenderApiJson()->Success(
$this->LocalService()->tmpDoctoradviceformal->getdormaldrugData($patient_id,$drug_id)
);
}
public function drugDaySaveAction() {
$drugDayData = $this->params()->fromPost('drugDay', []);
foreach($drugDayData as $drugDay) {
$this->LocalService()->tmpDoctoradviceformal->save($drugDay);
}
return $this->RenderApiJson()->Success();
}
public function arrangeDrugSaveAction() {
$fileName = $this->params()->fromPost('fileName', '');
$arrangeDrug = $this->params()->fromPost('arrangeDrug', []);
if(!file_exists(APP_PATH . '/data/drug/')) {
mkdir(APP_PATH . '/data/drug/', 0777, true);
}
Factory::toFile(APP_PATH . '/data/drug/'.$fileName.'.php', $arrangeDrug);
return $this->RenderApiJson()->Success();
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace Application\Controller;
use Application\Common\StatusCode;
use Application\Form\item\LogicModel;
use Application\Form\item\patient\PatientFormModel;
use Application\Form\LogicFormModel;
use Application\Form\project\AeForm;
use Application\Form\project\LogicAeForm;
use Application\Mvc\Controller\BasicController;
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\DB\Item\PatientFormLogicErrorQuery;
use Application\Service\DB\Item\Signatory;
use Application\Service\Extension\CheckLogic\CheckLogicApplication;
use Application\Service\Extension\CheckLogic\ExpressionGenerator;
use Application\Service\Extension\ErrorHandler;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\LogicErrorFormatter;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\CurlHelper;
use Application\Service\Extension\Helper\FileHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Helper\VarDumperHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Validator\ValidatorApplication;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\Sql\Expression;
use Laminas\Db\Sql\Predicate\IsNotNull;
use Laminas\Db\Sql\Predicate\Like;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Predicate\Predicate;
use Laminas\Db\Sql\Select;
use Laminas\Db\Sql\Sql;
use Laminas\Db\TableGateway\Feature\EventFeatureEventsInterface;
use Laminas\Mvc\Controller\AbstractActionController;
class ExposeController extends AbstractActionController // BaseController
{
public function reportAction()
{
// type , content_id
$changeId = intval($this->params()->fromPost('change_id'));
$isCollectDate = intval($this->params()->fromPost('is_collectDate'));
$query = Laminas::$serviceManager->itemCsae->fetchOne(['where' => ['patient_change_id' => $changeId, 'is_del' => 0, 'is_ae_sure' => 1]]);
$type = $query['ae_type'] ?? false;
$csaeId = $query['id'] ?? false;
$v = new ValidatorApplication($this->params()->fromPost());
$v->attributes['type'] = $type;
$model = new LogicAeForm($v);
Db::beginTransaction();
// 属于已有ae
if ($type == 5) {
$model->updateAeType($csaeId);
} if ($type == 6) { // 属于新增ae
$model->updateAeType($csaeId);
}
if ($isCollectDate) {
Laminas::$serviceManager->itemCsae->isAnnulDate($changeId);
} else {
Laminas::$serviceManager->itemCsae->isAnnulChecknameSaveAction($changeId);
}
Db::commit();
return $this->RenderApiJson()->Success();
}
public function fileTimestampAction()
{
$directory = APP_PATH . '/' . ($this->getRequest()->getQuery('path') ?: 'module/Application');
$files = FileHelper::getFiles($directory);
foreach ($files as $file) {
$fileLastModifiedTime = filemtime($file);
$fileLastModifiedTimeFormatted = date("Y-m-d H:i:s", $fileLastModifiedTime);
$file = strtr($file, [
APP_PATH => ''
]);
echo "{$file} [{$fileLastModifiedTimeFormatted}]" . PHP_EOL;
}
// 输出结果
die;
}
}

View File

@ -0,0 +1,495 @@
<?php
namespace Application\Controller;
use Application\Common\StatusCode;
use Application\Form\FieldForm;
use Application\Form\FormForm;
use Application\Form\research\ContentForm;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Dictionary\Form;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\FormFormatter;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Validator\FormValidator;
use Application\Service\Extension\Validator\ValidatorApplication;
use Application\Service\Logs;
use Exception;
use Laminas\Db\Sql\Expression;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Validator\Between;
use Laminas\Validator\Db\NoRecordExists;
use Laminas\Validator\Db\RecordExists;
use Laminas\Validator\Digits;
use Laminas\Validator\Exception\InvalidArgumentException;
use Laminas\Validator\GreaterThan;
use Laminas\Validator\InArray;
use Laminas\Validator\LessThan;
use Laminas\Validator\NotEmpty;
use Laminas\Validator\StringLength;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
class FieldController extends BasicController
{
/** @var string 表单字段配置key */
public const FORM_VALIDATOR = 'itemFormField';
public const LOG_TARGET = 'DictionaryFormField';
/**
* 字段列表
* @doc https://www.showdoc.com.cn/p/e986fbe555c06367a9a8b96459908abd
* @url http://xx.com/dictionary/form/field
* @return JsonModel
* @throws Exception
*/
public function indexAction(): JsonModel
{
$validator = new ValidatorApplication();
// TODO id验证
$validator->attach(
[['version', 'id'], 'required'],
);
if (!$validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
}
$data = $this->LocalService()->dictionaryFormVersion->getField([
'form_id' => $validator->attributes['id'],
'version' => $validator->attributes['version'],
]);
return $this->RenderApiJson()->Success($data);
}
/**
* 版本列表
* @doc https://www.showdoc.com.cn/p/38faccc31ac49c9c8e0cc678bb6d56cd
* @url http://xx.com/dictionary/field/version
* @return JsonModel
*/
public function versionAction(): JsonModel
{
$validator = new ValidatorApplication();
$validator->attach(
[['id'], 'required']
);
if (!$validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
}
// 获取所有版本
// 新增无版本, 返回默认值
$query = $this->LocalService()->dictionaryFormVersion->fetchAll([
'columns' => ['version as label', 'version as value'],
'where' => ['form_id' => $validator->attributes['id']]
]) ?: [['label' => 'v1.0', 'value' => 'v1.0']];
return $this->RenderApiJson()->Success($query);
}
/**
* 创建表单
* @doc https://www.showdoc.com.cn/p/624d4f2f3c33f1e7b8e0f5adf6a2f776
* @url http://xx.com/api/dictionary/field/create
* @return JsonModel
* @throws Exception
*/
public function createAction(): JsonModel
{
$this->validator->attach(
[['form_id'], 'required'],
[['form_id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryForm, 'targetAttribute' => 'id'], // 验证 form_id 是否存在
[['form_type'], 'default', 'value' => FieldForm::FORM_CONFIG_TEXT],
[['is_list', 'is_booked_time','is_hide','dicform_id'], 'default', 'value' => 0],
[['is_export'], 'default', 'value' => 1],
[['value'], 'function', 'targetClass' => FieldForm::class, 'method' => 'invalidRadioValue'],
[['is_booked_time'], 'function', 'targetClass' => FieldForm::class, 'method' => 'invalidBookedTime']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
// 前端传的 `default` 字段可能会有前缀, 需要处理一下
$default = 'default' . $this->validator->attributes['type'];
if (isset($this->validator->attributes[$default])) {
$this->validator->attributes['default'] = $this->validator->attributes[$default];
}
if(isset($this->validator->attributes['checkname_id'])){
if(is_array($this->validator->attributes['checkname_id'])){
$this->validator->attributes['checkname_id'] = !empty($this->validator->attributes['checkname_id']) ? implode(',',$this->validator->attributes['checkname_id']) : '';
}else{
$this->validator->attributes['checkname_id'] = !empty($this->validator->attributes['checkname_id']) ? trim($this->validator->attributes['checkname_id'],',') : '';
}
}
//选项无关联信息时,关联分类、关联类型默认为空值
if(isset($this->validator->attributes['relation_information']) && empty($this->validator->attributes['relation_information'])){
$this->validator->attributes['relation_classification'] = 0;
$this->validator->attributes['relation_type'] = 0;
}
$model = new FieldForm($this->validator);
if ($this->validator->attributes['id']) {
//先验证是否可以修改
$model->editCheck();
//查询选项值 判断本次是否修改了表单选项的字典项 如果修改了 提示先去删除旧的选项值 再进行修改
$childen_count = $this->LocalService()->dictionaryFormField->getCount([
'is_del' => 0,
'parent' => $this->validator->attributes['id'],
]);
$oldform_id = $this->LocalService()->dictionaryFormField->getOneFieldVal('dicform_id',[
'id' => $this->validator->attributes['id'],
]);
$oldform_id = !empty($oldform_id) ? $oldform_id : 0;
if($childen_count > 0 && $this->validator->attributes['dicform_id'] != $oldform_id){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '请先删除旧的选项值再进行修改选项字典!');
}
$model->editField();
//处理选项值
if($childen_count == 0 && isset($this->validator->attributes['dicform_id']) && !empty($this->validator->attributes['dicform_id'])){
//查询对应的选项值
$where_value = [
'where'=> [
'is_del' => 0,
'form_id' => $this->validator->attributes['dicform_id'],
],
'columns'=>['id','value_name','option_value','option_variable','is_score','score_value']
];
$value_datas = $this->LocalService()->dictionaryLevervalue->fetchAll($where_value);
if(!empty($value_datas)){
$i = 1;
foreach ($value_datas as $value_data){
$i++;
$res =[
'parent' => $this->validator->attributes['id'],
'name' => $value_data['value_name'], //选项名称
'var_name' => $value_data['option_variable'], //变量名
'value' => $value_data['option_value'], //选项值
'is_check' => 0, //是否默认选中
'is_score' => $value_data['is_score'], //分值选项
'score' => $value_data['score_value'], //分值
'form_id' => $this->validator->attributes['form_id'],
'form_type' => 'RADIO', //分值选项
'version' => $this->validator->attributes['version'],
'order' => $i,
];
//print_r($res);die;
//选项值入库
$newresult_id = $model->createField($res,1);
$this->LocalService()->log->saveFileLog(
$newresult_id,
self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
$this->validator->attributes,
Logs::OPERATE_CREATE,
'创建字典项表单字段'
);
}
}
}
$this->LocalService()->log->saveFileLog(
$this->validator->attributes['id'],
self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
$this->validator->attributes,
Logs::OPERATE_EDIT,
'编辑字典项表单字段'
);
} else {
$result_id = $model->createField();
$res = [];
//判断是否选择了表单选项的字典项 选了的话 把选项值直接带过来保存到本次表单字段的子集中
if(isset($this->validator->attributes['dicform_id']) && !empty($this->validator->attributes['dicform_id'])){
//查询对应的选项值
$where_value = [
'where'=> [
'is_del' => 0,
'form_id' => $this->validator->attributes['dicform_id'],
],
'columns'=>['id','value_name','option_value','option_variable','is_score','score_value']
];
$value_datas = $this->LocalService()->dictionaryLevervalue->fetchAll($where_value);
if(!empty($value_datas)){
$i = 1;
foreach ($value_datas as $value_data){
$i++;
$res =[
'parent' => $result_id,
'name' => $value_data['value_name'], //选项名称
'var_name' => $value_data['option_variable'], //变量名
'value' => $value_data['option_value'], //选项值
'is_check' => 0, //是否默认选中
'is_score' => $value_data['is_score'], //分值选项
'score' => $value_data['score_value'], //分值
'form_id' => $this->validator->attributes['form_id'],
'form_type' => 'RADIO', //分值选项
'version' => $this->validator->attributes['version'],
'order' => $i,
];
//print_r($res);die;
//选项值入库
$newresult_id = $model->createField($res,1);
$this->LocalService()->log->saveFileLog(
$newresult_id,
self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
$this->validator->attributes,
Logs::OPERATE_CREATE,
'创建字典项表单字段'
);
}
}
}
$this->LocalService()->log->saveFileLog(
$result_id,
self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
$this->validator->attributes,
Logs::OPERATE_CREATE,
'创建字典项表单字段'
);
}
return $this->RenderApiJson()->Success();
}
/**
* Notes: 处理旧的研究分层的字段数据 手写 和系统分配的默认显示字段
* @param
* @return
* @author haojinhua
* @date 2025-02-24
*/
public function setolddataAction(){
//查询所有小项目id
$item_ids = $this->LocalService()->itemInfo->fetchCol('id','is_del= 0 and fid > 0');
//查询所有小项目中的随机分组类型的表单
$randomgroup_id = $this->LocalService()->dictionaryFormGroup->getOneFieldVal('id', 'is_del = 0 and code = "RDG"');
//查询所有随机分组的表单
$form_ids = $this->LocalService()->itemForm->fetchCol('id',[
'is_del' => 0,
'group_id' => $randomgroup_id,
'item_id' => StringHelper::toArray($item_ids),
]);
//字段id信息
$form_filed_infos = $this->LocalService()->itemFormField->fetchAll([
'where' => [
'is_del' => 0,
'form_id' => StringHelper::toArray($form_ids),
'type' => 12
],
'columns'=>['id','form_id']
]);
if(!empty($form_filed_infos)){
foreach ($form_filed_infos as $form_filed_info){
$var_name = $form_filed_info['var_name'];
if(in_array($var_name,['RANDOM_GROUP_CUSTOM', 'RANGC'])){
//手写随机分组
$show_name = '随机号';
}else{
//系统分配
$show_name = '随机号/方案分组';
}
//修改随机号字段名称信息及缓存表
$this->LocalService()->itemFormField->updateField($form_filed_info['id'], 'showfiled_name', $show_name);
$v = $this->LocalService()->itemForm->buildFieldVersion($form_filed_info['form_id']);
$this->LocalService()->itemFormVersion->update(['field' => $v], ['form_id' => $form_filed_info['form_id']]);
}
echo "处理完成!";die;
}
}
/**
* Notes:处理itemFormVersion 表中历史数据增加是否隐私字段的值
* @param
* @return
* @author haojinhua
* @date 2025-03-31
*/
public function setversiondataAction(){
//查询所有小项目id
$item_ids = $this->LocalService()->itemInfo->fetchCol('id','is_del= 0 and fid > 0');
//查询所有小项目中的常规识别类型的表单
$gcogroup_id = $this->LocalService()->dictionaryFormGroup->getOneFieldVal('id', 'is_del = 0 and code = "GCO"');
//查询所有随机分组的表单
$form_ids = $this->LocalService()->itemForm->fetchCol('id',[
'is_del' => 0,
'group_id' => $gcogroup_id,
'item_id' => StringHelper::toArray($item_ids),
]);
foreach ($form_ids as $form_id){
$v = $this->LocalService()->itemForm->buildFieldVersion($form_id);
}
echo "处理完成!";die;
}
/**
* 添加版本
* @doc https://www.showdoc.com.cn/p/28696c346fb0381c8b38250b30929375
* @url http://xx.com/dictionary/field/addVersion
* @return JsonModel
* @throws Exception
*/
public function addVersionAction(): JsonModel
{
$validator = new ValidatorApplication();
$validator->attach(
[['version', 'form_id'], 'class' => new NotEmpty(), 'message' => fn($attr) => "{$attr}不能为空"]
);
if (!$validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, current($validator->getErrors()));
}
$form = [
'version' => $validator->attributes['version'],
'field' => '[]',
'form_id' => $validator->attributes['form_id'],
];
$query = $this->LocalService()->dictionaryFormVersion->fetchOne([
'where' => [
'version' => $validator->attributes['version'],
'form_id' => $validator->attributes['form_id']
]
]);
if ($query) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '版本号重复啦~~');
}
$this->LocalService()->dictionaryFormVersion->insert($form);
return $this->RenderApiJson()->Success();
}
/**
* 表单详情
* @doc https://www.showdoc.com.cn/p/45af2714da57a616fcb21b118c25fa98
* @url http://xx.com/dictionary/field/view
* @return JsonModel
* @throws Exception
*/
public function viewAction(): JsonModel
{
$validator = new ValidatorApplication();
$validator->attach(
[['id', 'form_type', 'form_id'], 'required', 'strict' => true], // 验证参数是否为 null
[['form_id'], 'integer'], // 验证 form_id 是否为整数
[['form_id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryForm, 'targetAttribute' => 'id'] // 验证 form_id 是否存在
);
if (!$validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
}
$model = new FieldForm($validator);
$query = $model->view() ?: ['order' => $this->getOrder()];
return $this->RenderApiJson()->Success($query, 'OK', [
'FormFileData' => $model->getFieldConfig(),
]);
}
/**
* 获取order
* @return int
*/
protected function getOrder(): int
{
return ($this->LocalService()->dictionaryFormField->getCount(['form_id' => $this->validator->attributes['form_id']]) + 1) * 10;
}
/**
* @param string $type
* @param string $validatorName
* @return mixed
*/
protected function getFieldConfig(string $type = '', string $validatorName = 'DictionaryFormField')
{
$config = include Laminas::$app->getConfig()['formValidator'][$validatorName];
$default = FieldForm::FORM_CONFIG_TEXT;
if ($type) {
$default = $type;
}
$formType = $this->LocalService()->dictionaryForm->fetchOne(['where' => ['id' => $this->validator->attributes['form_id']]])['type'];
if ($formType == Form::FORM_TYPE_SINGLE) {
unset($config[$default]['form']['is_list']);
}
$config[$default]['form'] = array_values($config[$default]['form'] ?? []);
return $config[$default];
}
/**
* 删除字段
* @doc https://www.showdoc.com.cn/p/6c88b2eada517628bfdc3ba0d87ce931
* @url http://xx.com/dictionary/field/del
* @return JsonModel
* @throws Exception
*/
public function delAction(): JsonModel
{
$this->validator->attach(
[['id'], 'required'],
[['id'], 'function', 'targetClass' => FieldForm::class, 'method' => 'invalidDeleteId']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new FieldForm($this->validator);
$model->delete();
$this->LocalService()->log->saveFileLog($this->validator->attributes['id'], self::LOG_TARGET, $this->validator->attributes, Logs::OPERATE_DELETE, '删除字段');
return $this->RenderApiJson()->Success();
}
public function getRelationInformationAction()
{
$this->validator->attach(
[['type'], 'required'],
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
if ($this->validator->attributes['type'] == 0) {
return $this->RenderApiJson()->Success([
['label' => '无关联信息', 'value' => '0']
]);
} elseif ($this->validator->attributes['type'] == 1) { // 表单
$query = $this->LocalService()->dictionaryForm->fetchAll([
'columns' => [ new Expression('name as label'),new Expression('id as value')],
'where' => ['is_del' => 0]
]);
return $this->RenderApiJson()->Success($query);
} elseif ($this->validator->attributes['type'] == 2) { // 属性
$query = Laminas::$serviceManager->dictionaryFormVersion->getField([
'form_id' => $this->validator->attributes['form_id'],
'version' => 'v1.0'
], true);
$options[] = ['label' => '无关联信息', 'value' => '0'];
foreach ($query as $v) {
$options[] = ['label' => $v['name'], 'value' => $v['id']];
}
return $this->RenderApiJson()->Success($options);
}
}
}

View File

@ -0,0 +1,229 @@
<?php
namespace Application\Controller;
use Application\Common\Enum;
use Application\Common\StatusCode;
use Application\Form\item\FormForm;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Db;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\FormFormatter;
use Application\Service\Extension\Formatter\FormViewFormatter;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Validator\ValidatorApplication;
use Application\Service\Logs;
use Exception;
use Laminas\View\Model\JsonModel;
/**
* 字典项设置 - 表单设置
*/
class FormController extends BasicController
{
/** @var string 表单字段配置key */
public const FORM_VALIDATOR = 'DictionaryForm';
public const LOG_TARGET = 'DictionaryForm';
/**
* 获取表单设置列表
* @doc https://www.showdoc.com.cn/p/757c59c613bc3c71675699d33694c165
* @url http://xx.com/dictionary/form
* @return JsonModel
*/
public function indexAction(): JsonModel
{
// 表单类型id
$form_group_id = $this->params()->fromPost('form_group_id', '');
// 表单tpye
$form_type = $this->params()->fromPost('form_type', '');
// 表单检索条件
$formWhereArr = ['is_del' => 0];
if($form_group_id) $formWhereArr['group_id'] = $form_group_id;
if($form_type !== '') $formWhereArr['type'] = $form_type;
$data = $this->LocalService()->dictionaryForm->fetchAllWithPagination([
'order' => ['order ASC'],
'columns' => ['id as parent', 'id', 'group_id', 'name', 'type', 'order'],
'where' => $formWhereArr
]);
Formatter::format($data['data'], new FormFormatter());
return $this->RenderApiJson()->Success($data['data'], 'OK', [
'total' => $data['count']
]);
}
/**
* 创建表单
* @doc https://www.showdoc.com.cn/p/e0d7e9989e501ccbfd039af9d025e572
* @url http://xx.com/dictionary/form/create
* @return JsonModel
* @throws Exception
*/
public function createAction(): JsonModel
{
$validator = new ValidatorApplication();
$validator->attach(
[[], 'form', 'config' => self::FORM_VALIDATOR],
[['reference_file'], 'default', 'value' => '[]'],
[['group_id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryFormGroup, 'targetAttribute' => 'id'],
[['name'], 'function', 'targetClass' => \Application\Form\FormForm::class, 'method' => 'invalidCreateName'],
[['checklist_id'], 'function', 'targetClass' => \Application\Form\FormForm::class, 'method' => 'invalidCheckListId'],
);
if (!$validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
}
$model = new \Application\Form\FormForm($validator);
if ($validator->attributes['id']) {
$model->editForm();
$this->LocalService()->log->saveFileLog($this->validator->attributes['id'], self::LOG_TARGET . '.form', $this->validator->attributes, Logs::OPERATE_EDIT, '编辑表单');
} else {
$this->LocalService()->log->saveFileLog($model->createForm(), self::LOG_TARGET . '.form', $this->validator->attributes, Logs::OPERATE_CREATE, '创建表单');
}
return $this->RenderApiJson()->Success();
}
/**
* 表单详情
* @doc https://www.showdoc.com.cn/p/e4c896652e7ae80c5560851e8ec8c171
* @url http://xx.com/dictionary/form/view
* @return JsonModel
* @throws Exception
*/
public function viewAction(): JsonModel
{
$validator = new ValidatorApplication();
$query = $this->LocalService()->dictionaryForm->fetchOne([
'columns' => [
'id', 'group_id', 'name', 'type', 'order', 'is_required', 'checklist_id', 'finish_condition',
'is_show', 'show_type', 'reference_file', 'rdg_type', 'var_name', 'can_patient_write', 'is_handwritten_signature',
'ds_stage','identification_edit'
],
'where' => ['id' => $validator->attributes['id']]
]) ?: ['order' => $this->getOrder()];
Formatter::format($query, new FormViewFormatter());
return $this->RenderApiJson()->Success($query, 'OK', [
'FormFileData' => ($this->getFieldConfig())
]);
}
/**
* 删除表单
* @doc https://www.showdoc.com.cn/p/2ed2ef0a8894ed47b8226d6daed08634
* @url http://xx.com/dictionary/form/del
* @return JsonModel
* @throws Exception
*/
public function delAction(): JsonModel
{
$validator = new ValidatorApplication();
$this->LocalService()->dictionaryForm->update([
'is_del' => 1
], [
'id' => $validator->attributes['id']
]);
$this->LocalService()->dictionaryFormField->update([
'is_del' => 1
], [
'form_id' => $validator->attributes['id']
]);
$this->LocalService()->log->saveFileLog($this->validator->attributes['id'], self::LOG_TARGET . '.form', $this->validator->attributes, Logs::OPERATE_DELETE, '删除表单');
return $this->RenderApiJson()->Success();
}
/**
* 获取字典项页面表单配置
* @return mixed
*/
protected function getFieldConfig(string $formValidator = self::FORM_VALIDATOR)
{
$config = include Laminas::$app->getConfig()['formValidator'][$formValidator];
$config['form'] = array_values($config['form']);
return $config;
}
protected function getOrder()
{
return $this->LocalService()->dictionaryForm->getMaxOrder('order');
}
/**
* 表单预览页面~
*/
public function previewAction()
{
$id = $this->params()->fromPost('id');
if (!$id) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '请传入正确的参数');
}
$query = $this->LocalService()->dictionaryForm->fetchOne([
'where' => ['id' => $id]
]);
return $this->RenderApiJson()->Success(ArrayHelper::merge($this->LocalService()->dictionaryForm->getPreviewConfig($id), [
'type' => $query['type'],
'show_type' => $query['show_type'] ?: 'right',
]));
}
/**
* 选择表单列表
*/
public function copyAction()
{
$this->validator->attach(
[['item_id'], 'required']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new \Application\Form\FormForm($this->validator);
$data = $model->getCopyList();
return $this->RenderApiJson()->Success($data['data'], 'OK', [
'total' => $data['total']
]);
}
/**
* 选择表单
* @url
* @doc
* @return JsonModel
* @throws Exception
*/
public function copyToAction(): JsonModel
{
$this->validator->attach(
[['id', 'item_id'], 'required'],
[['id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryForm, 'targetAttribute' => ['id']],
[['item_id'], 'exist', 'targetClass' => $this->LocalService()->itemInfo, 'targetAttribute' => ['id']],
[['id'], 'function', 'targetClass' => \Application\Form\FormForm::class, 'method' => 'invalidCopyId']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new \Application\Form\FormForm($this->validator);
$model->copyTo();
return $this->RenderApiJson()->Success();
}
}

View File

@ -0,0 +1,183 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/6/1 11:40
* @Description 表单管理 - 表单类型管理
*
*/
namespace Application\Controller;
use Application\Common\Com;
use Application\Common\StatusCode;
use Application\Mvc\Controller\BasicController;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Stdlib\ArrayUtils;
class FormgroupController extends BasicController
{
/**
* Notes: 左侧列表数据
* User: llbjj
* DateTime: 2022/6/1 20:51
*
* @return \Laminas\View\Model\JsonModel
*/
public function treelistAction(){
$formgroupWhere = 'is_del = 0';
$formgroupDatas = $this->LocalService()->dictionaryFormGroup->fetchAll([
'where' => $formgroupWhere,
'columns' => ['id', 'name', 'code'],
'order' => 'order',
]);
return $this->RenderApiJson()->Success($formgroupDatas);
}
/**
* Notes: 表单类型列表
* User: llbjj
* DateTime: 2022/6/1 11:41
*
*/
public function listAction(){
$searchField = [];
$searchField = $this->params()->fromPost();
$limit = $searchField['limit'] ?? 10;
$page = $searchField['page'] ?? 1;
$offset = ($page - 1) * $limit;
$formgroupWhere = [
'is_del' => 0
];
//表单类型列表检索表单
$DictionaryFormGroupSearchFormData = $this->Introduce('DictionaryFormGroup')['listSearch'];
$searchFormFieldData = array_values($DictionaryFormGroupSearchFormData);
// 根据检索创建where条件
if(!empty($searchField)) $formgroupWhere = ArrayUtils::merge($formgroupWhere, Com::CreateSearchWhere($searchField, $DictionaryFormGroupSearchFormData));
//表单类型总数
$formgroupCount = $this->LocalService()->dictionaryFormGroup->getCount($formgroupWhere);
//表单类型列表信息
$formgroupDatas = $this->LocalService()->dictionaryFormGroup->fetchAll([
'where' => $formgroupWhere,
'columns' => ['id', 'name', 'code', 'order'],
'order' => 'order',
'limit' => $limit,
'offset' => $offset
]);
return $this->RenderApiJson()->Success($formgroupDatas, '', ['total' => $formgroupCount, 'searchFormFieldData' => $searchFormFieldData]);
}
/**
* Notes: 表单类型增改
* User: llbjj
* DateTime: 2022/6/1 11:42
*
*/
public function editAction(){
$id = $this->params()->fromPost('id', 0);
$formFieldData = array_values($this->Introduce('DictionaryFormGroup')['editForm']);
$formGroupData = [];
if(!empty($id)){
$formGroupData = $this->LocalService()->dictionaryFormGroup->fetchOne([
'where' => [
'is_del' => 0,
'id' => $id,
],
'columns' => ['id', 'name', 'code', 'order']
]);
}else{
$formGroupData['order'] = $this->LocalService()->dictionaryFormGroup->getMaxOrder('order');
}
return $this->RenderApiJson()->Success($formGroupData, '', ['formFieldData' => $formFieldData]);
}
/**
* Notes: 保存表单类型信息
* User: llbjj
* DateTime: 2022/6/1 11:42
*
*/
public function saveAction(){
if($this->getRequest()->isPost()){
$this->Check('DictionaryFormGroup.editForm');
$dictionaryFormGroupSv = $this->LocalService()->dictionaryFormGroup;
$submitData = $this->params()->fromPost();
if(isset($submitData['old_data_str'])) unset($submitData['old_data_str']);
$id = 0;
$oper_type = 0;
if(!empty($submitData['id'])){
// 编辑检测信息是否存在
if(!$dictionaryFormGroupSv->getCount([
'id' => $submitData['id'],
'is_del' => 0
])) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息不存在!');
$id = $submitData['id'];
$oper_type = 1;
}else{
$submitData['is_del'] = 0;
}
// 验证名称是否重复
$dictionaryFormGroupSv->check_field_repeat('name', $submitData['name'], [
'is_del' => 0,
new Operator('id', Operator::OP_NE, $id)
], '表单类型名称【'.$submitData['name'].'】已存在!');
// 验证编码是否重复
$dictionaryFormGroupSv->check_field_repeat('code', $submitData['code'], [
'is_del' => 0,
new Operator('id', Operator::OP_NE, $id)
], '表单类型编码【'.$submitData['code'].'】已存在!');
$result = $dictionaryFormGroupSv->save($submitData);
$event_id = $id ?: $result;
if($result) $this->LocalService()->log->saveFileLog($event_id, 'DictionaryFormGroup.editForm', $submitData, $oper_type);
return $this->RenderApiJson()->Success(['id' => $event_id]);
}else{
return $this->RenderApiJson()->Error(StatusCode::E_ACCESS);
}
}
/**
* Notes: 删除表单类型 - 表单类型下已有表单信息,则不可删除
* User: llbjj
* DateTime: 2022/6/1 11:43
*
*/
public function deleteAction(){
if($this->getRequest()->isPost()){
$id = $this->params()->fromPost('id', 0);
$dictionaryFormGroupSv = $this->LocalService()->dictionaryFormGroup;
// 检测信息是否存在
if(!$dictionaryFormGroupSv->getCount([
'id' => $id,
'is_del' => 0
])) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息不存在!');
// 检测表单类型下是否有表单信息,有则不能删除
$dictionaryFormCount = $this->LocalService()->dictionaryForm->getCount([
'group_id' => $id,
'is_del' => 0
]);
if($dictionaryFormCount) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '此表单类型下已存在表单信息,不可删除!');
$result = $dictionaryFormGroupSv->upDelState([
'id' => $id,
], 1);
if($result) $this->LocalService()->log->saveFileLog($id, 'DictionaryFormGroup', [], 2);
return $this->RenderApiJson()->Success();
}else{
return $this->RenderApiJson()->Error(StatusCode::E_ACCESS);
}
}
}

View File

@ -0,0 +1,368 @@
<?php
//declare(strict_types=1);
namespace Application\Controller;
use Application\Common\Container;
use Application\Form\ExportModel;
use Application\Mvc\Controller\Plugins\RenderApiJson;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Helper\ExcelHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Queue\jobs\SyncPatientFormJob;
use Application\Service\Extension\Queue\QueueApplication;
use Application\Service\Extension\Xml\LaboratoryXmlGenerator;
use Laminas\ApiTools\Admin\Module as AdminModule;
use Laminas\Http\Response;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
use function class_exists;
/**
*
* @package Application\Controller
*
* @method RenderApiJson RenderApiJson()
* @method Container LocalService()
*/
class IndexController extends AbstractActionController
{
const Genercsetinfotype='Genercsetinfotype';//字典项分类-1
const Genercsetinfo='Genercsetinfo';//字典项通用名
/**
* @return Response|ViewModel
*/
public static function yieldFuc($num)
{
$oper_type = [0,1,2];
$log_type = [0,1,3];
$formData = include $_SERVER['DOCUMENT_ROOT'].'/../formData/formMap.php';
for($i = 0; $i < $num; $i++){
$logData = [
'user_id' => 1,
'event_from' => array_rand($formData),
'event_id' => $i,
'create_time' => time(),
'log_ip' => '127.0.0.1',
'oper_type' => array_rand($oper_type),
'log_type' => array_rand($log_type),
'change_data' => '测试'
];
yield $logData;
}
}
public function indexAction()
{
set_time_limit(0);
$datas = self::yieldFuc(10000);
foreach($datas as $data){
$this->LocalService()->adminLog->save($data);
}
exit('finish');
echo "<pre>";print_r($this->LocalService()->identity->getIdentityData());exit;
for($i = 19728; $i <= 19830; $i++){
echo $i.' ';
}
exit;
$formFieldData = $this->Introduce(self::Genercsetinfotype);
$formFieldData = empty($formFieldData) ? [] : array_values($formFieldData);
$formValData = 1 ? $this->LocalService()->dictionaryGenercsetinfotype->fetchOne(['where' => 'id = 1']) : [];
return $this->RenderApiJson()->Success($formValData, '', ['formFieldData' => $formFieldData]);
$maxId = $this->LocalService()->adminUser->getOneFieldVal('id', 'status = 1', 'id desc');
$maxOrder = $this->LocalService()->adminUser->getMaxOrder('id', 'status = 1');
echo 'maxId'.$maxId.' </br>';
echo 'maxOrder'.$maxOrder.' </br>';exit;
$this->LocalService()->adminUser->check_field_repeat('mobile', '15001062410', ['field' => 'is_del', 'value' => 1]);
// 操作前数据
$oprt_pre = [
'id' => 1,
'name' => '张三',
'status' => 0,
'mobile' => '12345678901',
'role_id' => 1
];
// 操作后数据
$oprt_last = [
'id' => 1,
'name' => '张山',
'status' => 0,
'mobile' => '01234567890',
'role_id' => '1,2,3,4,5'
];
//日志文件数据
$logData = [
'event' => 'AdminUser',
'ip' => '127.0.0.1',
'user_id' => 1,
'user_name' => '超级管理员',
'time' => time(),
'oprt_pre' => $oprt_pre,
'oprt_last' => $oprt_last
];
// 获取修改的字段
$changeData = array_diff_assoc($logData['oprt_last'], $logData['oprt_pre']);
if(!empty($changeData)){
$formMapData = include $_SERVER['DOCUMENT_ROOT'].'/../data/FormData/formMap.php';
$form_col_desc_data = include $_SERVER['DOCUMENT_ROOT'].'/../data/FormData/'.$logData['event'].'Data.php';
$event_name = $formMapData[$logData['event']];
foreach($changeData as $changeKey => &$changeVal){
if(isset($form_col_desc_data[$changeKey]['val_source']) and is_callable($form_col_desc_data[$changeKey]['val_source'])){
$changeVal = $form_col_desc_data[$changeKey]['val_source']($this->LocalService(), $changeVal);
}
$desc_data[] = $form_col_desc_data[$changeKey]['title'].''.$changeVal;
}
}
echo "<pre>";print_r($changeData);
echo $logData['user_name'].' 修改了:</br></br>'.implode('</br>', $desc_data);
echo "<pre>";print_r($logData);exit;
if (class_exists(AdminModule::class, false)) {
return $this->redirect()->toRoute('api-tools/ui');
}
return new ViewModel();
}
protected int $contentId = 0;
protected string $prop = '';
public function testAction()
{
$model = new ExportModel();
// $model->exportLogicError();
//2267; // pumch - 1101
ExcelHelper::exportExcel($model->exportLogicError(1101), [
[
['项目ID', 'item_id', 'text'],
['中心编号', 'sign_id', 'text'],
['筛选号', 'patient_id', 'text'],
['访视名称', 'checktime_id', 'text'],
['表单名称', 'form_id', 'text'],
['字段名称', 'prop', 'text'],
['原来值', 'origin_value', 'text'],
['更正值', 'value', 'text'],
// ['更正原因', 'note', 'text'],
['质疑内容', 'expression_note', 'text'],
['质疑时间', 'create_time', 'text'],
['质疑发出人员/角色', 'create_user_id', 'text'],
['质疑回复内容', 'reply_content', 'text'],
['质疑回复时间', 'replay_time', 'text'],
['质疑回复人员/角色', 'replay_user_id', 'text'],
['质疑关闭时间', 'is_closed', 'text'],
['质疑关闭人员/角色', 'closed_user_id', 'text'],
]
], time(), 'xlsx', '', ['质疑数据']);
die;
// $a = new App();
// $a->itemId = 1084;
// $a->signId = 1248;
// $a->menuId = App::MODULE_CS;
// $a->push([37]);
// die('123123');
// var_dump(Laminas::$serviceManager->itemForm->getPreviewConfig(518, true));die;
// $model = new SyncPatientFormJob();
// $model = new FormContentXmlGenerator();
// $model->patientId = 4134;
// $model->itemSignId = 272;
// $model->itemId = 101;
// $model->formId = 947; // 3917 //747 717;
// $model->checkTimeId = 566; //747 717;
// $xmlModel = new XmlBuilder();
// $data = $xmlModel->build($model->generate());
// echo $data;die;
//// echo json_encode($data, JSON_UNESCAPED_SLASHES);die;
////// $model->run();
// echo QueueApplication::push($model);die;
// die;
$model = new LaboratoryXmlGenerator();
// $model->setHeader([
// [
// 'key' => 'TEST',
// 'value' => '是',
// 'transactionType' => 'Insert',
// ],
// [
// 'key' => 'DATE',
// 'value' => '2022-1-1',
// 'transactionType' => 'Update',
// ]
// ]);
// $model->setContent(
// [
// [
// ['itemOID' => 'INDICATORS', 'transactionType' => 'Insert', 'value' => '白细胞'], // 指标
// ['itemOID' => 'UNIT', 'transactionType' => 'Insert', 'value' => '10^9/L'], // 单位
// ],
// [
// ['itemOID' => 'INDICATORS', 'transactionType' => 'Insert', 'value' => '中性粒细胞绝对值'], // 指标
// ['itemOID' => 'UNIT', 'transactionType' => 'Insert', 'value' => '10^9/L'], // 单位
//// ['itemOID' => 'RESULT', 'transactionType' => 'Insert', 'value' => '4.05'], // 结果
//// ['itemOID' => 'RANGE', 'transactionType' => 'Insert', 'value' => '1.8-6.3'], // 范围
//// ['itemOID' => 'NORMAL', 'transactionType' => 'Insert', 'value' => 'true'], // 正常
// ]
// ]
// );
// $model->setFormId(3946);
// $model->setPatientId(1992);
// $model->generate();
// $builder = new XmlBuilder();
//
// echo $builder->build($model->generate());die;
$query = Laminas::$serviceManager->patient->fetchAll([
// 'where' => ['item_id' => 1084, 'itemsig_id' => 1344, 'is_del' => 0]
'where' =>
[
// 'id' => [2032, 2069, 2640, 4134, 4557, 5015, 5358, 5488, 5531, 5599, 5659, 5769, 6083]
// 'id' => [4814, 4813, 2032, 2069, 2640, 4134, 4557, 5015, 5358, 5488, 5531, 5599, 5659, 5769, 6083]//[2032, 2069, 2640, 4134, 4557, 5015, 5358, 5488, 5531, 5599, 5659, 5769, 6083],
// 'id' => [2069, 2640, 4134, 4557, 5015, 5358, 5488, 5531, 5599, 5659, 5769, 6083],
'id' => [5651, 5652, 5878, 6127, 6146],
// 'id' => [2367, 2368, 2369, 2370, 2539, 2540, 2541, 4813, 2863, 2864, 2865, 2866, 4814, 4584, 4585, 5651, 5652, 5669, 5670, 5878, 5879, 5941, 6127, 6146]
] // 1043
// 'where' => ['id' => [2367, 2368, 2369, 2370, 2539, 2540, 2541, 2863, 2864, 2865, 2866, 4584, 4585]] // 2368, 2369, 2370, 2539, 2540, 2541, 2863, 2864, 2865, 2866, 4584, 4585
// 'where' => ['id' => 2069] // 1043
]);
//
// $model = new SyncPatientFormJob();
//// $model = new FormContentXmlGenerator();
// $model->patientId = intval($query[0]['id']);
// $model->itemSignId = $query[0]['itemsig_id'];
// $model->itemId = intval($query[0]['item_id']);
// $model->formId = 3921; //747 717;
// $model->checkTimeId = intval(563); //747 717;
//// $xmlModel = new XmlBuilder();
//// $data = $xmlModel->build($model->generate());
//// echo $data;die;
// $model->run();
// die;
////// 新增 一个受试者
// die;
// var_dump($query);die;
// 处理 ae
foreach ($query as $item) {
// $model = new SyncPatientJob();
////// $model = new PatientXmlGenerator();
// $model->patientId = intval($item['id']); // 受试者id
// $model->itemSignId = $item['itemsig_id']; // 中心id
//// $xmlModel = new XmlBuilder();
//// $data = $xmlModel->build($model->generate());
//// echo $data;die;
//// $model->run();
// echo QueueApplication::push($model);
// // 1406, 1407, 1409, 1410, 1411, 1412, 1408, 1413, 1414, 99
//
//// foreach ([560, 561, 562, 575, 563, 564, 565, 566, 570, 567, 571, 569, 572, 573, 99] as $v) {
// foreach ([1409] as $v) {
// $model = new SyncPatientFormJob();
//// $model = new FormContentXmlGenerator();
// $model->patientId = intval($item['id']);
// $model->itemSignId = 1344; //$item['itemsig_id'];
// $model->itemId = 1084; // intval($item['item_id']);
// $model->formId = 4602; //82841, 2841;
// $model->checkTimeId = intval($v); //747 717;
//// $model->isSync = true;
//// $xmlModel = new XmlBuilder();
//// $data = $xmlModel->build($model->generate());
//// echo json_encode($data, JSON_UNESCAPED_SLASHES);die;
// echo QueueApplication::push($model);
//// $model->isSync = false;
//// echo QueueApplication::push($model);
// }
//die;
// $model = new SyncPatientFormJob();
// $model = new FormContentXmlGenerator();
// $model->patientId = intval($item['id']);
// $model->itemSignId = 272; //$item['itemsig_id'];
// $model->itemId = 101; // intval($item['item_id']);
// $model->formId = 3918; //747 717;
// $model->checkTimeId = intval(1412); //747 717;
//// $model->isDeleteItemData = true;
//// echo QueueApplication::push($model);die;
// $xmlModel = new XmlBuilder();
// $data = $xmlModel->build($model->generate());
// echo json_encode($data, JSON_UNESCAPED_SLASHES);die;
$this->syncPatientForm($item);
}
die;
}
private function syncPatientForm(array $query)
{
$allCheckTime = Laminas::$serviceManager->itemPatientchecktime->fetchAll([
'columns' => ['checktime_id'],
'where' => [
'patient_id' => $query['id']
]
]);
$allCheckTime[] = [
'checktime_id' => 99
];
foreach ($allCheckTime as $checkTime) {
if ($checkTime['checktime_id'] == 99) {
$allFormId = Laminas::$serviceManager->itemForm->fetchCol('id', [
'item_id' => $query['item_id'],
'group_id' => [FormGroup::SAE, FormGroup::AE, FormGroup::THROUGH_PROCESS, FormGroup::TEST_SUMMARY],
'is_del' => 0
]);
} else {
$allFormId = Laminas::$serviceManager->patientForm->fetchCol('form_id', ['patient_id' => $query['id'], 'is_del' => 0, 'checktime_id' => $checkTime['checktime_id']]);
}
$allFormId = array_unique(array_values($allFormId));
foreach ($allFormId as $formId) {
// var_dump($formId);
// $formId = intval($formId['form_id']);
$form = Laminas::$serviceManager->itemForm->fetchOne([
'where' => ['id' => $formId]
]);
if ($form['group_id'] != FormGroup::CHECK_OCR) {
continue;
}
if ($checkTime['checktime_id'] != 99) {
if (in_array($form['group_id'], [FormGroup::SAE, FormGroup::AE, FormGroup::THROUGH_PROCESS, FormGroup::TEST_SUMMARY])) {
continue;
}
}
$model = new SyncPatientFormJob();
// $model = new FormContentXmlGenerator();
$model->patientId = intval($query['id']);
$model->itemSignId = $query['itemsig_id'];
$model->itemId = intval($query['item_id']);
$model->formId = $formId; //747 717;
$model->checkTimeId = intval($checkTime['checktime_id']); //747 717;
// 有数据说明写了
// if ($model->isSync() === false || $model->getFormContent('fetchOne', false) === false || $model->getIsProcessSync() === true) {
// continue;
// }
// $model->formContent = [];
// $xmlModel = new XmlBuilder();
// $data = $xmlModel->build($model->generate());
// echo $data;
// $model->run();
echo "受试者: [{$query['id']}]. 检查点: [{$checkTime['checktime_id']}]. 表单 [{$formId}]. " . PHP_EOL;
QueueApplication::push($model);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,699 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 13:42
* @Description登录
*
*/
namespace Application\Controller;
use Application\Common\Container;
use Application\Common\RedisEnum;
use Application\Common\StatusCode;
use Application\Form\LoginForm;
use Application\Mvc\Controller\Plugins\RenderApiJson;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Identity\Identity;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Sms\SmsRateLimitException;
use Application\Service\Extension\Validator\ValidatorApplication;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Laminas\Db\Sql\Where;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\Exception\InvalidArgumentException;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
use Overtrue\Socialite\User;
/**
* Class LoginController
* @package Application\Controller
* @method Container LocalService()
* @method RenderApiJson RenderApiJson()
*/
class LoginController extends AbstractActionController
{
/**
* @note 账户密码登录
* @return JsonModel
*/
public function accountPwdAction() : JsonModel
{
return $this->RenderApiJson()->Success($this->LocalService()->loginClient->accoutPwd->login());
}
/**
* 获取扫码登陆登录二维码地址
* @doc https://www.showdoc.com.cn/1936668638131821/8824484392761392
* @url GET http://xx.com/login-code
* @return JsonModel
*/
public function loginCodeAction(): JsonModel
{
$model = new LoginForm();
// 获取登录网址
$wechatConfig = $this->getEvent()->getApplication()->getConfig()['wechat'];
$code = StringHelper::generateHashValue();
$info = $model->getLoginInfo($code);
$this->LocalService()->redisExtend->getRedisInstance()->setex(RedisEnum::TMP_CODE . $code, 180, $info);
return $this->RenderApiJson()->Success([
'url' => strtr(
$wechatConfig['forward_code_url'],
['{auk}' => $wechatConfig['forward_auk'], '{state}' => $code]
),
'code' => $code
]);
}
/**
* v2版本获取扫码登陆二维码
* @url GET http://xx.com/v2/login-code
* @return JsonModel
*/
public function loginCodeV2Action(): JsonModel
{
$model = new LoginForm();
$code = StringHelper::generateHashValue();
$info = $model->getLoginInfo($code);
$this->LocalService()->redisExtend->getRedisInstance()->setex(RedisEnum::TMP_CODE . $code, 180, $info);
$host = "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}";
if ($_SERVER['HTTP_HOST'] === 'local.kingdone.com') {
$host = 'https://esm.kingdone.com';
}
return $this->RenderApiJson()->Success([
'url' => "{$host}/oauth?code={$code}",
'code' => $code
]);
}
public function oAuthAction(): ViewModel
{
// 获取登录网址
$wechatConfig = $this->getEvent()->getApplication()->getConfig()['wechat'];
$code = $_GET['code'];
if (!$code) {
return $this->RenderApiJson()->Error(StatusCode::E_LOGIN_CODE_EXPIRE, '无效的二维码');
}
$view = new ViewModel();
$view->setTemplate('application/login/auth');
$view->setTerminal(true);
$view->setVariables([
'authUrl' => strtr(
$wechatConfig['forward_code_url'],
['{auk}' => $wechatConfig['forward_auk'], '{state}' => $code]
)
]);
return $view;
}
/**
* 用户是否已经扫码登录
* @doc https://www.showdoc.com.cn/p/7b784fee3c5be975d574144dc02836fc
* @url POST http://xx.com/is-scan
* @return JsonModel
*/
public function isScanAction(): JsonModel
{
// 验证是否登录成功
$code = $this->getRequest()->getPost()->get('code');
$redis = $this->LocalService()->redisExtend->getRedisInstance();
// 判断code 是否过期
if (!$redis->get(RedisEnum::TMP_CODE . $code)) {
return $this->RenderApiJson()->Error(StatusCode::E_LOGIN_CODE_EXPIRE, '二维码已过期,请刷新后重试');
}
// 检查用户状态, 是否绑定微信
$statusKey = RedisEnum::USER_STATUS . $code;
$info = $redis->get($statusKey);
if (!$info) {
return $this->RenderApiJson()->Error(StatusCode::E_RUNTIME, '未发现用户扫码');
}
$info = json_decode($info, true);
if (!isset($info['bind_status'])) {
return $this->RenderApiJson()->Error(StatusCode::E_RUNTIME, '获取用户信息失败');
}
// 未绑定和已绑定的用户返回信息做一下处理
if ($info['bind_status'] == -1) {
return $this->RenderApiJson()->Success([
'bind_status' => -1,
'bind_code' => $code
]);
} else {
$redis->del($statusKey);
if (isset($info['group']) && $info['group'] == 2) {
return $this->RenderApiJson()->Success($info, 'OK', [
'auth' => $this->LocalService()->identity->generateTokenByUserId($info['id'], Identity::PLATFORM_REAL)
]);
}
return $this->RenderApiJson()->Success($info);
}
}
/**
* @return \Laminas\Http\Response
*/
public function forwardAction(): \Laminas\Http\Response
{
$auk = $this->params()->fromQuery('auk', '');
$scan_code = $this->params()->fromQuery('state');
$wechatConfig = $this->LocalService()->config['wechat'];
$callBackUrl = "{$wechatConfig['forward_callback_url']}?auk={$auk}&scan_code={$scan_code}";
$redirectUrl = $this->LocalService()->wechat->getApp()
->oauth
->scopes(['snsapi_userinfo'])->with(['forceSnapShot' => true])
->redirect($callBackUrl);
return $this->redirect()->toUrl($redirectUrl);
// die;
}
/**
* 微信扫码回调
* @throws GuzzleException
* @throws AuthorizeFailedException
*/
public function callbackAction()
{
$auk = $this->params()->fromQuery('auk', '');
$code = $this->params()->fromQuery('code', '');
$scan_code = $this->params()->fromQuery('scan_code', '');
if($auk !== ''){
$callBackUrl = $this->LocalService()->config['wechatRedirectUrlConfig'][$auk];
return $this->redirect()->toUrl($callBackUrl.'?code='.$code.'&scan_code='.$scan_code);
}else{
// 微信配置信息
$wechatConfig = $this->LocalService()->config['wechat'];
if($wechatConfig['open_forward']){
// 获取微信用户信息
$user = $this->LocalService()->httpSv->post($wechatConfig['forward_user_url'], ['code'=>$code]);
$user = new User($user);
}else{
$user = $this->LocalService()->wechat->getApp()->oauth->userFromCode($code);
}
$model = new LoginForm();
$model->code = $scan_code;
$status = $model->setCallback($user);
if ($status['bind_status'] == -1) {
include __DIR__ . '/../../view/application/login/bind.phtml';
}else{
include __DIR__ . '/../../view/application/login/success.phtml';
}
die;
}
}
/**
* Notes: 通过code值获取wechat用户信息
* User: llbjj
* DateTime: 2022/7/26 13:46
*
*/
public function wechatuserAction(): JsonModel
{
$code = $this->params()->fromPost('code');
$scopes = $this->params()->fromPost('scopes', 'snsapi_userinfo');
$user = $this->LocalService()->wechat->getApp()->oauth->scopes([$scopes])->userFromCode($code);
$userData = [
'id' => $user->getId(),
'nickname' => $user->getNickname(),
'avatar' => $user->getAvatar(),
'openid' => $user->getId(),
];
return $this->RenderApiJson()->Success($userData);
}
/**
* 发送短信
* @doc https://www.showdoc.com.cn/p/020e03537a97fb3c19c8871d60a2427a
* @url POST http://xx.com/send-sms
* @return JsonModel
* @throws Exception
*/
public function sendSmsAction(): JsonModel
{
$mobile = $this->params()->fromPost('mobile');
if (!Laminas::$serviceManager->adminUser->fetchOne(['where' => ['mobile' => $this->params()->fromPost('mobile'), 'is_del' => 0]])) {
throw new InvalidArgumentException("没有匹配的账户信息,请联系客服后重试!", StatusCode::E_FIELD_VALIDATOR['code']);
}
$redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
$limitKey = RedisEnum::SMS_LIMIT . $mobile;
// 验证发送速率
if ($redis->get($limitKey)) {
throw new SmsRateLimitException("短信发送频繁, 60秒内只能发送一次。");
}
$response = $this->LocalService()->sms->send($mobile);
if ($response['error'] != 0) {
throw new InvalidArgumentException("验证码发送失败", StatusCode::E_FIELD_VALIDATOR['code']);
}
$this->LocalService()->redisExtend->getRedisInstance()->setex(RedisEnum::SMS . $mobile, 60 * 5, $response['code']);
// 设置请求速率key
$redis->setex(RedisEnum::SMS_LIMIT . $mobile, 60, 1);
return $this->RenderApiJson()->Success();
}
public function h5SendSmsAction(): JsonModel
{
$mobile = $this->params()->fromPost('mobile');
$redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
$limitKey = RedisEnum::SMS_LIMIT . $mobile;
// 验证发送速率
if ($redis->get($limitKey)) {
throw new SmsRateLimitException("短信发送频繁, 60秒内只能发送一次。");
}
// 验证手机号是否是受试者用户
$adminUser = $this->LocalService()->adminUser->fetchOne([
'where' => ['is_del' => 0, 'mobile' => $mobile, 'patient_status' => 0],
'columns' => ['id', 'patient_openid']
]);
if(empty($adminUser)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '用户不存在,请联系相关客服!');
if(!empty($adminUser['patient_openid'])) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '请勿重复绑定!');
$response = $this->LocalService()->sms->send($mobile);
if ($response['error'] != 0) {
throw new InvalidArgumentException("验证码发送失败", StatusCode::E_FIELD_VALIDATOR['code']);
}
$this->LocalService()->redisExtend->getRedisInstance()->setex(RedisEnum::SMS . $mobile, 60 * 5, $response['code']);
// 设置请求速率key
$redis->setex(RedisEnum::SMS_LIMIT . $mobile, 60, 1);
return $this->RenderApiJson()->Success();
}
/**
* @note 发送登录验证码(账户登录使用)
* @return JsonModel
* @throws \RedisException
*/
public function sendLoginSmsAction(): JsonModel
{
$mobile = $this->params()->fromPost('mobile');
if(empty($mobile)) {
throw new InvalidArgumentException("手机号不能为空!");
}
$redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
$limitKey = RedisEnum::SMS_LIMIT . $mobile;
// 验证发送速率
if ($redis->get($limitKey)) {
throw new SmsRateLimitException("短信发送频繁, 60秒内只能发送一次。");
}
// 验证手机号是否是受试者用户
$adminUser = $this->LocalService()->adminUser->fetchOne([
'where' => [
'is_del' => 0,
'mobile' => $mobile,
'or' => [
'real_status' => 0,
'status' => 0,
],
],
'columns' => ['id']
]);
if(empty($adminUser)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '用户不存在,请联系相关客服!');
$response = $this->LocalService()->sms->send($mobile);
if ($response['error'] != 0) {
throw new InvalidArgumentException("验证码发送失败", StatusCode::E_FIELD_VALIDATOR['code']);
}
$this->LocalService()->redisExtend->setDatabase(6)->getRedisInstance()->setex(RedisEnum::SMS_LOGIN . $mobile, 60 * 5, $response['code']);
// 设置请求速率key
$redis->setex(RedisEnum::SMS_LIMIT . $mobile, 60, 1);
return $this->RenderApiJson()->Success();
}
/**
* 绑定用户
* @doc https://www.showdoc.com.cn/p/9bdf32451aed20b9120fbe047427691b
* @url POST http://xx.com/bind
* @throws Exception
*/
public function bindAction(): JsonModel
{
$validator = new ValidatorApplication();
$mobile = $this->params()->fromPost('mobile');
// 验证短信验证码
$code = $this->LocalService()->redisExtend->getRedisInstance()->get(RedisEnum::SMS . $validator->attributes['mobile']);
if (!$code || $code != $this->params()->fromPost('checkcode')) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "验证码有误");
}
$callbackInfo = $this->LocalService()->redisExtend->getRedisInstance()->get(RedisEnum::USER_STATUS . $validator->attributes['bind_code']);
// 如果扫完码超过了一个小时还没进行绑定操作, key已经过期了
if (!$callbackInfo) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "已绑定或绑定超时。");
}
$callbackInfo = json_decode($callbackInfo, true);
// 更新对应用户的信息
$this->LocalService()->adminUser->update([
'avatar' => $callbackInfo['avatar'],
'nickname' => $callbackInfo['nickname'],
'openid' => $callbackInfo['openid'],
], ['mobile' => $validator->attributes['mobile']]);
// 获取用户信息
$user = $this->LocalService()->adminUser->fetchOne([
'where' => ['mobile' => $validator->attributes['mobile'], 'is_del' => 0]
]);
$this->LocalService()->redisExtend->getRedisInstance()->del(RedisEnum::USER_STATUS . $validator->attributes['bind_code']);
return $this->RenderApiJson()->Success($this->LocalService()->identity->getLoginInfo($user['id']));
}
/**
* 登出
* @doc https://www.showdoc.com.cn/p/fdd7b478543cdbcd19c64f9443dd2a73
* @url GET http://xx.com/logout
* @return JsonModel
*/
public function logoutAction(): JsonModel
{
$this->LocalService()->identity->disCard();
return $this->RenderApiJson()->Success();
}
/**
* 小程序登录
* @doc https://www.showdoc.com.cn/p/b89babadc4ef3ebc46910f8605355ef8
* @url GET http://xx.com/mini-login
* @return JsonModel
* @throws GuzzleException|InvalidConfigException|Exception
*/
public function miniLoginAction(): JsonModel
{
// 获取手机号code
$code = $this->params()->fromPost('code');
// 获取openid code, 目前没用了
$sessionCode = $this->params()->fromPost('session_code');
$platform = $this->params()->fromPost('platform');
$phoneResponse = $this->LocalService()->wechat->getMiniApp($platform)->phone_number->getUserPhoneNumber($code);
if ($phoneResponse['errmsg'] != 'ok') {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '微信授权失败');
}
if (!isset($phoneResponse['phone_info']['purePhoneNumber'])) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '获取手机号失败!');
}
$data = $this->LocalService()->identity->generateTokenByMobile(
$phoneResponse['phone_info']['purePhoneNumber'],
Identity::PLATFORM_MINI_PROGRAM
);
if (count($data) !== count($data, COUNT_RECURSIVE) && count($data) > 1) {
return $this->RenderApiJson()->Success([], 'OK', ['auth' => $data]);
} else {
return $this->RenderApiJson()->Success(
current($data)
);
}
}
public function patientH5OauthAction() {
$code = $this->params()->fromPost('code', ''); // 微信Code值用于获取openid
$type = $this->params()->fromPost('type', 'default');
if( empty($code) ) return $this->RenderApiJson($type)->Success([
'status' => 1,
'msg' => '非法登录!'
]);
// 获取微信公众号用户信息
$wechatUserInfo = $this->LocalService()->wechat->getPatientH5App($type)->oauth->scopes(['snsapi_base'])->userFromCode($code);
if( empty($wechatUserInfo->getId()) ) return $this->RenderApiJson()->Success([
'status' => 1,
'msg' => '公众号授权失败!'
]);
// 查询微信公众号openid对应的用户信息
$adminUser = $this->LocalService()->adminUser->fetchOne([
'where' => [
'is_del' => 0,
'patient_openid' => $wechatUserInfo->getId()
],
'columns' => [ 'id', 'mobile', 'patient_status']
]);
if( empty($adminUser) ) return $this->RenderApiJson()->Success([
'status' => 2,
'msg' => '账户未绑定!',
'openid' => $wechatUserInfo->getId()
]);
if( !empty($adminUser['patient_status']) ) return $this->RenderApiJson()->Success([
'status' => 1,
'msg' => '账户已禁用,请联系相关客服人员!'
]);
// 受试者登录
$authData = $this->LocalService()->identity->generateTokenByUserId($adminUser['id'], Identity::PLATFORM_H5_PROGRAM_PATIENT);
return $this->RenderApiJson()->Success([
'token' => $authData['token'],
'status' => 0
]);
}
public function h5BindAction()
{
$openid = $_POST['openid'];
$smsCode = $_POST['sms_code'];
$mobile = $_POST['mobile'];
$type = $_POST['type'];
// 验证短信验证码
$smsCodeVal = $this->LocalService()->redisExtend->setDatabase(6)->getRedisInstance()->get(RedisEnum::SMS . $mobile);
if (!$smsCodeVal || $smsCodeVal != $smsCode) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "验证码有误");
}
$adminUser = $this->LocalService()->adminUser->fetchOne([
'where' => ['is_del' => 0, 'mobile' => $mobile, 'patient_status' => 0],
'columns' => ['id', 'patient_openid']
]);
if(empty($adminUser)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '用户不存在,请联系相关客服人员!');
if (!empty($adminUser['patient_openid'])) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "请勿重复绑定。");
}
$wechatUserInfo = $this->LocalService()->wechat->getPatientH5App($type)->user->get($openid);
if (empty($wechatUserInfo['openid'] ?? '')) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "获取用户信息失败,请重试。");
}
// 更新受试者用户的openid
Laminas::$serviceManager->adminUser->updateField($adminUser['id'], 'patient_openid', $openid);
// 授权登录
$authData = $this->LocalService()->identity->generateTokenByUserId($adminUser['id'], Identity::PLATFORM_H5_PROGRAM_PATIENT);
return $this->RenderApiJson()->Success(['token' => $authData['token']]);
}
public function getwebsitefilingAction(): JsonModel
{
return $this->RenderApiJson()->Success($this->LocalService()->adminWebsitefiling->getCurrentWebsiteFiling());
}
public function indexAction(){
$viewModel = new ViewModel();
$viewModel->setTerminal(true);
return $viewModel;
}
public function patientH5Action() {
$time = $this->params()->fromQuery('date', '');
$type = $this->params()->fromQuery('type', 'default');
$sendUrl = $this->LocalService()->config['sendUrl'];
$sendUrl .= '/#/patientH5?type='.$type;
if($time) $sendUrl .= '&date=' . $time;
$redirectUrl = rawurlencode($sendUrl);
$appid = $this->LocalService()->wechat->getPatientH5App($type)->getConfig()['app_id'];
return $this->redirect()->toUrl("https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirectUrl}&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect");
}
/**
* @note webH5 静默授权登录
* @return \Laminas\Http\Response
*/
public function webH5Action(): \Laminas\Http\Response
{
$wechatH5Config = $this->LocalService()->config['wechat']['h5Proxy'];
// 开启代理
if($wechatH5Config['open_forward']) {
return $this->redirect()->toUrl(strtr(
$wechatH5Config['forward_code_url'],
['{auk}' => $wechatH5Config['forward_auk']]
));
}
$sendUrl = $this->LocalService()->config['sendUrl'];
$sendUrl .= '/#/webH5';
if(!empty($this->params()->fromQuery())) $sendUrl .= "?" . http_build_query($this->params()->fromQuery());
return $this->redirect()->toUrl(
$this->LocalService()->wechat->getApp()
->oauth
->scopes(['snsapi_base'])
->with(['forceSnapShot' => true])
->redirect($sendUrl)
);
}
/**
* @note webH5 代理
* @return \Laminas\Http\Response
*/
public function webH5ForwardAction(): \Laminas\Http\Response
{
$wechatH5Config = $this->LocalService()->config['wechat']['h5Proxy'];
return $this->redirect()->toUrl(
$this->LocalService()->wechat->getApp()
->oauth
->scopes(['snsapi_base'])
->with(['forceSnapShot' => true])
->redirect(
$wechatH5Config['forward_callback_url'] . "?". http_build_query($this->params()->fromQuery())
)
);
}
/**
* @note webH5 代理回调
* @return \Laminas\Http\Response
*/
public function webH5CallbackAction(): \Laminas\Http\Response
{
$auk = $this->params()->fromQuery('auk', '');
$code = $this->params()->fromQuery('code', '');
return $this->redirect()->toUrl(
$this->LocalService()->config['wechatH5RedirectUrlConfig'][$auk] . "?code=" . $code
);
}
public function webH5OauthAction() {
$code = $this->params()->fromPost('code', ''); // 微信Code值用于获取openid
if( empty($code) ) return $this->RenderApiJson()->Success([
'status' => 1,
'msg' => '非法登录!'
]);
// 获取微信公众号用户信息
$wechatH5Config = $this->LocalService()->config['wechat']['h5Proxy'];
// 开启代理
if($wechatH5Config['open_forward']) {
// 获取微信用户信息
$wechatUserInfo = $this->LocalService()->httpSv->post(
$this->LocalService()->config['wechat']['forward_user_url'],
[
'code'=>$code,
'scopes' => 'snsapi_base'
]
);
$wechatUserInfo = new User($wechatUserInfo);
}else {
$wechatUserInfo = $this->LocalService()->wechat->getApp()->oauth->scopes(['snsapi_base'])->userFromCode($code);
}
if( empty($wechatUserInfo->getId()) ) return $this->RenderApiJson()->Success([
'status' => 1,
'msg' => '公众号授权失败!'
]);
// 查询微信公众号openid对应的用户信息
$adminUser = $this->LocalService()->adminUser->fetchOne([
'where' => [
'is_del' => 0,
'openid' => $wechatUserInfo->getId()
],
'columns' => [ 'id', 'mobile', 'status', 'real_status']
]);
if( empty($adminUser) ) {
// 插入用户状态, 3600秒生存时间, 防止扫完码不取数据一直占用内存
Laminas::$serviceManager->redisExtend->getRedisInstance()->setex(RedisEnum::USER_STATUS . $code, 60 * 60 , json_encode([
'bind_status' => -1,
'nickname' => $wechatUserInfo->getNickname(),
'avatar' => $wechatUserInfo->getAvatar(),
'openid' => $wechatUserInfo->getId(),
]));
return $this->RenderApiJson()->Success([
'status' => 2,
'msg' => '账户未绑定!',
'openid' => $wechatUserInfo->getId()
]);
}
if( !empty($adminUser['status']) && !empty($adminUser['real_status']) ) return $this->RenderApiJson()->Success([
'status' => 1,
'msg' => '账户已禁用,请联系相关客服人员!'
]);
// 受试者登录
$authData = $this->LocalService()->identity->generateTokenByUserId($adminUser['id'], Identity::PLATFORM_H5_WEB);
return $this->RenderApiJson()->Success([
'token' => $authData['token'],
'status' => 0
]);
}
}

View File

@ -0,0 +1,260 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/7/31 20:39
* @Description
*
*/
namespace Application\Controller;
use Application\Common\Com;
use Application\Common\StatusCode;
use Application\Mvc\Controller\BasicController;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Helper\StringHelper;
use Exception;
use Laminas\Cache\Exception\ExceptionInterface;
use Laminas\Db\Sql\Predicate\Expression;
use Laminas\Mvc\MvcEvent;
use Laminas\View\Model\JsonModel;
class PatientH5Controller extends BasicController
{
protected ?array $patientData;
public function attachDefaultListeners()
{
parent::attachDefaultListeners(); // TODO: Change the autogenerated stub
$event = $this->getEventManager();
$event->attach(MvcEvent::EVENT_DISPATCH, [$this, 'checkPatientStatus'], 100);
}
/**
* Notes: 检测当前登录账户对应的受试者的状态
* User: llbjj
* DateTime: 2024/8/1 9:26
*
* @throws ExceptionInterface
*/
public function checkPatientStatus() {
// 检测当前用户的状态
$adminUser = $this->LocalService()->adminUser->fetchOne([
'where' => ['id' => $this->LocalService()->identity->getId(), 'is_del' => 0],
'columns' => ['patient_status', 'id', 'patient_openid']
]);
if(empty($adminUser)) throw new InvalidArgumentException('账户不存在!');
if($adminUser['patient_status']) throw new InvalidArgumentException('账户已禁用!');
// 检测用户是否关注
if(( $this->LocalService()->toolSys->getWechatUserStatus($adminUser['patient_openid'], 'patient')['userStatus'] ?? 'unsubscribe' ) === 'unsubscribe') {
throw new InvalidArgumentException('尚未关注公众号!');
}
// 获取对应的受试者信息
$patientData = $this->LocalService()->patient->fetchOne([
'where' => ['patient_tel' => $this->LocalService()->identity->getMobile(), 'is_del' => 0],
'columns' => [ 'id', 'item_id', 'itemsig_id', 'patient_name', 'patient_number' ]
]);
if(empty($patientData)) throw new InvalidArgumentException('受试者不存在!');
$this->patientData = $patientData;
}
public function editSendAction(): JsonModel
{
$date = $this->params()->fromPost('date', time());
$date = $date ?: time();
$itemMessageSendContent = $this->LocalService()->itemMessageSend->getOneFieldVal('content', ['is_del' => 0, 'item_id' => $this->patientData['item_id'] ]);
if (empty($itemMessageSendContent)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '后台推送新增表单还未设置');
$itemMessageSendPatientWhere = [
'where' => 'is_del=0 and item_id='.$this->patientData['item_id'].' and patient_id='.$this->patientData['id'].' and FROM_UNIXTIME(create_time ,"%Y-%m-%d")="'.date('Y-m-d', $date).'"',
'columns'=>['item_id','content','itemsig_id','patient_id','id', 'is_write'],
];
$itemMessageSendInfo = $this->LocalService()->itemMessageSendPatient->fetchOne($itemMessageSendPatientWhere);
if (!empty($itemMessageSendInfo) && $itemMessageSendInfo['is_write'] == 1){
return $this->RenderApiJson()->Success([
'itemMessageSendInfo' => [
'is_write' => 1
]
]);
}
$com = new Com();
$itemMessageSendInfo['itemInfoName'] = $this->LocalService()->itemInfo->getOneFieldVal('name','id='.$this->patientData['item_id'])?:'';
$itemMessageSendInfo['patient_name'] = $this->patientData['patient_name'] ?: '';
if($this->patientData['patient_number']) $itemMessageSendInfo['patient_name'] .= "{$this->patientData['patient_number']}";
if (!empty($itemMessageSendInfo['content'])){
$itemMessageSendInfo['content'] = json_decode($itemMessageSendInfo['content'],true);
}else{
$itemMessageSendInfo['content'] = [];
}
$itemMessageFieldWhere = [
'is_del' => 0,
'item_id' => $this->patientData['item_id'],
];
$itemMessageFieldData = $this->LocalService()->itemMessageField->fetchAll([
'where' => $itemMessageFieldWhere,
'order' => ['mess_order']
]);
$relation = [];
if(!empty($itemMessageFieldData)){
$relationFieldData = [];
$relationIdArr = [];
$relationId = array_filter(array_column($itemMessageFieldData,'relation_id'));
if (!empty($relationId)){
$relationIds = implode(',',$relationId);
$relationFieldData = $this->LocalService()->itemMessageField->fetchAll(['where' => [
'is_del' => 0,
'item_id' => $this->patientData['item_id'],
[
'or' => [
'id' => StringHelper::toArray($relationIds),
'parent' => StringHelper::toArray($relationIds)
]
]
],'order' => ['mess_order']]);
}
if(!empty($relationFieldData)){
$relationFieldData = $com->getTree($relationFieldData,0,0,2,'parent');
$relationIdArr = array_column($relationFieldData,'id');
}
$relationFieldDatas = $this->LocalService()->itemMessageSend->getPatientattrTemplate($relationFieldData);
if(!empty($relationFieldDatas)) {
foreach ($itemMessageFieldData as $itemMessageFieldDataK => $itemMessageFieldDataV){
if (!empty($itemMessageFieldDataV['relation_id'])){
$relationIdData = explode(',',$itemMessageFieldDataV['relation_id']);
foreach ($relationFieldDatas as $relationFieldDatasK=>$relationFieldDatasV) {
if (in_array($relationFieldDatasV['id'],$relationIdData)){
$relationFieldDatasV['prop'] = $relationFieldDatasV['id'];
$relation[$itemMessageFieldDataV['parent']][$itemMessageFieldDataV['id']][] = $relationFieldDatasV;
}
}
}
if (in_array($itemMessageFieldDataV['id'],$relationIdArr)){
unset($itemMessageFieldData[$itemMessageFieldDataK]);
}
}
}
}
!empty($itemMessageFieldData) && $itemMessageFieldData = $com->getTree($itemMessageFieldData,0,0,2,'parent');
$FormFileDatas = $this->LocalService()->itemMessageSend->getPatientattrTemplate($itemMessageFieldData);
$FormFileData =array_values($this->Introduce('MessageSend',['item_id'=>$this->patientData['item_id'],'messageSend'=>$FormFileDatas,'MINI_PATIENT'=>1]));
$data['itemMessageSendInfo'] = $itemMessageSendInfo;
$data['FormFileData'] =$FormFileData;
$data['relation'] =$relation;
return $this->RenderApiJson()->Success($data);
}
/**
* @throws Exception
*/
public function savePatientSendAction(): JsonModel
{
$newData['item_id'] = $this->patientData['item_id'] ?: 0;
$newData['patient_id'] = $this->patientData['id'] ?: 0;
$newData['itemsig_id'] = $this->patientData['itemsig_id'] ?: 0;
$newData['id'] = $this->params()->fromPost('id', 0);
$newData['content'] = $this->params()->fromPost('content', '');
$date = $this->params()->fromPost('date', 0);
$date = $date ?: time();
$com = new Com();
if (empty($newData['item_id']) || empty($newData['content']) || empty($newData['patient_id'])){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');
}
//验证链接
if((strtotime(date('Y-m-d',$date)) != strtotime(date('Y-m-d'))) || empty($date)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
}
$itemMessageSendInfo = $this->LocalService()->itemMessageSend->fetchOne(['where'=> [
'is_del' => 0,
'item_id' => $newData['item_id'],
]]);
if (empty($itemMessageSendInfo)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息已过期');
}
//没有填写数据
$itemMessageSendPatientWhere = [
'where' => [
'is_del' => 0,
'item_id' => $newData['item_id'],
'patient_id' => $this->patientData['patient_id'],
new Expression('FROM_UNIXTIME(create_time ,"%Y-%m-%d")=?', date('Y-m-d'))
],
'columns'=>['item_id','content','itemsig_id','patient_id','id'],
];
$itemMessageSendPatientInfo = $this->LocalService()->itemMessageSendPatient->fetchOne($itemMessageSendPatientWhere);
if(!empty($itemMessageSendPatientInfo['is_write'])) return $this->RenderApiJson()->Success();
$itemMessageFieldData = $this->LocalService()->itemMessageField->fetchAll(['where' => [
'is_del' => 0,
'item_id' => $newData['item_id'],
],'order' => ['mess_order']]);
$itemMsgParent = [];
$itemMsgParents = [];
if (!empty($itemMessageFieldData)){
$itemMsgParents = array_column($itemMessageFieldData,null,'id');
foreach ($itemMessageFieldData as $itemMessageFieldDataK=>$itemMessageFieldDataV){
if (empty($itemMessageFieldDataV['parent']) && $itemMessageFieldDataV['is_required'] == 1){
$itemMsgParent[] = $itemMessageFieldDataV['id'];
}
}
$itemMessageFieldData = $com->getTree($itemMessageFieldData,0,0,2,'parent');
}
$FormFileDatas = $this->LocalService()->itemMessageSend->getPatientattrTemplate($itemMessageFieldData);
$contentField = $newData;
if (!empty($newData['content'])){
$newContentData = json_decode($newData['content'],true);
foreach ($newContentData as $newContentDataK=>$newContentDataV){
$var_name = isset($itemMsgParents[$newContentDataV['id']]['var_name'])?$itemMsgParents[$newContentDataV['id']]['var_name']:'';
$names = isset($itemMsgParents[$newContentDataV['id']]['name'])?$itemMsgParents[$newContentDataV['id']]['name']:'';
if (in_array($newContentDataV['id'],$itemMsgParent) && empty($newContentDataV['value'])){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '【'.$names.'】:不能为空');
}
$contentField[$var_name] = $newContentDataV['value'];
}
//必填写都填写则为已完成
$newData['is_write'] = 1;
unset($contentField['content']);
}
$FormFileData =$this->Introduce('MessageSendPatient',['item_id'=>$newData['item_id'],'messageSend'=>$FormFileDatas]);
empty($newData['id']) && $newData['id'] = $itemMessageSendPatientInfo['id'];
$newData['write_time'] = time();
$result = $this->LocalService()->itemMessageSendPatient->save($newData);
unset($newData['write_time']);
unset($newData['update_user_id']);
$contentField['realname'] = $this->patientData['patient_name'];
$contentField['data_type_flag'] = 1;
if (!empty($result)) $this->LocalService()->log->saveFileLog($newData['id'],'MessageSendPatient',$contentField,0,'暂无说明',$newData['item_id'],'',['item_id'=>$newData['item_id'],'messageSend'=>$FormFileData]);
return $this->RenderApiJson()->Success();
}
}

View File

@ -0,0 +1,191 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/4/8 16:28
* @Description
*
*/
namespace Application\Controller;
use Application\Common\StatusCode;
use Application\Mvc\Controller\BasicController;
use Application\Mvc\Controller\ThirdToolController;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\DateHelper;
use Laminas\Cache\Exception\ExceptionInterface;
use Laminas\Stdlib\ArrayUtils;
use Laminas\View\Model\JsonModel;
class SasController extends BasicController
{
/**
* @throws ExceptionInterface
*/
public function exportAction() : JsonModel
{
$exportResult = $this->LocalService()->toolSys->exportSas($this->params()->fromPost());
$extendData = [];
if (!$exportResult['isValid']) {
// 获取错误提示信息的表格结构
$extendData = [
'FormFileData' => $this->Introduce('ExportSasErr', ['item_id' => $this->params()->fromPost('item_id')])
];
}
return $this->RenderApiJson()->Success($exportResult, '', $extendData);
}
public function editAction(): JsonModel
{
$id = $this->params()->fromPost('id', 0);
$item_id = $this->params()->fromPost('item_id', 0);
$category = $this->params()->fromPost('category', 0);
if(empty($item_id)) throw new InvalidArgumentException('请选择项目!');
$where = ['item_id' => $item_id, 'category' => $category, 'is_del' => 0, 'id' => $id];
$exportSas = $this->LocalService()->exportSas->fetchOne([
'where' => $where,
'columns' => ['item_id', 'itemsig_id', 'export_form_id', 'mode', 'path', 'category', 'status', 'type', 'create_user_id', 'create_time', 'update_user_id', 'update_time', 'date_ym', 'export_create_user_id']
]);
if(empty($exportSas)) {
$exportSas = [ 'mode' => '0', 'item_id' => $item_id, 'type' => '0', 'category' => $category, 'itemsig_id' => '', 'date_ym' => $date_ym, 'export_form_id' => 'null' ];
}else {
$exportSas['applyUserName/dateTime'] = $this->LocalService()->adminUser->getOneFieldVal('realname', ['id' => $exportSas['update_user_id'] ?: $exportSas['create_user_id']]) . '/' . date('Y-m-d H:i:s', $exportSas['update_time'] ?: $exportSas['create_time']);
$exportSas['itemsig_id'] = !empty($exportSas['itemsig_id']) ? explode(',', $exportSas['itemsig_id']) : [];
$exportSas['export_form_id'] = !empty($exportSas['export_form_id']) ? explode(',', $exportSas['export_form_id']) : [];
unset($exportSas['create_user_id']);
unset($exportSas['create_time']);
unset($exportSas['update_user_id']);
unset($exportSas['update_time']);
}
$FormFileData = $this->Introduce('ExportSas', ['item_id' => $item_id, 'category' => $category]);
return $this->RenderApiJson()->Success($exportSas, '', [
'FormFileData' => array_values($FormFileData)
]);
}
public function listAction(): JsonModel
{
$item_id = $this->params()->fromPost('item_id', 0);
$category = $this->params()->fromPost('category', 0);
if(empty($item_id)) throw new InvalidArgumentException('请选择项目!');
$limit = $this->params()->fromPost('limit', 10);
$page = $this->params()->fromPost('page', 1);
$formFileData = $this->Introduce('ExportSas', ['item_id' => $item_id, 'category' => $category]);
$listWhere = [
'category' => $category,
'item_id' => $item_id,
'is_del' => 0,
];
$exportSasList = $this->LocalService()->exportSas->fetchAll([
'where' => $listWhere,
'limit' => $limit,
'offset' => ($page - 1) * $limit,
'order' => 'update_time desc'
]);
$formFieldOptions = [];
array_walk($formFileData, function ($item, $key) use (&$formFieldOptions) {
if ( in_array ( $item['type'], [ 'Radio', 'SelectUser' ])) {
$optionsKey = $item['type'] == 'Radio' ? 'radios' : 'options';
$formFieldOptions[$key] = ArrayHelper::index($item[$optionsKey], 'value');
}
});
$adminUserNameList = $this->LocalService()->adminUser->fetchCol('realname', 'id > 0');
$result = [];
array_walk($exportSasList, function (&$item, $index) use($adminUserNameList, $formFileData, &$result, $formFieldOptions) {
if($item['update_time'] != 0) {
$oprtUserAndTime = sprintf('%s / %s', $adminUserNameList[$item['update_user_id']], DateHelper::formatTimestamp($item['update_time']));
}else {
$oprtUserAndTime = sprintf('%s / %s', $adminUserNameList[$item['create_user_id']], DateHelper::formatTimestamp($item['create_time']));
}
$result[$index] = array_fill_keys(array_keys($formFileData), '') ;
foreach($result[$index] as $k => &$v) {
$v = $item[$k] == 'null' ? '' : $item[$k];
if(isset($formFieldOptions[$k])) {
if($v !== '') {
$v = implode(',', array_column(
array_intersect_key($formFieldOptions[$k], array_flip(explode(',', $v))),
'label'
)
);
}else {
$v = '全部';
}
}
if($k == 'date_ym' && !$v) {
$v = '全量';
}
}
$result[$index] = ArrayUtils::merge($result[$index], [
'id' => $item['id'],
'path' => $item['path'],
'status' => $item['status'],
'applyUserName/dateTime' => $oprtUserAndTime
]);
});
return $this->RenderApiJson()->Success(
$result,
'',
[
'FormFileData' => array_values($formFileData),
'total' => $this->LocalService()->exportSas->getCount($listWhere)
]
);
}
/**
* Notes:删除导出受试者进度信息
* @param
* @return
* @author haojinhua
* @date 2025-08-29
*/
public function deleteAction(){
$id = $this->params()->fromPost('id',0);//信息ID
if (empty($id)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');
$exportData = $this->LocalService()->exportSas->fetchOne([
'where' => [
'id' => $id,
'is_del' => 0
],
'columns' => ['id', 'category']
]);
if (empty($exportData)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '信息不存在!');
$save_data = [
'id'=>$id,
'is_del'=>1
];
$result = $this->LocalService()->exportSas->save($save_data);
if($result){
//日志
$log_type = 2;
$log_remark = sprintf("(新版) %s - 删除申请导出信息", $this->LocalService()->exportSas->getCategoryText((int) $exportData['category']));;
$this->LocalService()->log->saveFileLog($id,'ExportSas',$save_data,$log_type,$log_remark,'',' ',[]);
}
return $this->RenderApiJson()->success();
}
}

View File

@ -0,0 +1,251 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/6/27 11:19
* @Description
*
*/
namespace Application\Controller\Temple;
use Application\Mvc\Controller\BasicController;
use Application\Service\Exceptions\InvalidArgumentException;
use Laminas\Db\Sql\Predicate\NotIn;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Mvc\Controller\AbstractActionController;
use Zend\Stdlib\ArrayUtils;
class ChecklistController extends BasicController
{
public function siglistAction() {
$type = $this->params()->fromPost('type', 0);
$sigList = $this->LocalService()->ocrSigpatient->fetchAll([
'where' => "pid = 0 and is_del = 0",
'columns' => ['id', 'name'],
'order' => ['number']
]);
$patientList = $this->LocalService()->ocrSigpatient->fetchCol('pid', "is_del = 0 and have_status < 2 and pid > 0");
$patientCountData = [];
if(!empty($patientList)) {
foreach($patientList as $pid) {
$patientCountData[$pid]++;
}
}
$checklistList = $this->LocalService()->templeChecklist->fetchAll([
'where' => 'is_del = 0',
'columns' => ['id', 'sig_id', 'patient_id', 'is_lock']
]);
$checklistPatientCountData = [];
$checklistNoLockPatientCountData = [];
if(!empty($checklistList) ) {
foreach($checklistList as &$checklist) {
$checklistPatientCountData[$checklist['sig_id']][$checklist['patient_id']] = $checklist['patient_id'];
if(!$checklist['is_lock'] && !$type ) $checklistNoLockPatientCountData[$checklist['sig_id']][$checklist['patient_id']] = $checklist['patient_id'];
}
}
$result = [];
if(!empty($sigList)) {
foreach ($sigList as &$sig) {
if(!$type) {
if( ! count( $checklistPatientCountData[$sig['id']] ?? [] ) ) continue;
$sig['patientCount'] = count( $checklistNoLockPatientCountData[$sig['id']] ?? [] ) . ' / ' . count( $checklistPatientCountData[$sig['id']] ?? [] ) . ' / ' . ( $patientCountData[$sig['id']] ?? 0 );
$result[] = &$sig;
}else if($type == 1) {
if(! ($patientCountData[$sig['id']] ?? 0)) continue;
$sig['patientCount'] = ( $patientCountData[$sig['id']] - count( $checklistPatientCountData[$sig['id']] ?? [] ) ) . ' / ' . $patientCountData[$sig['id']];
$result[] = &$sig;
}
}
}
return $this->RenderApiJson()->Success(array_values($result));
}
public function patientlistAction() {
$type = $this->params()->fromPost('type', 0);
$sig_id = $this->params()->fromPost('sig_id', 0);
$patientDatas = $this->LocalService()->ocrSigpatient->fetchAll([
'where' => [
'pid' => $sig_id,
'is_del' => 0,
new Operator('have_status', Operator::OP_LT, 2),
],
'columns' => ['id', 'name', 'pid', 'number'],
'order' => ['number']
]);
$result = [];
$annexCount = [];
if(!empty($patientDatas)) {
$templeChecklistList = $this->LocalService()->templeChecklist->fetchAll([
'where' => [
'is_del' => 0,
'sig_id' => $sig_id,
],
'columns' => ['id', 'annex_id', 'patient_id', 'is_lock']
]);
$checklistData = [];
if(!empty($templeChecklistList)) {
foreach($templeChecklistList as $key => &$templeChecklist) {
$checklistData[$templeChecklist['patient_id']]['count'] ++;
if($templeChecklist['is_lock']) $checklistData[$templeChecklist['patient_id']]['lock_count'] ++;
else $checklistData[$templeChecklist['patient_id']]['nolock_count'] ++;
}
}
if($type == 1) {
$annexList = $this->LocalService()->templeAnnex->fetchAll([
'where' => "is_del = 0",
'columns' => ['id', 'patient_id']
]);
if(!empty($annexList)) {
foreach($annexList as $annex) {
$annexCount[$annex['patient_id']]['annexCount'] ++;
}
}
}
foreach($patientDatas as &$patientData) {
$key = $patientData['number'];
for ($i = 0; $i < 8 - strlen($patientData['number']); $i++ ) {
$key = '0' . $key;
}
$patientData = ArrayUtils::merge($patientData, $checklistData[$patientData['id']] ?? []);
if( !$type ) {
if($patientData['nolock_count']) $result["0.{$key}"] = &$patientData;
else if($patientData['lock_count']) $result["1.{$key}"] = &$patientData;
}else {
$patientData = ArrayUtils::merge($patientData, $annexCount[$patientData['id']] ?? []);
if( !$patientData['count'] ) {
if(!$patientData['annexCount']) $result["3.{$key}"] = &$patientData;
else $result["2.{$key}"] = &$patientData;
}
}
}
ksort($result, SORT_NUMERIC );
}
return $this->RenderApiJson()->Success(array_values($result));
}
public function annexlistAction() {
$patient_id = $this->params()->fromPost('patient_id', 0);
if(empty($patient_id)) return $this->RenderApiJson()->Success();
$patientSex = $this->LocalService()->ocrSigpatient->getOneFieldVal('sex', ['id' => $patient_id]);
$sex_code = $patientSex == 1 ? 'boy' : 'girl';
$checklistAnnexIdArr = array_unique($this->LocalService()->templeChecklist->fetchCol('annex_id', ['patient_id' => $patient_id, 'is_del' => 0]));
$annexWhere = ['patient_id' => $patient_id];
if(!empty($checklistAnnexIdArr)) $annexWhere[] = new NotIn('id', $checklistAnnexIdArr);
$annexList = $this->LocalService()->templeAnnex->fetchAll([
'where' => $annexWhere,
'columns' => [ 'id', 'annex_path', 'annex_name' ]
]);
$keywordList = $this->LocalService()->ocrKeyword->fetchAll([
'where' => "is_del = 0 and keyword_code in ('CRP', 'hscrp')",
'columns' => [ 'category_name', 'keyword_code', 'keyword_name', 'keyword_unit', 'min' => "{$sex_code}_min", 'max' => "{$sex_code}_max"]
]);
$keywordData = [];
foreach($keywordList as &$keyword) {
$keywordData[$keyword['keyword_code']] = &$keyword;
}
return $this->RenderApiJson()->Success([
'annexlist' => $annexList,
'keywordData' => $keywordData
]);
}
public function listAction() {
$patient_id = $this->params()->fromPost('patient_id', 0);
$patientSex = $this->LocalService()->ocrSigpatient->getOneFieldVal('sex', ['id' => $patient_id]);
$sex_code = $patientSex == 1 ? 'boy' : 'girl';
$keywordList = $this->LocalService()->ocrKeyword->fetchAll([
'where' => "is_del = 0 and keyword_code in ('CRP', 'hscrp')",
'columns' => [ 'category_name', 'keyword_code', 'keyword_name', 'keyword_unit', 'min' => "{$sex_code}_min", 'max' => "{$sex_code}_max"]
]);
$keywordData = [];
foreach($keywordList as &$keyword) {
$keywordData[$keyword['keyword_code']] = &$keyword;
}
$result = $this->LocalService()->templeChecklist->fetchAll([
'where' => ['is_del' => 0, 'patient_id' => $patient_id],
'columns' => [ 'id', 'patient_id', 'sig_id', 'annex_id', 'raw_date', 'raw_code', 'raw_name', 'raw_result','raw_range','raw_unit', 'is_lock'],
'order' => ['raw_date']
]);
if(!empty($result)) {
$templeAnnexIdData = array_column($result, 'annex_id');
$annexNameData = $this->LocalService()->templeAnnex->fetchCol('annex_path', 'id in (' . implode(',', $templeAnnexIdData) . ')');
foreach($result as &$checklist) {
$checklist['annex_path'] = $annexNameData[$checklist['annex_id']] ?? '';
if($checklist['is_lock'] != 1){
$checklist['raw_unit'] = $keywordData[$checklist['raw_code']]['keyword_unit'];
$checklist['raw_range'] = implode(' - ', array_filter([
$keywordData[$checklist['raw_code']]['min'],
$keywordData[$checklist['raw_code']]['max']
], function($val) {
return strlen($val);
}));
}
}
}
return $this->RenderApiJson()->Success([
'checklist' => $result,
'keywordData' => $keywordData
]);
}
public function saveAction() {
$checklistData = $this->params()->fromPost();
$checklistData['is_lock'] = 1; // 默认提交就锁定
$this->LocalService()->templeChecklist->save($checklistData);
return $this->RenderApiJson()->Success();
}
public function lockAction() {
$id = $this->params()->fromPost('id', 0);
$is_lock = $this->params()->fromPost('is_lock', 1);
if(!$id) throw new InvalidArgumentException('无效的操作信息!');
$this->LocalService()->templeChecklist->updateField($id, 'is_lock', $is_lock);
return $this->RenderApiJson()->Success();
}
public function deleteAction() {
$id = $this->params()->fromPost('id', 0);
if(!$id) throw new InvalidArgumentException('无效的操作信息!');
$this->LocalService()->templeChecklist->upDelState("id = " . $id);
return $this->RenderApiJson()->Success();
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Application\Controller;
use Application\Mvc\Controller\ThirdToolController;
use Laminas\Cache\Exception\ExceptionInterface;
use Laminas\View\Model\JsonModel;
class ThirdController extends ThirdToolController
{
/**
* @throws ExceptionInterface
*/
public function sourceAction(): JsonModel
{
$sv = $this->params()->fromPost('sv');
$method = $this->params()->fromPost('method');
$params = $this->params()->fromPost('params');
$sourceData = $this->LocalService()->toolSys->sasSourceData($sv, $method, $params);
return $this->RenderApiJson()->Success([], '', ['data' => $sourceData]);
}
}

View File

@ -0,0 +1,222 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 13:42
* @Description登录
*
*/
namespace Application\Controller;
use Application\Common\Container;
use Application\Common\Crypt;
use Application\Common\RedisEnum;
use Application\Form\FieldForm;
use Application\Mvc\Controller\Plugins\RenderApiJson;
use Application\Service\Extension\ErrorHandler;
use Application\Service\Extension\Helper\ValidatorHelper;
use Application\Service\Extension\Identity\Identity;
use Application\Service\Extension\Laminas;
use Application\Form\LoginForm;
use Application\Common\StatusCode;
use Application\Service\Extension\Helper\StringHelper;
//use Application\Service\Extension\Model\XmlModel;
use Application\Service\Extension\Queue\jobs\SyncPatientFormJob;
use Application\Service\Extension\Queue\jobs\SyncPatientJob;
use Application\Service\Extension\Queue\QueueApplication;
//use Application\Service\Extension\Queue\QueueMessage;
//use Application\Service\Extension\Queue\job\TestQueue;
use Application\Service\Extension\Sms\SmsRateLimitException;
use Application\Service\Extension\Validator\ValidatorApplication;
use Application\Service\Extension\ValidatorV2\Validator;
use Application\Service\Extension\Xml\FormContentXmlGenerator;
use Application\Service\Extension\Xml\PatientXmlGenerator;
use Application\Service\Extension\Xml\XmlBuilder;
//use Application\Service\Extension\XmlGenerate;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Messages\Text;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Laminas\Db\Sql\Where;
use Laminas\Http\Client;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\Exception\InvalidArgumentException;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
use Overtrue\Socialite\User;
use Swoole\Coroutine\Http\Server;
use function Swoole\Coroutine\run;
/**
* Class LoginController
* @package Application\Controller
* @method Container LocalService()
* @method RenderApiJson RenderApiJson()
*/
class WechatController extends AbstractActionController
{
/**
* 微信回调入口
* @url xxx.com/wechat/entry
* @throws InvalidConfigException
* @throws \EasyWeChat\Kernel\Exceptions\BadRequestException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \ReflectionException
*/
public function entryAction()
{
if (isset($_GET["echostr"])) {
$echoStr = $_GET["echostr"];//从微信用户端获取一个随机字符赋予变量echostr
//valid signature , option访问地61行的checkSignature签名验证方法如果签名一致输出变量 echostr完整验证配置接口的操作
if($this->checkSignature()){
echo $echoStr;
exit;
}
} else {
$app = Laminas::$serviceManager->wechat->getApp();
$app->server->push(function($message) {
return $this->LocalService()->wechat->getMessage()->handle($message);
});
$response = $app->server->serve();
$response->send();
die;
}
}
/**
* 微信验签
* @return bool
*/
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = '66668888';
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
/**
* 受试者绑定界面
* @url xxx.com/wechat/bind
* @return \Laminas\Http\Response|ViewModel
*/
public function bindAction()
{
if (!$_GET['code']) {
$redirectUrl = $this->LocalService()->wechat->getApp()
->oauth
->scopes(['snsapi_base'])->with(['forceSnapShot' => true])
->redirect("{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}/wechat/bind");
return $this->redirect()->toUrl($redirectUrl);
}
$view = new ViewModel();
$view->setTemplate('application/wechat/bind');
$this->layout('layout/wechat');
$view->setVariables([
'code' => $_GET['code'],
'host' => "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}"
]);
return $view;
}
/**
* 获取绑定微信短信验证码
* @url xxx.com/wechat/bind-captcha
* @return JsonModel
* @throws GuzzleException
*/
public function bindCaptchaAction(): JsonModel
{
$mobile = $this->params()->fromPost('mobile');
$code = $this->params()->fromPost('code');
$api = [
// 'http://lzy.kingdone.com/common/patient-mobile',
'https://www.5-mc.cn/common/patient-mobile',
'https://www.scitrials.cn/common/patient-mobile',
];
$hasMobile = false;
$arr = [];
foreach ($api as $item) {
$sign = md5($mobile . CommonController::SECRET_KEY);
$client = new \GuzzleHttp\Client();
$content = $client->get("{$item}?sign={$sign}&mobile={$mobile}")->getBody()->getContents();
if ($content === '1') {
$hasMobile = true;
$arr[$code][] = $item;
} elseif ($content === '-1') { // 已经绑定
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "当前手机号码无法绑定。请先解绑关联关系。");
}
}
if (!$hasMobile) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "当前手机号码无法绑定。请确定手机号是否正确。");
}
$captcha = mt_rand(1000, 9999);
Laminas::$serviceManager->redisExtend->getRedisInstance()->setex("bind:{$mobile}:{$captcha}:{$code}", 3600, json_encode($arr));
$this->LocalService()->sms->send($mobile, $captcha);
return $this->RenderApiJson()->Success();
}
/**
* 绑定
* @return JsonModel
* @throws GuzzleException
* @throws InvalidConfigException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
*/
public function bindSubmitAction(): JsonModel
{
$mobile = $this->params()->fromPost('mobile');
$captcha = $this->params()->fromPost('captcha');
$code = $this->params()->fromPost('code', '');
$captchaKey = "bind:{$mobile}:{$captcha}:{$code}";
$captchaCache = Laminas::$serviceManager->redisExtend->getRedisInstance()->get("bind:{$mobile}:{$captcha}:{$code}");
$openid = Laminas::$serviceManager->wechat->getApp()->oauth->userFromCode($code)->getId();
$user = $this->LocalService()->wechat->getApp()->user->get($openid);
if ($user && isset($user['errmsg'])) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "绑定失败。请重进页面重新进行绑定。");
}
if ($user['subscribe'] != 1) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "请关注公众号。");
}
if (!$captchaCache) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "验证码有误。");
}
foreach (StringHelper::jsonDecode($captchaCache) as $code => $urlArr) {
foreach ($urlArr as $item) {
$sign = md5($mobile . CommonController::SECRET_KEY);
$client = new \GuzzleHttp\Client();
$client->get("{$item}?sign={$sign}&mobile={$mobile}&openid={$openid}")->getBody()->getContents();
}
}
$this->LocalService()->wechat->getApp()->customer_service->message(new Text("您在" . date('Y-m-d H:i:s') . '绑定成功。'))->to($openid)->send();
Laminas::$serviceManager->redisExtend->getRedisInstance()->del($captchaKey);
return $this->RenderApiJson()->Success();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,258 @@
<?php
namespace Application\Controller\item;
use Application\Common\StatusCode;
use Application\Form\item\patient\PatientFormModel;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\QuestionFormatter;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Exception;
use Laminas\View\Model\JsonModel;
class QuestionController extends BasicController
{
/**
* @actionUrl /question/view
* @return JsonModel
* @throws Exception
*/
public function questionViewAction(): JsonModel
{
$this->validator->attach(
[['patient_id', 'form_id', 'checktime_id'], 'required']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
// 一对多 表单 图片质疑,常规识别 的图片 独立入口不在表单中所以id = 0
if (SDMHelper::app()->form->getGroupId($this->validator->attributes['form_id']) == FormGroup::NORMAL_OCR && SDMHelper::app()->form->getType($this->validator->attributes['form_id']) == Form::FORM_TYPE_MULTI) {
$formId = 0;
}else {
$formId = Laminas::$serviceManager->patientFormContent->fetchOne(['where' => ['form_id' => $this->validator->attributes['form_id'], 'patient_id' => $this->validator->attributes['patient_id'], 'checktime_id' => $this->validator->attributes['checktime_id'], 'is_del' => 0]])['id'] ?? 0;
}
// if (SDMHelper::app()->form->getGroupId($this->validator->attributes['form_id']) == FormGroup::NORMAL_OCR && SDMHelper::app()->form->getType($this->validator->attributes['form_id']) == Form::FORM_TYPE_MULTI) {
return $this->RenderApiJson()->Success([
'id' => $formId,
SDMHelper::app()->form->getShareFormField($this->validator->attributes['form_id'])['id'] => SDMHelper::app()->form->getShareFormImages($this->validator->attributes['form_id'], $this->validator->attributes['patient_id'], $this->validator->attributes['checktime_id'])
// 'shareFormImages' => SDMHelper::app()->form->getShareFormImages($this->validator->attributes['form_id'], $this->validator->attributes['patient_id'], $this->validator->attributes['checktime_id'])
]);
// return $this->RenderApiJson()->Success([
// 'id' => 0,
//// SDMHelper::app()->form->getShareFormField($this->validator->attributes['form_id'])['id'] => SDMHelper::app()->form->getShareFormImages($this->validator->attributes['form_id'], $this->validator->attributes['patient_id'], $this->validator->attributes['checktime_id'])
// 'shareFormImages' => SDMHelper::app()->form->getShareFormImages($this->validator->attributes['form_id'], $this->validator->attributes['patient_id'], $this->validator->attributes['checktime_id'])
// ]);
// }
throw new InvalidArgumentException('表单类型有误。');
}
/**
* 回复表单质疑
* @url http://xxx.com/v1/item/question/replyQuestion
* @return JsonModel
* @throws Exception
*/
public function replyQuestionAction(): JsonModel
{
// 改版了 `content` 现在没用了
$this->validator->attach(
[['question_id', 'content'], 'required']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
Db::beginTransaction();
$questionData = $this->LocalService()->itemQuestion->fetchOne([
'where' => ['id' => $this->validator->attributes['question_id']]
]);
// 新增回复历史
$this->LocalService()->itemReply->insert([
'question_id' => $this->validator->attributes['question_id'],
'reply_status' => 0,
'remarks' => json_encode([
// 表单数据
'formData' => call_user_func(function () use ($questionData) {
// 获取表单原始数据
if($questionData['content_id']) {
$model = new PatientFormModel();
$originData = $this->handleFormData($model->viewById($questionData['content_id']));
}else {
// 常规识别且一对多表单,只提取共享图片
$originData = [
SDMHelper::app()->form->getShareFormField($questionData['form_id'])['id'] => SDMHelper::app()->form->getShareFormImages($questionData['form_id'], $questionData['patient_id'], $questionData['checktime_id'])
];
}
$postData = DataHelper::handleFormData($this->params()->fromPost(), $questionData['form_id']);
foreach ($postData as $postKey => &$postDatum) {
if ($postDatum === '[]') {
$postDatum = [];
}
if (is_numeric($postKey)) {
$originData[$postKey] = $postDatum;
}
}
return $originData;
}),
// 表单结构
'form' => call_user_func(function () use ($questionData) {
return $this->getQuestionTypeId(
$questionData['content_id'],
$questionData['form_id'],
$questionData['question_type_id']
);
}),
'remarks' => $this->validator->attributes['reply']
]),
'annex_aligned' => '',
'completed_id' => $this->LocalService()->identity->getId(),
'completed_time' => time(),
'completed_type' => 1,
'is_del' => 0,
]);
// 修改疑问状态
// 提出疑问的content要变成上一次回复的数据
$this->LocalService()->itemQuestion->update([
// 'content' => json_encode($this->formData), // $this->validator->attributes['content'],
'question_status' => 1
], [
'id' => $this->validator->attributes['question_id']
]);
Db::commit();
//异步处理访视进度情况信息
$form_content_arr = !empty($questionData['content_id']) ? [$questionData['content_id']] : [];
Laminas::$serviceManager->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => $questionData['item_id'],
'itemsig_id' => $questionData['item_sign_id'],
'patient_id' => $questionData['patient_id'],
'checktime_id' => $questionData['checktime_id'],
'form_id' => $questionData['form_id'],
'operate_type'=>11,
'content_id'=>!empty($form_content_arr) ? $form_content_arr : [],
'user_id' => Laminas::$serviceManager->identity->getId()
]
]);
unset($form_content_arr);
return $this->RenderApiJson()->Success();
}
private function handleFormData(array $formData): array
{
foreach ($formData as $k => $item) {
if (stripos($k, '-') !== false) {
$key = (explode('-', $k)[0]);
$formData[$key] = $item;
unset($formData[$k]);
}
}
return $formData;
}
/**
* @param int $contentId
* @param int $formId
* @param string $questionTypeId
* @param string $originFormData
* @return array
*/
private function getQuestionTypeId(int $contentId, int $formId, string $questionTypeId): array
{
if (!$questionTypeId || !$formId) {
return [];
}
$form = SDMHelper::app()->setAttributes([
'formId' => $formId,
])->form;
$isValidContentId = ! ( $form->getType() == Form::FORM_TYPE_MULTI && $form->getGroupId() == FormGroup::NORMAL_OCR );
if($isValidContentId && !$contentId) {
return [];
}
$data = explode(',', $questionTypeId);
foreach ($data as $datum) {
$formData = $this->LocalService()->itemFormVersion->getField(['form_id' => $formId], true);
if (isset($formData[$datum])) {
$res[] = $this->LocalService()->itemForm->buildConfig($formData[$datum]);
}
}
return $res ?? [];
}
/**
* @url http://xxx.com/v1/item/question/historyReply
* @return JsonModel
* @throws Exception
*/
public function historyReplyAction(): JsonModel
{
$this->validator->attach(
[['question_id', 'reply_id'], 'required']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$query = $this->LocalService()->itemReply->fetchOne([
'where' => ['id' => $this->validator->attributes['reply_id']]
]) ?? [];
Formatter::format($query, new QuestionFormatter());
if (is_array($query['remarks']['formData'])) {
foreach ($query['remarks']['formData'] as &$remark) {
// ErrorHandler::log2txt($remark);
if (is_numeric($remark)) {
continue;
}
$d = StringHelper::jsonDecode($remark, false);
if ($d !== false) {
$remark = $d;
}
}
}
if (isset($query['remarks']['remarks'])) {
array_unshift($query['remarks']['form'], [
'label' => '回复内容',
'prop' => 'reply',
'type' => 'Text',
'disabled' => true
]);
$query['remarks']['formData']['reply'] = $query['remarks']['remarks'];
}
return $this->RenderApiJson()->Success($query);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,406 @@
<?php
namespace Application\Controller\project;
use Application\Common\Ocr;
use Application\Common\StatusCode;
use Application\Form\item\patient\PatientFormModel;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Laminas;
use Laminas\Db\Sql\Predicate\IsNotNull;
use Laminas\Db\Sql\Predicate\Like;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;
class SaeController extends BasicController
{
/**
* @return JsonModel|ViewModel
*/
public function indexAction(): JsonModel
{
$MINI = $this->LocalService()->identity->getPlatform();
$user_id = $this->LocalService()->identity->getId();
$flag = 0;
if (stripos($MINI, 'MINI') !== false) {
$flag = 1;
}
$itemId = $this->params()->fromPost('item_id', 0);
// 0为小项目, 1为大项目
$type = $this->params()->fromPost('type', 0);
$search =$_POST['search']?:'';
$condition = ['id' => $itemId];
$query = $this->LocalService()->itemInfo->fetchOne(['columns' => ['id', 'name', 'fid'], 'where' => $condition]);
if (!isset($query['fid'])) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'参数不太对呀');
}
if (!empty($flag)) {
$user_id = $this->LocalService()->signatoryUser->findsignatoryUser($user_id);
$res = $this->LocalService()->itemSignatory->userRoleSignInfo($itemId, $user_id, $search,0,1) ?: [];
foreach ($res as &$item) {
$item['name'] = $item['info_name'];
$item['signatory_id'] = $item['id'];
unset($item['info_name']);
}
} else {
$allSignatoryId = $this->LocalService()->itemSignatory->fetchAll([
'order' => ['order ASC'],
'columns' => ['id', 'signatory_id', 'number'],
'where' => ['item_id' => $query['fid']]]
);
$res = [];
foreach ($allSignatoryId as $item) {
if (
$childData = $this->LocalService()->signatoryInfo->fetchOne([
'columns' => ['info_name AS name'],
'where' => ['id' => $item['signatory_id']]
])
) {
$childData['id'] = $itemId;
$childData['signatory_id'] = $item['id'];
$childData['name'] = "{$item['number']}{$childData['name']}";
$res[] = $childData;
}
}
}
return $this->RenderApiJson()->Success($res);
}
/**
* @url xxx.com/v1/item/sae/patient
* @return JsonModel
*/
public function patientAction(): JsonModel
{
$itemsig_id = $this->params()->fromPost('itemsig_id');
if($itemsig_id == 'undefined'){
$itemsig_id = 0;
}
$item_id = $this->params()->fromPost('item_id');
if($item_id == 'undefined'){
$item_id = 0;
}
$search_keyword = $this->params()->fromPost('search_keyword'); //受试者关键字 可以是编号 或者名称 或者缩写
if(empty($itemsig_id) || empty($item_id)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '项目或中心参数有误!');
}
$patient_where = [
'is_del' => 0,
'itemsig_id' => $itemsig_id,
'item_id' => $item_id,
];
if(!empty($search_keyword)){
$patient_where[] = [
'or' => [
new Like('patient_number', "%{$search_keyword}%"),
new Like('patient_name', "%{$search_keyword}%"),
new Like('patient_name_easy', "%{$search_keyword}%"),
]
];
}
$query = $this->LocalService()->patient->fetchAll([
'where' =>$patient_where,
'columns' => ['patient_name', 'id', 'patient_number'],
'order' => ['patient_order','id']
]);
//总sea数据量
$total = 0;
$no_sae_arr = [];
if(!empty($query)){
$form_id = $this->LocalService()->itemForm->getOneFieldVal('id',[
'item_id' => $item_id,
'group_id' => FormGroup::SAE,
'is_del' => 0,
]);
if(empty($form_id)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '请先设置该项目的SAE表单信息');
}
$all_total = $this->LocalService()->patientFormContent->getsaeNum([
'item_id' => $item_id,
'itemsig_id' => $itemsig_id,
'form_id' => $form_id,
'is_del' => 0,
]);
$all_total = !empty($all_total) ? $all_total : [];
$total = !empty($all_total[$item_id][$itemsig_id][$form_id]['allnum']) ? $all_total[$item_id][$itemsig_id][$form_id]['allnum'] : 0;
foreach ($query as $queryKey=>&$item) {
$patient_saenum = !empty($all_total[$item_id][$itemsig_id][$form_id][$item['id']]['patientnum']) ? $all_total[$item_id][$itemsig_id][$form_id][$item['id']]['patientnum']: 0;
if($item['patient_number'] != ''){
$item['patient_name'] = "".$item['patient_number']."".$item['patient_name'];
}
$item = [
'id' => $item['id'],
'patient_name' => $item['patient_name']."(".$patient_saenum.")",
];
$item['patient_saenum'] = $patient_saenum;
if(empty($patient_saenum)){
$no_sae_arr[] = $item;
unset($query[$queryKey]);
}
unset($item['patient_number']);
}
}
$query = array_values($query);
if(!empty($no_sae_arr)){
$query = !empty($query) ? array_merge($query,$no_sae_arr) : $no_sae_arr;
}
unset($no_sae_arr);
//搜索表结构
$serchFormFileData[] = [
"type" => "Input",
"label" => "关键字",
"placeholder" => "请输入关键字",
"prop" => "search_keyword",
];
return $this->RenderApiJson()->Success($query,'',['total'=>$total,'SerchFormFileData'=>$serchFormFileData]);
}
/**
* Notes: 获取SAE数量
* @param
* @return
* @author haojinhua
* @date 2024-09-06
*/
public function saecountAction(){
$itemsig_id = $this->params()->fromPost('itemsig_id');
$item_id = $this->params()->fromPost('item_id');
if(empty($itemsig_id || empty($item_id))){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '项目或中心参数有误!');
}
//总sea数据量
$total = 0;
$form_id = $this->LocalService()->itemForm->getOneFieldVal('id',[
'item_id' => $item_id,
'group_id' => FormGroup::SAE,
'is_del' => 0,
]);
if(!empty($form_id)){
$all_total = $this->LocalService()->patientFormContent->getsaeNum([
'item_id' => $item_id,
'itemsig_id' => $itemsig_id,
'form_id' => $form_id,
'is_del' => 0,
]);
$all_total = !empty($all_total) ? $all_total : [];
$total = !empty($all_total[$item_id][$itemsig_id][$form_id]['allnum']) ? $all_total[$item_id][$itemsig_id][$form_id]['allnum'] : 0;
}
//获取cm的数据量
$cm_total = call_user_func(fn() => $this->LocalService()->patientFormContentCm->getCount(['status' => 0, 'is_del' => 0, 'sign_id' => $itemsig_id, 'item_id' => $item_id]));
//获取待判断AE的数据量
$ae_total = $this->LocalService()->itemCsae->getCount([
'is_del' => 0,
'item_id' => $item_id,
'itemsig_id' => $itemsig_id,
'is_ae_sure' => 0,
'is_normal_type' => 2,
]);
return $this->RenderApiJson()->Success(['sae_total'=>$total,'cm_total'=>$cm_total,'ae_total'=>$ae_total]);
}
/**
* @url http://xx.com/v1/item/sae/form
* @return JsonModel
* @throws \Exception
*/
public function formAction(): JsonModel
{
$itemId = $this->params()->fromPost('item_id', 0);
$saeForm = $this->LocalService()->itemForm->fetchOne([
'columns' => ['id', 'type', 'show_type'],
'where' => ['item_id' => $itemId, 'group_id' => FormGroup::SAE, 'is_del' => 0]
]);
if (!$saeForm) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "未发现SAE表单呢 /(ㄒoㄒ)/~~");
}
return $this->RenderApiJson()->Success(ArrayHelper::merge($this->LocalService()->itemForm->getPreviewConfig($saeForm['id']), [
'type' => $saeForm['type'],
'show_type' => $saeForm['show_type'] ?: 'right',
'form_id' => $saeForm['id']
]));
}
public function generateFormData(array $postData)
{
foreach ($postData as $key => $datum) {
if (stripos($datum, ',') !== false && stripos($datum, '[{') === false) {
$postData[$key] = explode(',', $datum);
}
}
return json_encode($postData);
}
public function oldcreateAction()
{
$request = $this->params();
$postData = $this->generateFormData($this->params()->fromPost());
if ($request->fromPost('id')) {
Laminas::$serviceManager->patientFormContent->save([
'id' => $request->fromPost('id'),
'patient_id' => $this->validator->attributes['patient_id'],
'form_id' => $this->validator->attributes['form_id'],
'data' => $postData,
'item_id' => $this->validator->attributes['item_id'],
'itemsig_id' => $this->validator->attributes['itemsig_id'],
]);
} else {
Laminas::$serviceManager->patientFormContent->save([
'patient_id' => $this->validator->attributes['patient_id'],
'form_id' => $this->validator->attributes['form_id'],
'data' => $postData,
'item_id' => $this->validator->attributes['item_id'],
'checktime_id' => 0,
'itemsig_id' => $this->validator->attributes['itemsig_id'],
]);
}
return $this->RenderApiJson()->Success();
}
/**
* Notes: SAE保存
* User: lltyy
* DateTime: 2025/3/25 10:06
*
* @return JsonModel
* @throws \Exception
*/
public function createAction(): JsonModel
{
$this->validator->attributes['checktime_id'] = 0;
$this->validator->attach(
[['patient_id', 'form_id', 'item_id', 'itemsig_id'], 'required'],
[['patient_id', 'form_id', 'item_id', 'itemsig_id'], 'integer'],
[[Form::ATTACH_SDTX], 'default', 'value' => '[]']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
}
$model = new PatientFormModel($this->validator);
$postData = DataHelper::handleFormData($this->validator->attributes, $this->params()->fromPost('form_id'));
if (SDMHelper::app()->setAttributes(['form_id' => $this->params()->fromPost('form_id')])->form->getIsUsingScore() == 1) {
throw new InvalidArgumentException('评分类表单不允许操作。');
}
$reason = $this->validator->attributes['reason'];
if(!empty($reason)){
$reason_res = [];
$reason_datas = json_decode($reason,true);
foreach ($reason_datas as $reason_data){
$reason_res[] = [
'filed_id'=>$reason_data['filed_id'],
'modify_reason'=>$reason_data['modify_reason'],
];
}
unset($reason_datas);
$reason = json_encode($reason_res,true);
}
unset($this->validator->attributes['reason']);
$postData['note'] = $reason;
if ($this->validator->attributes['id']) {
$model->editForm($postData);
} else {
$insertId = $model->createForm($postData);
return $this->RenderApiJson()->Success([
'id' => $insertId
]);
}
return $this->RenderApiJson()->Success();
}
public function viewAction(): JsonModel
{
if($this->request->isPost()){
$patient_id = $this->params()->fromPost('patient_id');
$form_id = $this->params()->fromPost('form_id',0);
//获取表单类型
$addFalseMes = '';
$formGroup = 0;
if(!empty($form_id)){
$formGroup = Laminas::$serviceManager->itemForm->getOneFieldVal('group_id',[
'id' => $this->validator->attributes['form_id'],
]);
}
//判断SAE表单操作时该患者是否已经开始访视【即判断是否存在有基点日期的访视期数据】
if(!empty($patient_id) && $formGroup == FormGroup::SAE){
$patientChecktimeCount = $this->LocalService()->itemPatientchecktime->getCount([
'is_del' => 0,
'patient_id' => $this->validator->attributes['patient_id'],
new Operator('anchor_date', Operator::OP_GT, 0),
NEW IsNotNull('anchor_date')
]);
if(empty($patientChecktimeCount)){
$addFalseMes = '该患者的访视还未开始不可增加SAE数据';
}
unset($patientChecktimeCount);
}
unset($formGroup);
$this->validator->setAttributes([
'patient_id' => $patient_id,
'form_id' => $form_id,
]);
$model = new PatientFormModel($this->validator);
$form_count = $this->LocalService()->itemForm->getCount([
'is_del' => 0,
'id' => $form_id
]);
if(empty($form_count)){
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, "无此表单信息!");
}
return $this->RenderApiJson()->Success($model->setDataHaveDel(true)->view(), 'OK', [
'total' => $model->getFormMultiTotalCount(),
'addFalseMes'=>$addFalseMes
]);
}else{
return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'非法请求');
}
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Application\Controller\project\ae;
use Application\Common\StatusCode;
use Application\Form\project\AeForm;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\FormFormatter;
use Application\Service\Extension\Helper\ArrayHelper;
use Laminas\View\Model\JsonModel;
class AeController extends BasicController
{
/**
* 渲染表格内容
* @return JsonModel
* @throws \Exception
*/
public function indexAction(): JsonModel
{
$this->validator->attach(
[['item_id', 'ae_type'], 'required']
);
if (!$this->validator->isValid()) {
return $this->RenderApiJson()->Error(
StatusCode::E_FIELD_VALIDATOR,
$this->validator->getFirstErrorToString()
);
}
$model = new AeForm($this->validator);
$data = [];
// 属于新增AE表单, 属于已有AE
if (in_array($this->validator->attributes['ae_type'], [5, 6])) {
$data = $model->renderNewAeTable();
}
return $this->RenderApiJson()->Success($data);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Application\Controller\v2;
use Application\Models\logic\patientForm\PatientFormLogic;
use Application\Mvc\Controller\BasicController;
use Application\Service\Extension\Logger\BasicLogger;
use Laminas\View\Model\JsonModel;
class PatientFormController extends BasicController
{
/**
* 受试者表单激活/失活
* @return JsonModel
*/
public function inactiveAction(): JsonModel
{
$logicModel = new PatientFormLogic();
$logicModel->setLogger(new BasicLogger());
$logicModel->executeWithTransaction('inactive');
return $this->RenderApiJson()->Success();
}
}

View File

@ -0,0 +1,24 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/7 21:30
* @Description
*
*/
namespace Application\Factory;
use Psr\Container\ContainerInterface;
class ChainFactory implements \Laminas\ServiceManager\Factory\FactoryInterface
{
/**
* @inheritDoc
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
$defaultDbAdapter = $container->get('dbAdapter');
return new $requestedName($defaultDbAdapter, $container, $options);
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 20:02
* @Description
*
*/
namespace Application\Factory;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class DbFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// TODO: Implement __invoke() method.
$defaultDbAdapter = $container->get('dbAdapter');
return new $requestedName($defaultDbAdapter, $container);
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 20:17
* @Description
*
*/
namespace Application\Factory;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class EdcDbFactory implements FactoryInterface
{
/**
* @inheritDoc
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// TODO: Implement __invoke() method.
$defaultDbAdapter = $container->get('edcDbAdapter');
return new $requestedName($defaultDbAdapter, $container);
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/5/28 23:06
* @Description
*
*/
namespace Application\Factory;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerInterface;
class ListenerFactory implements FactoryInterface
{
/**
* @inheritDoc
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
// TODO: Implement __invoke() method.
return new $requestedName($container);
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/7 21:30
* @Description
*
*/
namespace Application\Factory;
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
class LogDbFactory implements \Laminas\ServiceManager\Factory\FactoryInterface
{
/**
* @inheritDoc
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
// TODO: Implement __invoke() method.
$defaultDbAdapter = $container->get('logDbAdapter');
return new $requestedName($defaultDbAdapter, $container);
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 20:02
* @Description
*
*/
namespace Application\Factory;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class QueryFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// TODO: Implement __invoke() method.
$defaultDbAdapter = $container->get('queryDbAdapter');
return new $requestedName($defaultDbAdapter, $container);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Application\Factory;
use Application\Service\Redis\RedisExtend;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class RedisExtendFactory implements FactoryInterface
{
private static ?RedisExtend $instance = null;
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$redisConfig = $container->get('config')['caches']['Redis']['adapter']['options'];
if (self::$instance !== null) {
return self::$instance->setDatabase($redisConfig['database']);
}
// TODO: Implement __invoke() method.
self::$instance = new $requestedName($redisConfig);
return self::$instance;
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 21:28
* @Description
*
*/
namespace Application\Factory;
use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException;
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
class ServiceFactory implements \Laminas\ServiceManager\Factory\FactoryInterface
{
/**
* @inheritDoc
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// TODO: Implement __invoke() method.
return (null === $options) ? new $requestedName($container) : new $requestedName($container, $options);
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 20:17
* @Description
*
*/
namespace Application\Factory;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
class ShareDbFactory implements FactoryInterface
{
/**
* @inheritDoc
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// TODO: Implement __invoke() method.
$defaultDbAdapter = $container->get('shareDbAdapter');
return new $requestedName($defaultDbAdapter, $container);
}
}

View File

@ -0,0 +1,188 @@
<?php
namespace Application\Form;
use Application\Common\EventEnum;
use Application\Form\item\patient\PatientFormModel;
use Application\Form\project\AeForm;
use Application\Service\DB\Db;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\LogHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Laminas\Json\Json;
use Laminas\Stdlib\ArrayUtils;
/**
* @property-read int $cmContentId
* @property-read string $note
*/
class CmAEModel extends PatientFormModel
{
/**
* 受试者新增AE
* @return void
* @throws \Exception
*/
public function createNewPatientAE()
{
$aeFormId = SDMHelper::app()->form->getAeForm($this->validator->attributes['item_id'])['id'];
$this->setPostValues(ArrayUtils::merge(Json::decode($this->validator->attributes['ae'], Json::TYPE_ARRAY), [
'form_id' => $aeFormId,
'cm_content_id' => $this->validator->attributes['id'] // 用药ID
]));
Db::beginTransaction();
// 清理表单的attach
LogHelper::$attach = [];
$this->event = EventEnum::EVENT_CM_AE_FORM_CONTENT_CREATE;
$this->initLoggerData();
$AeModel = new \Application\Form\project\AeForm();
$branchHashString = StringHelper::generateHashValue();
$contentId = Laminas::$serviceManager->itemPatientAeContent->save([
'patient_id' => $this->patientId,
'item_id' => $this->itemId,
'itemsig_id' => $this->itemsigId,
'data' => json_encode($this->postData),
'is_del' => 0,
'csae_id' => 0,
'new_ae_list' => 0,
'ae_type' => 6, // 受试者新增AE
'branch' => $branchHashString,
'form_id' => $aeFormId,
'is_skip' => 0,
'is_complete' => $AeModel->getIsComplete($this->validator->attributes,$aeFormId)
]);
Laminas::$serviceManager->itemCsaeRelation->insert([
'csae_id' => 0,
'new_ae_list_id' => 0,
'content_id' => $contentId,
'patient_id' => $this->patientId,
'branch' => $branchHashString,
'cm_content_id' => $this->cmContentId
]);
$this->h()->log->setTraceAttach('在CM判断中新增了受试者AE表单数据。');
$this->logger->setContentId($contentId)->flush([
'item_id' => $this->itemId,
'patient_id' => $this->patientId,
'form_id' => $aeFormId,
'checktime_id' => $this->checktimeId ?: 0,
]);
Db::commit();
//异步处理访视进度情况信息
Laminas::$serviceManager->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => $this->itemId,
'itemsig_id' => $this->itemsigId,
'patient_id' => $this->patientId,
'checktime_id' => -1,
'form_id' => $aeFormId,
'operate_type'=>10,
'content_id'=>!empty($contentId) ? [$contentId] : [],
'user_id' => Laminas::$serviceManager->identity->getId()
]
]);
}
public function createAlreadyHaveAE()
{
Db::beginTransaction();
// 清理表单的attach
LogHelper::$attach = [];
$relationData = Laminas::$serviceManager->itemCsaeRelation->fetchOne([
'where' => ['content_id' => $this->validator->attributes['checked_content_id']]
]);
Laminas::$serviceManager->itemCsaeChecked->update([
'is_del' => 1,
], ['cm_content_id' => $this->cmContentId, 'content_id' => StringHelper::jsonDecode($this->validator->attributes['ae'])['id']]);
Laminas::$serviceManager->itemCsaeChecked->insert([
'csae_id' => 0,
'new_id' => 0,
'content_id' => StringHelper::jsonDecode($this->validator->attributes['ae'])['id'],
'branch' => $relationData['branch'],
'cm_content_id' => $this->cmContentId
]);
Db::commit();
}
public function updateNote()
{
Laminas::$serviceManager->patientFormContentCm->update(['note' => $this->note], ['content_id' => $this->cmContentId]);
}
public function getNewAEList()
{
$model = new AeForm($this->validator);
$data = [];
return $model->renderNewAeTable();
}
public function getAlreadyHaveAE()
{
$model = new AeForm($this->validator);
$data = [];
return $model->renderNewAeTable();
}
public function editAEForm()
{
$aeFormId = SDMHelper::app()->form->getAeForm($this->validator->attributes['item_id'])['id'];
$this->setPostValues(ArrayUtils::merge($this->validator->attributes, [
'form_id' => $aeFormId
]));
$this->event = EventEnum::EVENT_CM_AE_FORM_CONTENT_EDIT;
$this->initLoggerData();
Laminas::$serviceManager->itemPatientAeContent->update([
'data' => json_encode(DataHelper::handleFormData($this->validator->attributes, $aeFormId)),
], ['id' => $this->id]);
$this->logger->setContentId($this->id)->flush([
'item_id' => $this->itemId,
'patient_id' => $this->patientId,
'form_id' => $aeFormId,
'checktime_id' => $this->checktimeId ?: 0,
]);
//异步处理访视进度情况信息
Laminas::$serviceManager->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => $this->itemId,
'itemsig_id' => $this->itemsigId,
'patient_id' => $this->patientId,
'checktime_id' => -1,
'form_id' => $aeFormId,
'operate_type'=>11,
'content_id'=>!empty($this->id) ? [$this->id] : [],
'user_id' => Laminas::$serviceManager->identity->getId()
]
]);
}
}

View File

@ -0,0 +1,178 @@
<?php
namespace Application\Form;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Laminas;
use Laminas\Db\Sql\Predicate\Expression;
use Laminas\Http\Request;
use Laminas\Json\Json;
use Laminas\Stdlib\ArrayUtils;
use phpDocumentor\Reflection\Types\Mixed;
class CommonModel
{
/**
* 检查日期
* @var string
*/
private string $collectDate = '';
private string $note = '';
public function render(string $component,$dateType=1): array
{
if ($component === 'TableButton') {
$dateType = !empty($dateType) ? $dateType : 1;
$return_data = [
'data' => $this->renderTableButton(),
'collect_date' => $this->collectDate != '' ? $this->collectDate : '',
'note' => $this->note,
'table' => [
['type' => 'Text', 'label' => '检查项', 'prop' => 'check_item'],
['type' => 'Input', 'label' => '结果', 'prop' => 'result'],
['type' => 'Input', 'label' => '单位', 'prop' => 'unit'],
['type' => 'Input', 'label' => '最小值', 'prop' => 'min_val'],
['type' => 'Input', 'label' => '最大值', 'prop' => 'max_val']
],
'until' => [
'textarea' => call_user_func(function () {
$formData = Laminas::$serviceManager->itemForm->fetchOne(['where' => ['id' => $_POST['id']]]);
return (bool)Laminas::$serviceManager->dictionaryCheckcategory->fetchOne([
'where' => ['id' => $formData['checklist_id']]
])['report_type'] ?? 0;
})
]
];
unset($dateType);
return $return_data;
}
return [];
}
private function renderTableButton(): array
{
$request = Laminas::$app->getMvcEvent()->getRequest();
$formId = $request->getPost('id');
$itemId = $request->getPost('item_id');
$itemSigId = $request->getPost('itemsig_id');
$formData = Laminas::$serviceManager->itemForm->fetchOne(['where' => ['id' => $formId]]);
if (!$formId || !$formData || !$itemId) {
throw new InvalidArgumentException("当前组件无法渲染, 因为你的参数不对呀~");
}
$checkNameData = Laminas::$serviceManager->itemCheckname->fetchAll([
'order' => ['checkname_order'],
'where' => [
'item_id' => $itemId,
'category_id' => $formData['checklist_id'],
'is_del' => 0
]
]);
$tableData = [];
$imgTxtDiscernData = Laminas::$serviceManager->itemImgtxtdiscern->fetchOne([
'where' => [
'category_id' => $formData['checklist_id'],
'item_sign_id' => $itemSigId,
'is_del' => 0,
'item_id' => $itemId
]
])['check_data'] ?? [];
if ($imgTxtDiscernData) {
if (!is_array($imgTxtDiscernData)) {
$imgTxtDiscernData = Json::decode($imgTxtDiscernData, Json::TYPE_ARRAY);
}
$imgTxtDiscernData = ArrayHelper::index($imgTxtDiscernData, 'checkname_id');
}
foreach ($checkNameData as $k => $checkNameDatum) {
$result = $this->getResult($checkNameDatum['id'], $request);
$tableData[$k] = array_intersect_key($checkNameDatum, array_flip([
'id', 'check_type', 'unit', 'max_val', 'min_val'
]));
$tableData[$k]['check_item'] = $checkNameDatum['name'];
$tableData[$k]['result'] = $result['result'] ?? '';
if (!empty($imgTxtDiscernData[$checkNameDatum['checkname_id']])) {
$tableData[$k]['max_val'] = $imgTxtDiscernData[$checkNameDatum['checkname_id']]['max_val'];
$tableData[$k]['min_val'] = $imgTxtDiscernData[$checkNameDatum['checkname_id']]['min_val'];
$tableData[$k]['unit'] = $imgTxtDiscernData[$checkNameDatum['checkname_id']]['change_unit'];
}
if(!empty($result)) {
$tableData[$k]['max_val'] = $result['reference_range_max'];
$tableData[$k]['min_val'] = $result['reference_range_min'];
$tableData[$k]['unit'] = $result['unit'];
}
// 有手动填写的值就用手写的, 没有的话就用配置的
/*$tableData[$k]['max_val'] = $this->handleVal($imgTxtDiscernData['change_name'], $result['reference_range_max'] ?: $checkNameDatum['max_val']);
$tableData[$k]['min_val'] = $this->handleVal($imgTxtDiscernData['change_name'], $result['reference_range_min'] ?: $checkNameDatum['min_val']);*/
}
return $tableData;
}
private function handleVal($changeName, $val)
{
if ($changeName) {
return (string)(floatval($changeName) * floatval($val));
}
return $val;
}
/**
* 获取 [受试者工作附件表] 结果值
* @param $checkNameId
* @param Request $request
* @return array
*/
private function getResult($checkNameId, Request $request): array
{
$patientFormId = Laminas::$serviceManager->patientForm->fetchOne([
'where' => [
'patient_id' => $request->getPost('patient_id'),
'item_id' => $request->getPost('item_id'),
'itemsig_id' => $request->getPost('itemsig_id'),
'checktime_id' => $request->getPost('checktime_id'),
'form_id' => $request->getPost('id'),
]
])['id'] ?? 0;
$where = [
// 'is_del' => 0,
'item_checkname_id' => $checkNameId,
'patient_id' => $request->getPost('patient_id'),
'item_id' => $request->getPost('item_id'),
'itemsig_id' => $request->getPost('itemsig_id'),
'checktime_id' => $request->getPost('checktime_id'),
];
if($request->getPost('patientformcontent_id') != 0){
$where['patientformcontent_id'] = $request->getPost('patientformcontent_id');
}else{
$where['patient_form_id'] = $patientFormId;
}
$hasResult = Laminas::$serviceManager->itemIdentificationresultchange->fetchOne(['where'=>$where]);
// 检查日期
if (!$this->collectDate) {
$this->collectDate = $hasResult['collect_date'] ?? '';
}
// 备注
if (!$this->note) {
$this->note = $hasResult['result'] ?? '';
}
return $hasResult ?: [];
}
}

View File

@ -0,0 +1,486 @@
<?php
namespace Application\Form;
use Application\Service\Extension\Export\BaseExport;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Laminas\Db\Sql\Predicate\Operator;
/**
* 导出
*/
class ExportModel extends BaseExport
{
/**
* 表格内容
* @var array
*/
protected array $tableData = [];
/**
* Notes:修改查询方法
* @param
* @return
* @author haojinhua
* @date 2025-08-29
*/
public function exportLogicError($data)
{
$itemId = isset($data['item_id']) && !empty($data['item_id']) ? $data['item_id'] : 0;
$itemsig_ids = isset($data['itemsig_ids'])&&!empty($data['itemsig_ids']) ? $data['itemsig_ids'] : 0;
$patient_ids = isset($data['patient_ids'])&&!empty($data['patient_ids']) ? $data['patient_ids'] : 0;
//查询质疑条件拼接
$quer_where = [
'item_id' => $itemId,
'is_del' => 0,
];
//查询图片质疑条件拼接
$question_where = [
'item_id' => $itemId,
'question_type' => 1,
'is_del' => 0,
];
if(!empty($itemsig_ids)){
$question_where['item_sign_id'] = StringHelper::toArray($itemsig_ids);
$quer_where['sign_id'] = StringHelper::toArray($itemsig_ids);
}
if(!empty($patient_ids)){
$question_where['patient_id'] = StringHelper::toArray($patient_ids);
$quer_where['patient_id'] = StringHelper::toArray($patient_ids);
}
//优化 查询逻辑核查质疑信息都放一起
$allerror_infos = Laminas::$serviceManager->itemPatientFormLogicError->fetchAll([
'where' => $quer_where,
'columns' => ['id','is_closed','form_id','checktime_id','patient_id','is_closed','sign_id','expression_note','create_user_id','create_time','update_time','update_user_id','submit_role'],
]);
$error_ids = []; //存储所有用到的error_id
$closed_error_ids = []; //所有关闭质疑的ID
$error_infos = []; //质疑表信息 根据ID找到质疑所有信息
if (!empty($allerror_infos)) {
foreach ($allerror_infos as $error_key => $error_info) {
$error_ids[] = $error_info['id'];
if ($error_info['is_closed'] == 1) {
//所有关闭质疑的ID
$closed_error_ids[] = $error_info['id'];
}
$error_infos[$error_info['id']] = $error_info;
unset($allerror_infos[$error_key]);
}
unset($allerror_infos);
}
$pointer_where = ['is_del' => 0];
if (!empty($error_ids)) {
$pointer_where['error_id'] = StringHelper::toArray($error_ids);
}
//查询质疑回复信息
$all_error_replays = Laminas::$serviceManager->itemPatientFormLogicErrorQuery->fetchAll([
'where' => $pointer_where,
'columns' => ['id','content','error_id','pointer_id','create_user_id','create_time','is_reply','is_auditor','platform'],
]);
$error_replays = []; //存储质疑回复信息
$error_closes = []; //存储质疑关闭信息
if(!empty($all_error_replays)){
foreach ($all_error_replays as $all_error_repkey=>$all_error_replay){
if(in_array($all_error_replay['error_id'],$closed_error_ids)){
$error_closes[$all_error_replay['error_id']]['is_auditor'] = $all_error_replay['is_auditor'];
$error_closes[$all_error_replay['error_id']]['close_time'] = $all_error_replay['create_time'];
$error_closes[$all_error_replay['error_id']]['close_user'] = $all_error_replay['create_user_id'];
}
if($all_error_replay['is_reply'] == 1 && !in_array($all_error_replay['content'],['化验单数据更新锁定','常规识别数据更新锁定','化验单数据解锁更新','常规识别数据解锁更新','关闭质疑'])){
if($all_error_replay['content'] == '数据更新' && empty($all_error_replay['create_user_id'])){
//系统关闭了质疑 如常规识别的补充数据后自动关闭质疑会记录数据更新
continue;
}else{
$error_replays[$all_error_replay['error_id']][$all_error_replay['pointer_id']]['infos'][] = $all_error_replay;
}
}
unset($all_error_replays[$all_error_repkey]);
}
unset($all_error_replays);
}
// 调用
$totalCount = Laminas::$serviceManager->itemPatientFormLogicErrorPointer->getCount($pointer_where);
$pageSize = 10000;
$totalPages = ceil($totalCount / $pageSize);
if ($totalPages > 0) {
$yeildLogDatas = Laminas::$serviceManager->itemExport->yieldData($totalPages,Laminas::$serviceManager->itemPatientFormLogicErrorPointer,$pointer_where,['id','multi_id','create_time','error_id','prop'],['id']);
}
$com_wheres = [
'item_id' => $itemId,
'is_del ' => 0
];
//查询大项目ID
$fiditem_id = Laminas::$serviceManager->itemInfo->getOneFieldVal('fid', [
'id' => $itemId,
]);
//项目编号信息
$itemNumber = Laminas::$serviceManager->itemInfo->getOneFieldVal('number', [
'id' => $itemId,
]);
//中心编号信息
$sigNumbers = Laminas::$serviceManager->itemSignatory->fetchCol('number',['is_del = 0','item_id'=>$fiditem_id]);
//受试者编号
$patientNumbers = Laminas::$serviceManager->patient->fetchCol('patient_number',$com_wheres);
//表单名称
$formNames = Laminas::$serviceManager->itemForm->fetchCol('name',$com_wheres);
//检查点名称
$checkNames = Laminas::$serviceManager->itemChecktime->fetchCol('check_name', $com_wheres);
//重新查询角色IDs
$siguser_role_arr = Laminas::$serviceManager->roleSignatoryRelation->fetchDataByKey(['is_del ' =>0],['role_id','admin_user_id'],'id','admin_user_id',1);
//人员姓名
$userNameArr = Laminas::$serviceManager->adminUser->fetchCol('realname', ['is_del' => 0]);
//角色数组
$roleNameArr = Laminas::$serviceManager->realRole->fetchCol('role_name', ['is_del' => 0]);
$form_filed_arr = Laminas::$serviceManager->itemFormField->fetchCol('name',$com_wheres);
$result_filed_arr = Laminas::$serviceManager->itemIdentificationresultchange->fetchCol('item_name',['item_id'=>$itemId]);
$ocrFormField = [
'collect_date' => '检查时间',
'item_name' => '指标名称',
'unit' => '单位',
'result' => '结果',
'range' => '取值范围',
'normal' => '正常',
'cs' => 'CS',
'ncs' => 'NCS',
'is_identification' => '',
'sdtx' => '手动填写'
];
foreach ($yeildLogDatas as $pointer_datas){
if(!empty($pointer_datas)){
foreach ($pointer_datas as $pointer_key=>$pointer_data) {
$errorreplays = isset($error_replays[$pointer_data['error_id']][$pointer_data['id']]['infos']) && !empty($error_replays[$pointer_data['error_id']][$pointer_data['id']]['infos']) ? $error_replays[$pointer_data['error_id']][$pointer_data['id']]['infos'] : [];
$errorclose = isset($error_closes[$pointer_data['error_id']]) && !empty($error_closes[$pointer_data['error_id']]) ? $error_closes[$pointer_data['error_id']] : [];
$errorinfos = isset($error_infos[$pointer_data['error_id']]) && !empty($error_infos[$pointer_data['error_id']]) ? $error_infos[$pointer_data['error_id']] : [];
$itemsig_id = !empty($errorinfos['sign_id']) ? $errorinfos['sign_id'] : 0;
$patient_id = !empty($errorinfos['patient_id']) ? $errorinfos['patient_id'] : 0;
$form_id = !empty($errorinfos['form_id']) ? $errorinfos['form_id'] : 0;
$checktime_id = !empty($errorinfos['checktime_id']) ? $errorinfos['checktime_id'] : 0;
$submitRole = $errorinfos['submit_role'];
$userId = $errorinfos['create_user_id'];
$prop = $pointer_data['prop'];
$sign_id = isset($sigNumbers[$itemsig_id]) && !empty($sigNumbers[$itemsig_id]) ? $sigNumbers[$itemsig_id] : '';
// 处理化验单的字段
if (!is_numeric($prop) && stripos($prop, '-') === false) {
if (in_array($prop, ['sdtx', 'collect_date'])) {
$prop_filed = $ocrFormField[$prop] ?? '';
}else{
if (!is_numeric($prop)) {
$prefix = ($ocrFormField[$prop] ?? '');
}
$change_name = isset($result_filed_arr[$pointer_data['multi_id']]) & !empty($result_filed_arr[$pointer_data['multi_id']]) ? $result_filed_arr[$pointer_data['multi_id']] : '';
$prop_filed = ($prefix) . "[" . $change_name. ']';
}
}else{
$fieldId = DataHelper::getFieldId($prop);
//改为直接查询字段表
$fieldId_name = isset($form_filed_arr[$fieldId]) & !empty($form_filed_arr[$fieldId]) ? $form_filed_arr[$fieldId] : '';
$prop_filed = $fieldId_name ?? "未知的字段名称";
}
/*=====================================质疑提出人员 角色=====================================*/
if (!$submitRole) {
//查询用户角色
$role_ids = isset($siguser_role_arr[$userId]) && !empty($siguser_role_arr[$userId]) ? array_values(array_unique(array_column($siguser_role_arr[$userId],'role_id'))) : [];
if(!empty($role_ids)){
foreach ($role_ids as $role_id){
$submitRole .= isset($roleNameArr[$role_id]) && !empty($roleNameArr[$role_id]) ? $roleNameArr[$role_id].'|' : '';
}
}
unset($role_ids);
}
if ($userId == 0) {
$create_user_id = 'System';
}else{
$create_user_id = isset($userNameArr[$userId]) & !empty($userNameArr[$userId]) ? $userNameArr[$userId] . '[' . $submitRole . ']' : '';
}
/*=====================================质疑关闭人员 角色=====================================*/
$close_user_id = isset($errorclose['close_user']) ? $errorclose['close_user'] : null;
if ($close_user_id === null) {
$close_user = '';
$closed_user_id = $close_user;
}elseif($close_user_id == 0) {
$close_user = 'System';
$closed_user_id = $close_user;
} else {
//关闭 查询的是edc的角色 是单角色 手动质疑只有提出质疑的人可以关 系统质疑可以自动关或者DM关 系统质疑的话 提质疑角色是空的
$close_role = $errorinfos['submit_role'];
if(!empty($close_role)){
$closeRole = $close_role;
}else{
$closeRole = 'DM';
}
$close_user = isset($userNameArr[$close_user_id]) & !empty($userNameArr[$close_user_id]) ? $userNameArr[$close_user_id]:'';
$closed_user_id = $close_user. '[' . $closeRole . ']';
}
if (!empty($errorreplays)) {
$errorIdCount = []; // 初始化计数数组
//有回复信息
foreach ($errorreplays as $errorreplays_key=>$errorreplay) {
$error_id = $pointer_data['error_id']; // 获取当前error_id
// 计数逻辑(核心部分)
$occurrence = isset($errorIdCount[$error_id])
? ++$errorIdCount[$error_id] // 已存在:计数+1
: ($errorIdCount[$error_id] = 1); // 新ID初始化计数为1
$closed_time = !empty($errorclose['close_time']) ? $errorclose['close_time'] : null;
/*=====================================质疑回复人员 角色=====================================*/
if ($errorreplay['create_user_id'] === null) {
$reply_user_id = '';
}elseif($errorreplay['create_user_id'] == 0) {
$reply_user_id = 'System';
} else {
//查询用户角色
$rolereply_ids = isset($siguser_role_arr[$errorreplay['create_user_id']]) && !empty($siguser_role_arr[$errorreplay['create_user_id']]) ? array_values(array_unique(array_column($siguser_role_arr[$errorreplay['create_user_id']],'role_id'))) : [];
if(!empty($rolereply_ids)){
foreach ($rolereply_ids as $rolereply_id){
$replyRole = isset($roleNameArr[$rolereply_id]) && !empty($roleNameArr[$rolereply_id]) ? $roleNameArr[$rolereply_id].'|' : '';
}
}
$reply_user = isset($userNameArr[$errorreplay['create_user_id']]) & !empty($userNameArr[$errorreplay['create_user_id']]) ? $userNameArr[$errorreplay['create_user_id']]:'';
if($errorclose['is_auditor'] == 1){
$replyRole = '图片审核员';
}
unset($rolereply_ids);
$reply_user_id = $reply_user. '[' . $replyRole . ']';
}
$this->tableData[0][] = [
'item_id' => $itemNumber,
'sign_id' => $sign_id,
'patient_id' => isset($patientNumbers[$patient_id]) && !empty($patientNumbers[$patient_id]) ? $patientNumbers[$patient_id] : '',
'checktime_id' => isset($checkNames[$checktime_id]) && !empty($checkNames[$checktime_id]) ? $checkNames[$checktime_id] : '',
'form_id' => isset($formNames[$form_id]) && !empty($formNames[$form_id]) ? $formNames[$form_id] : '',
'prop' => $prop_filed,
'error_number' => $occurrence,
'expression_note' => !empty($errorinfos['expression_note']) ? $errorinfos['expression_note'] : 0,
'create_time' => !empty($pointer_data['create_time']) ? date('Y-m-d H:i:s', $pointer_data['create_time']) : '',
'create_user_id' => $create_user_id,
'reply_content' => $errorreplay['content'],
'reply_time' => !empty($errorreplay['create_time']) ? date('Y-m-d H:i:s', $errorreplay['create_time']) : '',
'reply_user_id' => $reply_user_id,
'closed_time' => !empty($closed_time) ? date('Y-m-d H:i:s', $closed_time) : '',
'closed_user_id' => $closed_user_id
];
unset($errorreplays[$errorreplays_key]);
}
unset($errorIdCount);
} else {
//无回复信息
$this->tableData[0][] = [
'item_id' => $itemNumber,
'sign_id' => $sign_id,
'patient_id' => isset($patientNumbers[$patient_id]) && !empty($patientNumbers[$patient_id]) ? $patientNumbers[$patient_id] : '',
'checktime_id' => isset($checkNames[$checktime_id]) && !empty($checkNames[$checktime_id]) ? $checkNames[$checktime_id] : '',
'form_id' => isset($formNames[$form_id]) && !empty($formNames[$form_id]) ? $formNames[$form_id] : '',
'prop' => $prop_filed,
'error_number' => 1,
'expression_note' => !empty($errorinfos['expression_note']) ? $errorinfos['expression_note'] : 0,
'create_time' => !empty($pointer_data['create_time']) ? date('Y-m-d H:i:s', $pointer_data['create_time']) : '',
'create_user_id' => $create_user_id,
'reply_content' => null,
'reply_time' => null,
'reply_user_id' => null,
'closed_time' => !empty($closed_time) ? date('Y-m-d H:i:s', $closed_time) : '',
'closed_user_id' => $closed_user_id
];
}
unset($errorinfos);
unset($errorclose);
unset($errorreplays);
unset($pointer_datas[$pointer_key]);
}
unset($pointer_datas);
}
}
//查询图片质疑
$question_cond = [
'where' => $question_where,
'columns' => ['id','item_sign_id','item_id','form_id','checktime_id','patient_id','content','question','create_time','create_user_id','question_status'],
'order' => ['patient_id','id'],
];
$question_infos = Laminas::$serviceManager->itemQuestion->fetchAll($question_cond);
$question_ids = array_column($question_infos,'id');
if(!empty($question_infos)){
$question_replays = Laminas::$serviceManager->itemQuestion->getreplayinfo([
'is_del' => 0,
'question_id' => StringHelper::toArray($question_ids),
new Operator('reply_status', Operator::OP_NE, 2)
]);
$question_closes = Laminas::$serviceManager->itemQuestion->getreplayinfo([
'is_del' => 0,
'question_id' => StringHelper::toArray($question_ids),
'reply_status' => 2,
]);
foreach ($question_infos as &$question_info){
$questionreplays = isset($question_replays[$question_info['id']]['replays']) && !empty($question_replays[$question_info['id']]['replays']) ? $question_replays[$question_info['id']]['replays'] : [];
$questionclosed = isset($question_closes[$question_info['id']]['colsed']) && !empty($question_closes[$question_info['id']]['colsed']) ? $question_closes[$question_info['id']]['colsed'] : [];
$question_info['closed_time'] = !empty($questionclosed) ? $questionclosed['create_time'] : null;
$question_info['closed_user_id'] = !empty($questionclosed) ? $questionclosed['create_user_id'] : null;
$closed_time = !empty($question_info['closed_time']) ? date('Y-m-d H:i:s', $question_info['closed_time']) : '';
/*=====================================质疑提出人员=====================================*/
$create_user_id = isset($userNameArr[$question_info['create_user_id']]) & !empty($userNameArr[$question_info['create_user_id']]) ? $userNameArr[$question_info['create_user_id']] : '';
/*=====================================质疑关闭人员 角色=====================================*/
if ($question_info['closed_user_id'] === null) {
$question_info['closed_user_id'] = '';
}elseif($question_info['closed_user_id'] == 0) {
$question_info['closed_user_id'] = 'System';
} else {
$closeRole = '';
//查询用户角色
$closerole_ids = isset($siguser_role_arr[$question_info['closed_user_id']]) && !empty($siguser_role_arr[$question_info['closed_user_id']]) ? array_values(array_unique(array_column($siguser_role_arr[$question_info['closed_user_id']],'role_id'))) : [];
if(!empty($closerole_ids)){
foreach ($closerole_ids as $closerole_id){
$closeRole .= isset($roleNameArr[$closerole_id]) && !empty($roleNameArr[$closerole_id]) ? $roleNameArr[$closerole_id].'|' : '';
}
$closeRole = rtrim($closeRole,'|');
}
$close_user = isset($userNameArr[$question_info['closed_user_id'] ]) && !empty($userNameArr[$question_info['closed_user_id'] ]) ? $userNameArr[$question_info['closed_user_id'] ]:'';
$question_info['closed_user_id'] = !empty($closeRole) ? $close_user. '[' . $closeRole . ']' : $close_user;
}
$prop = json_decode($question_info['content'],true);
// 处理化验单的字段
if (is_array($prop)) {
$prop = current(array_keys($prop));
}
//改为直接查询字段表
$fieldId_name = isset($form_filed_arr[$prop]) & !empty($form_filed_arr[$prop]) ? $form_filed_arr[$prop] : '';
$prop_filed = $fieldId_name ?? "未知的字段名称";
if(!empty($questionreplays)){
$errorIdCount = [];
foreach ($questionreplays as $questionreplay){
/*=====================================质疑回复人员 角色=====================================*/
if (!$questionreplay['create_user_id']) {
$reply_users = '';
}else{
$reply_user_id = $questionreplay['create_user_id'];
if ($reply_user_id === null) {
$reply_users = '';
}elseif($reply_user_id == 0) {
$reply_users = 'System';
} else {
//查询用户角色
$rolereply_ids = isset($siguser_role_arr[$reply_user_id]) && !empty($siguser_role_arr[$reply_user_id]) ? array_values(array_unique(array_column($siguser_role_arr[$reply_user_id],'role_id'))) : [];
if(!empty($rolereply_ids)){
foreach ($rolereply_ids as $rolereply_id){
$replyRole = isset($roleNameArr[$rolereply_id]) && !empty($roleNameArr[$rolereply_id]) ? $roleNameArr[$rolereply_id].'|' : '';
}
}
$reply_user = isset($userNameArr[$reply_user_id]) & !empty($userNameArr[$reply_user_id]) ? $userNameArr[$reply_user_id]:'';
$reply_users =!empty($replyRole) ? $reply_user. '[' . $replyRole . ']' : $reply_user;
}
}
$v = json_decode($questionreplay['remarks'], true);
if ($v['remarks'] === null) {
$reply_content = '';
}elseif (!isset($v['remarks'])) {
if ($questionreplay['remarks']) {
$reply_content = trim($questionreplay['remarks'], '"');
}else{
$reply_content = '';
}
}else{
$reply_content = trim($v['remarks'], '"');
}
$error_id = $question_info['id']; // 获取当前error_id
// 计数逻辑(核心部分)
$occurrence = isset($errorIdCount[$error_id])
? ++$errorIdCount[$error_id] // 已存在:计数+1
: ($errorIdCount[$error_id] = 1); // 新ID初始化计数为1
$this->tableData[1][] = [
'item_id' => $itemNumber,
'sign_id' => isset($sigNumbers[$question_info['item_sign_id']]) && !empty($sigNumbers[$question_info['item_sign_id']]) ? $sigNumbers[$question_info['item_sign_id']] : '',
'patient_id' => isset($patientNumbers[$question_info['patient_id']]) && !empty($patientNumbers[$question_info['patient_id']]) ? $patientNumbers[$question_info['patient_id']] : '',
'checktime_id' => isset($checkNames[$question_info['checktime_id']]) && !empty($checkNames[$question_info['checktime_id']]) ? $checkNames[$question_info['checktime_id']] : '',
'form_id' => isset($formNames[$question_info['form_id']]) && !empty($formNames[$question_info['form_id']]) ? $formNames[$question_info['form_id']] : '',
'prop' => $prop_filed,
'error_number' => $occurrence,
'expression_note' => $question_info['question'],
'create_time' => !empty($question_info['create_time']) ? date('Y-m-d H:i:s', $question_info['create_time']) : '',
'create_user_id' => $create_user_id,
'reply_content' => $reply_content,
'reply_time' => !empty($questionreplay['create_time']) ? date('Y-m-d H:i:s', $questionreplay['create_time']) : '',
'reply_user_id' => $reply_users,
'closed_time' => $closed_time,
'closed_user_id' => $question_info['closed_user_id']
];
}
unset($questionreplays);
unset($errorIdCount);
}else{
$this->tableData[1][] = [
'item_id' => $itemNumber,
'sign_id' => isset($sigNumbers[$question_info['item_sign_id']]) && !empty($sigNumbers[$question_info['item_sign_id']]) ? $sigNumbers[$question_info['item_sign_id']] : '',
'patient_id' => isset($patientNumbers[$question_info['patient_id']]) && !empty($patientNumbers[$question_info['patient_id']]) ? $patientNumbers[$question_info['patient_id']] : '',
'checktime_id' => isset($checkNames[$question_info['checktime_id']]) && !empty($checkNames[$question_info['checktime_id']]) ? $checkNames[$question_info['checktime_id']] : '',
'form_id' => isset($formNames[$question_info['form_id']]) && !empty($formNames[$question_info['form_id']]) ? $formNames[$question_info['form_id']] : '',
'prop' => $prop_filed,
'error_number' => 1,
'expression_note' => $question_info['question'],
'create_time' => !empty($question_info['create_time']) ? date('Y-m-d H:i:s', $question_info['create_time']) : '',
'create_user_id' => $create_user_id,
'reply_content' => null,
'reply_time' => null,
'reply_user_id' => null,
'closed_time' => null,
'closed_user_id' => null
];
}
unset($questionclosed);
}
unset($question_infos);
unset($question_replays);
unset($question_ids);
}
//print_r($questionQuery);die;
unset($sigNumbers);
unset($itemNumber);
unset($patientNumbers);
unset($formNames);
unset($checkNames);
unset($sig_user_arr);
unset($user_role_arr);
unset($siguser_role_arr);
unset($itemsig_arr);
unset($userNameArr);
unset($roleNameArr);
unset($ocrFormField);
unset($form_filed_arr);
return $this->tableData;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,749 @@
<?php
namespace Application\Form;
use Application\Common\Enum;
use Application\Form\item\ItemFieldForm;
use Application\Service\DB\AbstractDb;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Form\BaseForm;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\FormFormatter;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Laminas;
use Laminas\Db\Sql\Predicate\NotIn;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Validator\Exception\InvalidArgumentException;
/**
* 字典项表单
* @author TOOM1996 <1023150697@qq.com>
*/
class FormForm extends BaseForm
{
private ?array $_test = [];
/**
* dictionaryForm
* @return Form
*/
protected function getForm(): AbstractDb
{
return Laminas::$serviceManager->dictionaryForm;
}
protected function getFormField()
{
return Laminas::$serviceManager->dictionaryFormField;
}
protected function getFormRadio()
{
return Laminas::$serviceManager->dictionaryFormFieldRadio;
}
protected function getFormText()
{
return Laminas::$serviceManager->dictionaryFormFieldText;
}
protected function getFormVersion()
{
return Laminas::$serviceManager->dictionaryFormVersion;
}
/**
* 验证字典项表单名称是否添加重复
* @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]
]);
if ($query) {
throw new InvalidArgumentException("表单名称 {$value} 已存在, 请勿重复添加。");
}
} else {
$query = $this->getForm()->fetchOne([
'columns' => ['id'],
'where' => ['name' => $request->getPost('name'), 'is_del' => 0]
]);
if ($query && (count($query) > 1 || $query['id'] != $request->getPost('id'))) {
throw new InvalidArgumentException("表单名称 {$value} 已在其他表单中使用, 请勿重复添加。");
}
}
}
if ($request->getPost('type') == Form::FORM_TYPE_SINGLE && $request->getPost('group_id') == FormGroup::THROUGH_PROCESS) {
throw new InvalidArgumentException("一对一类型的表单暂不支持设置成贯穿全程。");
}
return null;
}
// TODO 现在好像不好使
public function invalidCopyId($value)
{
$value = explode(',', $value);
foreach ($value as $attribute) {
$dictionaryForm = Laminas::$serviceManager->dictionaryForm->fetchOne([
'where' => ['id' => $attribute]
]);
$hasExist = Laminas::$serviceManager->itemForm->fetchOne([
'where' => ['name' => $dictionaryForm['name'], 'is_del' => 0, 'item_id' => Laminas::$app->getMvcEvent()->getRequest()->getPost('item_id')]
]);
if ($hasExist) {
throw new InvalidArgumentException("添加失败啦!!!项目中已存在名称为 {$dictionaryForm['name']} 的表单。");
}
}
}
/**
* 验证检查类OCR识别是否设置了检查项。
* 验证是否切换了检查项id。
* 不允许有检查项id切换成无检查项id。
* 不允许无检查项id切换成有检查项id。
*/
public function invalidCheckListId($value)
{
$params = Laminas::$app->getMvcEvent()->getRequest();
if (in_array($params->getPost('group_id'), [FormGroup::CHECK_OCR]) && !$params->getPost('checklist_id')) {
throw new InvalidArgumentException("保存失败。检查类OCR识别必须选择一项检查项表单。");
}
if ($id = $params->getPost('id')) {
$formData = $this->getForm()->fetchOne(['where' => ['id' => $id]]);
if ($formData['checklist_id'] > 0 && $value == 0) {
throw new InvalidArgumentException("保存失败。无法将已添加的检查项表单清除, 因为我们已为您初始化了检查项表单。");
}
}
// 一个项目下只能有一个类型的化验单
if (in_array($params->getPost('group_id'), [FormGroup::CHECK_OCR]) && $params->getPost('checklist_id') && $this->getForm()->getCount([
'where' => [
'item_id' => $params->getPost('item_id'),
'checklist_id' => $params->getPost('checklist_id'),
'is_del' => 0,
new Operator('id', '<>', $id ?: 0)
]
])) {
throw new InvalidArgumentException("保存失败。此类化验单表单已存在!");
}
return null;
}
/**
* 创建字典项表单
* @return int
*/
public function createForm(): int
{
Db::beginTransaction();
// 实验总结类默认勾选所有隶属实验总结类检查点
if ($this->validator->attributes['group_id'] == FormGroup::TEST_SUMMARY) {
$this->validator->attributes['ds_stage'] = FormGroup::DS_STAGE;
}
$formId = $this->getForm()->insert([
'name' => $this->validator->attributes['name'],
'type' => $this->validator->attributes['type'],
'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'],
'code' => $this->getForm()->generateFormCode(),
'reference_file' => $this->validator->attributes['reference_file'],
'rdg_type' => $this->validator->attributes['rdg_type'],
'var_name' => $this->validator->attributes['var_name'] ?: '',
'can_patient_write' => $this->validator->attributes['can_patient_write'] ?: 0,
'is_handwritten_signature' => $this->validator->attributes['can_patient_write'] ?: 0,
'ds_stage' => $this->validator->attributes['ds_stage'] ?: 1,
'is_patient_general_info' => $this->validator->attributes['is_patient_general_info'] ?? ''
]);
// 添加随机分组字段
$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) {
if ($this->validator->attributes['type'] == 0) {
throw new \Application\Service\Exceptions\InvalidArgumentException('识别医嘱的类型不能为一对一');
}
// 初始化贯穿全程识别医嘱表单字段
$this->initThroughProcessDoField($formId);
}
Db::commit();
return $formId;
}
/**
* 初始化贯穿全程识别医嘱字段
*/
public function initThroughProcessDoField($formId)
{
$generateFields = [
[
'name' => '医嘱类型',
'type' => FormField::FORM_FIELD_TYPE_RADIO,
'var_name' => 'THROUGH_PROCESS_DO_TYPE',
'is_list' => 1
],
[
'name' => '临时医嘱',
'type' => 0,
'value' => 1,
'var_name' => 'THROUGH_PROCESS_DO_TYPE_A'
],
[
'name' => '长期医嘱',
'type' => 0,
'value' => 2,
'var_name' => 'THROUGH_PROCESS_DO_TYPE_B'
],
[
'name' => '处方',
'type' => 0,
'value' => 3,
'var_name' => 'THROUGH_PROCESS_DO_TYPE_C'
],
[
'name' => '日期类型',
'type' => FormField::FORM_FIELD_TYPE_RADIO,
'var_name' => 'THROUGH_PROCESS_DO_DATE',
'is_list' => 1
],
[
'name' => '年月日',
'type' => 0,
'value' => 1,
'var_name' => 'THROUGH_PROCESS_DO_DATE_A'
],
[
'name' => '日月年',
'type' => 0,
'value' => 2,
'var_name' => 'THROUGH_PROCESS_DO_DATE_B'
],
[
'name' => '年月',
'type' => 0,
'value' => 3,
'var_name' => 'THROUGH_PROCESS_DO_TYPE_C'
],
[
'name' => '月日',
'type' => 0,
'value' => 4,
'var_name' => 'THROUGH_PROCESS_DO_TYPE_D'
],
[
'name' => '图片',
'type' => FormField::FORM_FIELD_TYPE_UPLOAD_IMAGE,
'var_name' => 'THROUGH_PROCESS_DO_IMAGE'
]
];
foreach ($generateFields as $field) {
if (in_array($field['type'], [FormField::FORM_FIELD_TYPE_UPLOAD_IMAGE, FormField::FORM_FIELD_TYPE_RADIO])) {
$fieldId = $this->getFormField()->save([
'form_id' => $formId,
'name' => $field['name'],
'type' => $field['type'],
'is_list' => $field['is_list'],
'rules' => null,
'version' => 'v1.0',
'order' => 0,
'is_del' => 0,
'is_anchor' => 0,
'item_id' => $this->validator->attributes['item_id'],
'var_name' => $field['var_name'],
'default' => 0,
]);
}
if ($field['type'] == 0) {
$childId = $this->getFormField()->save([
'form_id' => $formId,
'name' => $field['name'],
'type' => $field['type'],
'is_list' => 0,
'rules' => null,
'version' => 'v1.0',
'order' => 0,
'is_del' => 0,
'is_anchor' => 0,
'item_id' => $this->validator->attributes['item_id'],
'var_name' => $field['var_name'],
'parent' => $fieldId
]);
$this->getFormRadio()->save([
'value' => $field['value'],
'is_check' => 0,
'relation_classification' => 0,
'relation_type' => 0,
'relation_information' => 0,
'field_id' => $childId,
'form_id' => $formId,
'is_score' => 0
]);
}
}
$versionData = Laminas::$serviceManager->itemForm->buildFieldVersion($formId);
$this->getFormVersion()->save([
'field' => $versionData,
'version' => 'v1.0',
'form_id' => $formId
]);
}
/**
* @param $formId
* @param int $type 1 => 手动添加, 2 => 系统分组
* @return void|null
*/
public function initRandomGroupField($formId, int $type)
{
if (!$type) {
return null;
}
// 随机分组类表单,随机日期的默认存在以及变量名统一要求设置 --蒙,美
//https://e.gitee.com/yikeen_project/dashboard?issue=I9QLAA
$randDateCondition = [
'form_id' => $formId,
'name' => '随机日期',
'type' => FormField::FORM_FIELD_TYPE_DATE,
'is_list' => 0,
'rules' => null,
'version' => 'v1.0',
'order' => 10,
'is_del' => 0,
'is_anchor' => 0,
'is_booked_time' => 0,
'var_name' => 'RANDDAT',
];
$condition = [
'form_id' => $formId,
'name' => '研究分层',
'type' => $type == 1 ? Enum::FORM_FIELD_TYPE_RADIO : Enum::FORM_FIELD_TYPE_DROPDOWN,
'is_list' => 0,
'rules' => null,
'version' => 'v1.0',
'order' => 10,
'is_del' => 0,
'is_anchor' => 0,
'is_booked_time' => 0,
'var_name' => $type == 1 ? 'RANGC' : 'RANGCA',
'showfiled_name'=>$type == 1 ? '随机号' : '随机号/方案分组',
];
if ($this->validator->attributes['item_id']) {
$condition['item_id'] = $randDateCondition['item_id'] = $this->validator->attributes['item_id'];
}
$randFileId = $this->getFormField()->save($randDateCondition);
$this->_test[] = $randFileId;
$this->getFormText()->save([
'var_name' => 'RANDDAT',
'tips' => '',
'placeholder' => '',
'is_list' => 0,
'field_id' => $randFileId,
'order' => 10,
'form_id' => $formId
]);
$fieldId = $this->getFormField()->save($condition);
$this->_test[] = $fieldId;
$this->getFormText()->save([
'var_name' => $type == 1 ? 'RANGC' : 'RANGCA',
'tips' => '',
'placeholder' => '',
'is_list' => 0,
'field_id' => $fieldId,
'order' => 10,
'form_id' => $formId
]);
SDMHelper::app()->form->setAttributes(['form_id' => $formId,])->setIsDictionary( get_called_class() == FormForm::class)->generateVersion($formId, true);
}
/**
* 获取初始化随机分组表单生成的字段id
*/
protected function _getInitRandomGroupFieldId(): ?array
{
return $this->_test;
}
/**
* 初始化检查项表单
* @param $formId
*/
public function initCheckListField($formId)
{
$checkNameData = Laminas::$serviceManager->dictionaryChecknameattr->fetchAll(['where' => ['is_del' => 0]]);
foreach ($checkNameData as $item) {
if ($item['attr_type'] == Enum::FORM_FIELD_TYPE_TEXT || $item['attr_type'] == Enum::FORM_FIELD_TYPE_UPLOAD_IMAGE || $item['attr_type'] == Enum::FORM_FIELD_TYPE_RADIO) {
$fieldId = $this->getFormField()->save([
'form_id' => $formId,
'name' => $item['attr_name'],
'type' => $item['attr_type'],
'is_list' => 0,
'rules' => null,
'version' => 'v1.0',
'order' => $item['attr_order'],
'is_del' => 0,
'is_anchor' => 0,
'item_id' => $this->validator->attributes['item_id'],
'var_name' => $item['attr_filed'] ?: '',
'default' => $item['default'] ?? '',
]);
$contentItemMap[$item['id']] = $fieldId;
}
}
foreach ($checkNameData as $item) {
if ($item['attr_type'] == Enum::FORM_FIELD_TYPE_TEXT || $item['attr_type'] == Enum::FORM_FIELD_TYPE_UPLOAD_IMAGE || $item['attr_type'] == Enum::FORM_FIELD_TYPE_RADIO) {
$this->getFormText()->save([
'var_name' => $item['attr_filed'],
'tips' => '',
'placeholder' => '',
'is_list' => 0,
'field_id' => $contentItemMap[$item['id']],
'order' => $item['attr_order'],
'form_id' => $formId,
]);
if ($item['content']) {
$content = json_decode($item['content'], true);
foreach ($content as $contentItem) {
// 处理关联项目
foreach ($contentItem['select_attr'] as &$v) {
$v = $contentItemMap[$v] ?? '0';
}
$childId = $this->getFormField()->save([
'form_id' => $formId,
'name' => $contentItem['select_name'],
'type' => 0,
'is_list' => 0,
'rules' => null,
'version' => 'v1.0',
'order' => $contentItem['select_order'],
'is_del' => 0,
'is_anchor' => 0,
'parent' => $fieldId,
'var_name' => $contentItem['select_code'],
'item_id' => $this->validator->attributes['item_id'],
'default' => $item['default'] ?? '',
]);
$this->getFormRadio()->save([
'value' => $contentItem['select_val'],
'is_check' => 0,
'relation_classification' => 2,
'relation_type' => 1,
'relation_information' => $contentItem['select_attr'] ? implode(',', $contentItem['select_attr']) : 0,
'field_id' => $childId,
'form_id' => $formId,
'is_score' => 0
]);
}
}
}
}
$versionData = Laminas::$serviceManager->itemForm->buildFieldVersion($formId);
$this->getFormVersion()->save([
'field' => $versionData,
'version' => 'v1.0',
'form_id' => $formId
]);
}
/**
* 编辑字典项表单
* @return array
*/
public function editForm()
{
Laminas::$serviceManager->dictionaryForm->save([
'id' => $this->validator->attributes['id'],
'name' => $this->validator->attributes['name'],
'type' => $this->validator->attributes['type'],
'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' => $this->validator->attributes['rdg_type'],
'var_name' => $this->validator->attributes['var_name'] ?: '',
'can_patient_write' => $this->validator->attributes['can_patient_write'] ?: 0,
'is_handwritten_signature' => $this->validator->attributes['is_handwritten_signature'] ?? 0,
'ds_stage' => $this->validator->attributes['ds_stage'] ?: 1,
'identification_edit' => ArrayHelper::getValue($this->validator->attributes, 'identification_edit', 0),
]);
return [];
}
/**
* 复制字典项表单
*/
public function copyTo()
{
Db::beginTransaction();
$selectDictionaryFormId = explode(',', $this->validator->attributes['id']);
foreach ($selectDictionaryFormId as $value) {
$this->_copy($value);
}
Db::commit();
}
/**
* @param int $id 字典项表单id
*/
private function _copy(int $id)
{
// form 表
$formData = $this->getForm()->fetchOne([
'where' => ['id' => $id]
]);
// 验证指定表单数量
if (
in_array($formData['group_id'], [
FormGroup::AE,
FormGroup::SAE,
FormGroup::RANDOM_GROUP
])
) {
if (
Laminas::$serviceManager->itemForm->fetchOne([
'where' => [
'item_id' => $this->validator->attributes['item_id'],
'group_id' => $formData['group_id'],
'is_del' => 0
]
])
) {
Db::rollback();
throw new \Application\Service\Exceptions\InvalidArgumentException("复制中断。 `{$formData['name']}` 的表单类型一个项目只能添加一个。 ");
}
}
$insertId = Laminas::$serviceManager->itemForm->save([
'name' => $formData['name'],
'item_id' => $this->validator->attributes['item_id'],
'group_id' => $formData['group_id'],
'type' => $formData['type'],
'is_del' => 0,
'order' => $formData['order'],
'finish_condition' => $formData['finish_condition'],
'is_required' => $formData['is_required'],
'checklist_id' => $formData['checklist_id'],
'is_show' => $formData['is_show'],
'show_type' => $formData['show_type'],
'is_patient' => 0,
'reference_file' => $formData['reference_file'],
'var_name' => $formData['var_name'],
'can_patient_write' => $formData['can_patient_write'],
'rdg_type' => $formData['rdg_type'],
'is_handwritten_signature' => $formData['is_handwritten_signature'],
'ds_stage' => $formData['ds_stage']
]);
// 字段表
$fieldData = Laminas::$serviceManager->dictionaryFormField->fetchAll([
'where' => ['form_id' => $id, 'version' => 'v1.0', 'is_del' => 0]
]);
if (!$fieldData) {
throw new InvalidArgumentException('你无法复制一个不存在字段属性的表单。');
}
$map = $fieldMap = [];
foreach ($fieldData as $datum) {
$fieldId = Laminas::$serviceManager->itemFormField->save([
'form_id' => $insertId,
'name' => $datum['name'],
'type' => $datum['type'],
'is_list' => $datum['is_list'],
'is_export' => $datum['is_export'],
'order' => $datum['order'],
'rules' => $datum['rules'],
'version' => $datum['version'],
'is_del' => $datum['is_del'],
'parent' => $datum['parent'] ? $map[$datum['parent']] : 0,
'is_anchor' => $datum['is_anchor'] ?: 0,
'is_booked_time' => $datum['is_booked_time'] ?: 0,
'item_id' => $this->validator->attributes['item_id'],
'var_name' => $datum['var_name'],
'is_hide' => $datum['is_hide'] ?: 0,
'dicform_id' => $datum['dicform_id'] ?: 0,
]);
if ($datum['parent'] == 0) {
$map[$datum['id']] = $fieldId;
}
$fieldMap[] = $fieldId;
}
foreach ($fieldData as $k => $datum) {
// text 表
$textData = Laminas::$serviceManager->dictionaryFormFieldText->fetchAll([
'where' => ['field_id' => $datum['id']]
]);
$relationMap = [];
foreach ($textData as $textDatum) {
$textId = Laminas::$serviceManager->itemFormFieldText->save([
'var_name' => $textDatum['var_name'],
'tips' => $textDatum['tips'],
'placeholder' => $textDatum['placeholder'],
'is_list' => $textDatum['is_list'],
'order' => $textDatum['order'],
'field_id' => $fieldMap[$k],
'form_id' => $insertId
]);
$relationMap[$textDatum['id']] = $textId;
}
// radio 表
$versionData = Laminas::$serviceManager->dictionaryFormFieldRadio->fetchAll([
'where' => ['field_id' => $datum['id']]
]);
foreach ($versionData as $versionDatum) {
Laminas::$serviceManager->itemFormFieldRadio->save([
'value' => $versionDatum['value'],
'is_check' => call_user_func(function () use ($versionDatum) { // 1是false 0是true
if (!$versionDatum['is_check']) {
return 0;
}
return $versionDatum['is_check'];
}),
'relation_classification' => $versionDatum['relation_classification'],
'relation_type' => $versionDatum['relation_type'],
'relation_information' => $this->_handleRelationInformation($versionDatum['relation_information'], $map),
'field_id' => $fieldMap[$k],
'form_id' => $insertId,
'score' => $versionDatum['score'],
'is_score' => $versionDatum['is_score'],
]);
}
}
// 重新生成表单版本数据
$model = new ItemFieldForm();
Laminas::$serviceManager->itemFormVersion->save([
'version' => 'v1.0',
'field' => $model->buildVersionField($fieldId, $insertId),
'form_id' => $insertId,
]);
}
/**
* 复制表单时对有关联信息的表单做处理
* @param string $relationInformation
* @param $relationMap
* @return string
*/
private function _handleRelationInformation(string $relationInformation, $relationMap): string
{
$relationInformation = explode(',', $relationInformation);
foreach ($relationInformation as &$value) {
if ($value) {
$value = $relationMap[$value];
}
}
return implode(',', $relationInformation);
}
public function getCopyList(): array
{
$itemForm = Laminas::$serviceManager->itemForm->fetchAll([
'columns' => ['code'],
'where' => ['is_del' => 0, 'item_id' => $this->validator->attributes['item_id']],
'order' => ['order']
]);
$arr = array_filter(ArrayHelper::getColumn($itemForm, 'code'));
$whereCondition = ['is_del' => 0];
if ($arr) {
$whereCondition[] = new NotIn('code', $arr);
}
// 表单类型id
$form_group_id = $this->validator->attributes['form_group_id'];
// 表单tpye
$form_type = $this->validator->attributes['form_type'];
// 表单检索条件
$formWhereArr = ['is_del' => 0];
if($form_group_id) $whereCondition['group_id'] = $form_group_id;
if($form_type !== '') $whereCondition['type'] = $form_type;
$dictionaryForm = Laminas::$serviceManager->dictionaryForm->fetchAllWithPagination([
'columns' => ['id', 'group_id', 'name', 'type', 'order'],
'where' => $whereCondition,
'order' => ['order']
]);
Formatter::format($dictionaryForm['data'], new FormFormatter());
return [
'data' => $dictionaryForm['data'],
'total' => $dictionaryForm['count']
];
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace Application\Form;
use Application\Common\RedisEnum;
use Application\Service\Extension\Laminas;
use Overtrue\Socialite\User;
class LoginForm
{
public string $code;
public function getLoginInfo($code): string
{
//获取hash值
$data['code'] = $code;
$data['ip'] = $_SERVER['REMOTE_ADDR'];
$data['create_time'] = time() + 180;
return serialize($data);
}
/**
* 设置用户状态, 及token
* @param User $user
* @return array
*/
public function setCallback(User $user)
{
$query = Laminas::$serviceManager->adminUser->fetchOne([
'where' => [
'openid' => $user->getId(),
'is_del' => 0
]
]);
// 用户未绑定
if (!$query) {
// 前端需要用这些信息做绑定
$status = [
'bind_status' => -1,
'nickname' => $user->getNickname(),
'avatar' => $user->getAvatar(),
'openid' => $user->getId(),
];
} else {
$status = Laminas::$serviceManager->identity->getLoginInfo($query['id']);
$status['bind_status'] = 1;
$data['id'] = $query['id'];
// 更新用户信息, 头像, 昵称
$data['nickname'] = $user->getNickname();
$data['avatar'] = $user->getAvatar();
Laminas::$serviceManager->adminUser->save($data);
}
// 插入用户状态, 3600秒生存时间, 防止扫完码不取数据一直占用内存
Laminas::$serviceManager->redisExtend->getRedisInstance()->setex(RedisEnum::USER_STATUS . $this->code, 60 * 60 , json_encode($status));
return $status;
}
}

View File

@ -0,0 +1,463 @@
<?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 [];
}
}

View File

@ -0,0 +1,146 @@
<?php
namespace Application\Form\item;
use Application\Form\FieldForm;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Laminas;
class ItemFieldForm extends FieldForm
{
protected string $prefix = 'item';
protected function getForm()
{
return Laminas::$serviceManager->itemForm;
}
protected function getFormField()
{
return Laminas::$serviceManager->itemFormField;
}
protected function getFormVersion()
{
return Laminas::$serviceManager->itemFormVersion;
}
protected function getFormFieldText()
{
return Laminas::$serviceManager->itemFormFieldText;
}
protected function getFormFieldRadio()
{
return Laminas::$serviceManager->itemFormFieldRadio;
}
public function getFieldConfig(string $validatorName = 'ItemFormField')
{
return parent::getFieldConfig($validatorName); // TODO: Change the autogenerated stub
}
protected function getFormRelation()
{
return Laminas::$serviceManager->itemFormRelation;
}
/**
* 验证是否更改了表单属性类型
* @param $value
*/
public function invalidEditType($value)
{
}
public function validMax(&$value)
{
$min = $_POST['min'] ?? '';
if ($value < $min) {
throw new InvalidArgumentException('最大值不能小于最小值');
}
return null;
}
/**
* 创建项目表单字段
* @param array $field
* @return int
*/
public function createField(array $field = [],$type = 0): int
{
if(!$field){
$field = [
'form_id' => $this->validator->attributes['form_id'],
'name' => $this->validator->attributes['name'],
'parent' => $this->validator->attributes['parent'],
'type' => $this->validator->attributes['form_type'] == FormField::FORM_CONFIG_RADIO ? 0 : $this->validator->attributes['type'], // 0 是选项
'is_list' => $this->validator->attributes['is_list'] ?? 0,
'dicform_id' => $this->validator->attributes['dicform_id'] ?? 0,
'order' => $this->validator->attributes['order'],
'rules' => $this->getRules(),
'version' => 'v1.0',
'is_anchor' => $this->validator->attributes['is_anchor'] ?? 0,
'is_booked_time' => $this->validator->attributes['is_booked_time'] ?? 0,
'item_id' => $this->validator->attributes['item_id'],
'var_name' => $this->validator->attributes['var_name'],
'default' => $this->getDefault() ?: '',
'unit' => $this->validator->attributes['unit'] ?? '',
'is_hyperwindow' => call_user_func(function () {
$val = $this->validator->attributes['is_hyperwindow'] ?? 0;
if ($val && !$this->validator->attributes['is_anchor']) {
throw new InvalidArgumentException('必须是基点日期才能设置超窗判断');
}
return $val;
}),
'english' => $this->validator->attributes['english'] ?? '',
'cut_pre' => $this->validator->attributes['cut_pre'] ?? '',
'cut_after' => $this->validator->attributes['cut_after'] ?? '',
'cut_start' => $this->validator->attributes['cut_start'] ?? '',
'cut_length' => $this->validator->attributes['cut_length'] ?? '',
'is_csae' => $this->validator->attributes['is_csae'] ?? 0,
'medical_type' => $this->validator->attributes['medical_type'] ?? '',
'checktime_id' => $this->validator->attributes['checktime_id'] ?? '',
'checkname_id' => $this->validator->attributes['checkname_id'] ?? '',
'form_field_id' => $this->validator->attributes['form_field_id'] ?? '',
'default_field_id' => $this->validator->attributes['default_field_id'] ?? '',
'default_field_type' => $this->validator->attributes['default_field_type'] ?? '',
'is_item_form_source' => $this->validator->attributes['is_item_form_source'] ?? '',
'item_form_source_set' => $this->validator->attributes['item_form_source_set'] ?? '',
'formchecktime_id' => $this->validator->attributes['formchecktime_id'] ?? '',
'is_hide' => $this->validator->attributes['is_hide']?? 0, //是否隐私字段
'is_export' => $this->validator->attributes['is_export']?? 1, //是否导出
'remind_type' => $this->validator->attributes['remind_type']?? 0 //是否导出
];
}else{
$field['parent'] = $field['parent'] ?: 0;
$field['type'] = $field['type'] ?: 0;
$field['is_list'] = $field['is_list'] ?: 0;
$field['is_export'] = $field['is_export'] ?: 1;
$field['is_hide'] = $field['is_hide'] ?: 0;
$field['dicform_id'] = $field['dicform_id'] ?: 0;
$field['order'] = $field['order'] ?: 0;
$field['is_anchor'] = $field['is_anchor'] ?: 0;
$field['is_booked_time'] = $field['is_booked_time'] ?: 0;
$field['version'] = $field['version'] ?: 'v1.0';
$field['form_type'] = $field['form_type'];
}
if($type == 1){
return parent::createField($field,1);
}else{
return parent::createField($field);
}
}
public function getRuleConfig(){
return $this->getRules();
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace Application\Form\item;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Laminas;
class ItemFormModel extends FormForm
{
public function getOutFormPreview($version = 'v1')
{
$method = ($version == 'v1' ? 'getOutForm' : 'getOutFormV2');
$outFormData = Laminas::$serviceManager->itemForm->{$method}($this->validator->attributes['item_id'], $this->validator->attributes['patient_status']);
if (!$outFormData) {
throw new InvalidArgumentException('暂无需填写表单!');
}
$checkTimeId = Laminas::$serviceManager->itemChecktime->getOutCheckTimeId($this->validator->attributes['item_id']);
if ($version == 'v2') {
$res = [];
foreach ($outFormData as $formItem) {
// 是否已经填写
$isWrite = (bool)Laminas::$serviceManager->patientFormContent->fetchOne([
'where' => [
'is_del' => 0,
'patient_id' => $this->validator->attributes['patient_id'],
'form_id' => $formItem['id'],
'checktime_id' => $checkTimeId]
]);
// 完成状态
$isComplete = $isWrite === false ? 0 : $this->getIsComplete($formItem['id'], $checkTimeId);
$res[] = ArrayHelper::merge(Laminas::$serviceManager->itemForm->getPreviewConfig($formItem['id']), [
'type' => $formItem['type'],
'show_type' => $formItem['show_type'] ?: 'right',
'title' => $formItem['name'],
'form_id' => $formItem['id'],
'is_write' => $isWrite,
'is_complete' => intval($isComplete),
// 1 完成 3 未完成 2 未填写
'status_color' => $isWrite === false ? 2 : (intval($isComplete) ? 1 : 3)
]);
}
return $res;
}
return ArrayHelper::merge(
Laminas::$serviceManager->itemForm->getPreviewConfig($outFormData['id']),
[
'type' => $outFormData['type'],
'show_type' => $outFormData['show_type'] ?: 'right',
]
);
}
public function getIsComplete($form_id, $checkTimeId = false)
{
return Laminas::$serviceManager->patientForm->fetchOne([
'where' => [
'form_id' => $form_id,
'patient_id' => $this->validator->attributes['patient_id'],
'is_del' => 0,
'checktime_id' => $checkTimeId ?: $this->validator->attributes['patient_id']
]
])['is_complete'] ?? 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,98 @@
<?php
namespace Application\Form\item\patient;
use Application\Common\EventEnum;
use Application\Service\Extension\ErrorHandler;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
class NormalOCRFormModel extends PatientFormModel
{
/**
*
*
* @param int $annexId
* @param int $params 写1就会一直向一对多的表单内追加数据。跟田老师商量过的
*
* @throws \Exception
*/
public function importMultiRow(int $annexId, int $params = 0)
{
// $trace = [];
// $trace['annexId'] = $annexId;
$query = Laminas::$serviceManager->itemPatientformimgcontent->fetchOne([
'where' => ['annex_id' => $annexId, 'is_del' => 0]
]);
// $trace['query'] = $query;
if (!$query) {
return;
}
$data = StringHelper::jsonDecode($query['table']);
//每笔数据中字段值都无值的话则清除此笔信息
if(!empty($data)){
foreach($data as $dataForm=>$dataFormContents){
$is_have_value = 0;
foreach($dataFormContents as $dataFormContentKey=>$dataFormContentDatas){
$child_is_have_value = 0;
foreach($dataFormContentDatas as $dataFormContentData){
if($dataFormContentData['value'] != ''){
$child_is_have_value = 1;
}
}
//判断此笔数据中是否都有值
if($child_is_have_value == 1){
$is_have_value = 1;
}else{
unset($dataFormContents[$dataFormContentKey]);
unset($data[$dataForm][$dataFormContentKey]);
}
unset($child_is_have_value);
}
if($is_have_value == 0){
unset($data[$dataForm]);
}
unset($is_have_value);
}
}
$query['data'] = $data;
if(!empty($data)){
foreach ($data as $formId => $ocrData) {
$postVal = [
'patient_id' => $query['patient_id'],
'form_id' => $formId,
'checktime_id' => $query['checktime_id'],
'item_id' => $query['item_id'],
'itemsig_id' => $query['itemsig_id'],
'id' => ''
];
if ($params != 1 && SDMHelper::app()->formContent->getMultiTempStorage($query['patient_id'], $query['checktime_id'], $formId)) {
continue;
}
foreach ($ocrData as $formRowData) {
$formData = ArrayHelper::getColumn($formRowData, 'value');
// 选项值转换。如果是单选的多选的 要把文本转换成对应的值
foreach ($formData as $key => &$item) {
if (!is_numeric($key)) {
continue;
}
$item = SDMHelper::app()->form->field->getLabelValue($key, $item);
}
// $trace['postVal'] = ArrayHelper::merge($postVal, $formData);
$this->setPostValues(ArrayHelper::merge($postVal, $formData));
$this->event = EventEnum::EVENT_FORM_CONTENT_TEMP_STORAGE;
$this->tempStorageMulti(false);
}
}
}
// ErrorHandler::log2txt($trace);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,719 @@
<?php
namespace Application\Form\project;
use Application\Common\EventEnumV2;
use Application\Service\DB\Admin\Log;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Form\BaseForm;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\FormContentHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Helper\WsHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Logger\FormContentLogger;
use Application\Service\Extension\Validator\ValidatorApplication;
use Exception;
use Laminas\Db\Sql\Predicate\IsNotNull;
use Laminas\Db\Sql\Where;
use Laminas\Json\Json;
use Laminas\Validator\Exception\InvalidArgumentException;
use Application\Service\DB\Dictionary\Form;
use Zend\Stdlib\ArrayUtils;
class AeForm extends BaseForm
{
private array $relationData = [];
private ?array $aeFormData = [];
private FormContentHelper $logger;
private array $postData = [];
private array $postOriginData = [];
public function __construct(ValidatorApplication $validator = null)
{
parent::__construct($validator);
$this->logger = SDMHelper::app()->log->formContentLog->setContentType(\Application\Service\Extension\Helper\components\FormContentHelper::CONTENT_TYPE_AE);
}
public function getAeForm()
{
if (!$this->aeFormData) {
$this->aeFormData = Laminas::$serviceManager->itemForm->fetchOne([
'where' => [
'item_id' => $this->validator->attributes['item_id'],
'group_id' => FormGroup::AE,
'is_del' => 0
]
]);
}
return $this->aeFormData;
}
public function rollbackToOriginType(int $contentId, int $type, int $csaeId)
{
$csaeData = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
'where' => ['id' => $contentId]
]);
$signId = $csaeData['itemsig_id'];
$itemId = $csaeData['item_id'];
$r = function () use ($csaeId, $signId, $itemId) {
Laminas::$serviceManager->itemCsae->update(['ae_type' => 0, 'is_ae_sure' => 0], ['id' => $csaeId]);
WsHelper::pushAeMessage($itemId, $signId);
};
if ($type == 5) {
$r();
} elseif ($type == 6) {
$r();
}
}
/**
* 是否提交了受试者新增ae
* @return bool
* @throws Exception
*/
private function isPostNewAeForm(): bool
{
$aeFormId = SDMHelper::app()->form->getAeForm($this->validator->attributes['item_id'])['id'];
$config = Laminas::$serviceManager->itemForm->getPreviewConfig($aeFormId);
$forms = ArrayHelper::index($config['form'] ?: [], 'prop');
foreach ($forms as $firstLevelKey => $firstLevel) {
if (!isset($this->validator->attributes[$firstLevelKey])) {
return false;
}
}
return true;
}
public function initFormContentLog() {
$this->logger->setEvent($this->event)->setPostData($this->postData)->setPostOriginData($this->postOriginData);
}
/**
* @throws Exception
*/
public function createNewAeV2()
{
$branchHashString = StringHelper::generateHashValue();
$this->validator->setAttributes([
'form_id' => $this->getAeForm()['id'],
'branch' => $branchHashString,
]);
$this->postData = DataHelper::handleFormData($this->validator->attributes, $this->getAeForm()['id']);
$this->event = EventEnumV2::getVal(EventEnumV2::EVENT_FORM_CONTENT_CREATE);
Db::beginTransaction();
// 初始表单日志信息
$this->initFormContentLog();
if ($this->validator->attributes['ae_type'] == 5 && !$this->validator->attributes['result_id']) {
throw new \Application\Service\Exceptions\InvalidArgumentException('请选择AE名称。');
}
// 受试者新增AE, 属于新增ae - 新增ae数据
if (in_array($this->validator->attributes['ae_type'], [0, 6])) {
if ($this->validator->attributes['ae_type'] == 6 && $this->isPostNewAeForm() === false) {
throw new \Application\Service\Exceptions\InvalidArgumentException('请新增AE表单。');
}
$contentId = Laminas::$serviceManager->itemPatientAeContent->save([
'patient_id' => $this->validator->attributes['patient_id'] ?: $this->getCsae($this->validator->attributes['id'])['patient_id'],
'item_id' => $this->validator->attributes['item_id'],
'itemsig_id' => $this->validator->attributes['itemsig_id'] ?: $this->getCsae($this->validator->attributes['id'])['itemsig_id'],
'data' => json_encode($this->postData),
'is_del' => 0,
'csae_id' => $this->validator->attributes['id'],
'new_ae_list' => 0,
'ae_type' => $this->validator->attributes['ae_type'],
'branch' => $branchHashString,
'form_id' => $this->getAeForm()['id'],
'is_skip' => 0,
'is_complete' => $this->getIsComplete($this->validator->attributes,$this->getAeForm()['id'])
]);
if ($this->validator->attributes['ae_type'] == 6) {
$this->addNewAeRelation($contentId, $branchHashString);
} elseif ($this->validator->attributes['ae_type'] == 0 && $this->validator->attributes['patient_id']) {
$this->addPatientNewAe($contentId, $branchHashString);
}
$this->logger->setContentId($contentId)->flush();
}
Db::commit();
if (!empty($contentId) && in_array($this->validator->attributes['ae_type'], [0, 6])) {
//异步处理访视进度情况信息
$form_content_arr = isset($contentId) && !empty($contentId) ? [$contentId] : [];
Laminas::$serviceManager->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => $this->validator->attributes['item_id'],
'itemsig_id' => $this->validator->attributes['itemsig_id'] ?: $this->getCsae($this->validator->attributes['id'])['itemsig_id'],
'patient_id' => $this->validator->attributes['patient_id'] ?: $this->getCsae($this->validator->attributes['id'])['patient_id'],
'checktime_id' => -1,
'form_id' => $this->getAeForm()['id'],
'operate_type' => 10,
'content_id' => !empty($form_content_arr) ? $form_content_arr : [],
'user_id' => Laminas::$serviceManager->identity->getId()
]
]);
}
unset($form_content_arr);
}
/**
* Notes:AE表单完整性判断
* @param
* @return
* @author haojinhua
* @date 2025-04-07
*/
public function getIsComplete(array $postData,int $formId = null): bool
{
$helper = SDMHelper::app()->setAttributes(['form_id' => $formId])->form;
$versionData = $helper->getVersionData();
$finish_condition = $helper->getFinishCondition($formId);
$skipField = 0;
foreach ($postData as $k => $v) {
$new_key = explode('-', $k)[0];
// 排除掉id等其他参数
if (!isset($versionData[$new_key])) {
$skipField++;
continue;
}
// 对传过来空图片数据做处理
if ($v == '[]') {
$v = '';
} elseif ($v === 'null') {
$v = null;
}
if (is_array($v)) {
// 防止notice错误, 有多维的数组和一维的, 还有空数组
$v = $v ? json_encode($v) : implode(',', $v);
}
if (trim($v)) {
// 表单完成条件为任意一个
if ($finish_condition == Form::FORM_FINISH_CONDITION_ANYONE) {
return true;
}
} else {
$skipField++;
if (!$v) {
return false;
}
}
}
if (count($postData) == $skipField) {
return false;
}
return true;
}
/**
* 新增ae - 新增一条新的数据
* @param int $contentId
* @param $branchHash
*/
private function addNewAeRelation(int $contentId, string $branchHash = '')
{
Laminas::$serviceManager->itemCsaeRelation->insert([
'csae_id' => $this->validator->attributes['id'],
'new_ae_list_id' => 0,
'content_id' => $contentId,
'patient_id' => $this->validator->attributes['patient_id'],
'branch' => $branchHash
]);
}
/**
* ae列表 - 新增受试者ae
* @param int $contentId
*/
private function addPatientNewAe(int $contentId, string $branch)
{
Laminas::$serviceManager->itemCsaeRelation->insert([
'csae_id' => 0,
'new_ae_list_id' => 0,
'content_id' => $contentId,
'patient_id' => $this->validator->attributes['patient_id'],
'branch' => $branch
]);
}
/**
* 编辑 - AE判断结果 - 属于新增ae
* @throws Exception
*/
public function editNewAeV2()
{
$relationData = Laminas::$serviceManager->itemCsaeRelation->fetchOne([
'where' => ['content_id' => $this->validator->attributes['result_id']]
]);
// 修改之前的数据
$oldData = Laminas::$serviceManager->itemPatientAeContent->getOneFieldVal('data',"id = {$this->validator->attributes['result_id']}");
// 补充本次提交的数据,
$this->validator->setAttributes([
'form_id' => $this->getAeForm()['id'],
'branch' => $relationData['branch'] ?? Json::decode($oldData, Json::TYPE_ARRAY)['branch'],
]);
$this->postData = $newData = DataHelper::handleFormData($this->validator->attributes, $this->getAeForm()['id']);
$this->event = EventEnumV2::getVal(EventEnumV2::EVENT_FORM_CONTENT_EDIT);
$this->postOriginData = ArrayUtils::merge($this->postData, [
'old_data_str' => $oldData,
]);
$reason = $this->validator->attributes['reason'];
if(!empty($reason)){
$reason_res = [];
$reason_datas = json_decode($reason,true);
foreach ($reason_datas as $reason_data){
$reason_res[] = [
'filed_id'=>$reason_data['filed_id'],
'modify_reason'=>$reason_data['modify_reason'],
];
}
unset($reason_datas);
$reason = json_encode($reason_res,true);
}
//$this->validator->attributes['note'] = $reason;
unset($this->validator->attributes['reason']);
$this->postData['note'] = $reason;
Db::beginTransaction();
// 初始表单日志
$this->initFormContentLog();
$contentId = $delContentId = 0;
if ($this->validator->attributes['ae_type'] == 5) {
if (!$this->validator->attributes['result_id']) {
throw new \Application\Service\Exceptions\InvalidArgumentException('请选择AE名称。');
}
$contentId = $this->editIsHasAe($relationData,$newData,$oldData);
} elseif ($this->validator->attributes['ae_type'] == 6) {
//已有AE
if ($this->isPostNewAeForm() === false) {
throw new \Application\Service\Exceptions\InvalidArgumentException('请新增AE表单。');
}
$delContentId = $this->validator->attributes['result_id'];
$contentId = Laminas::$serviceManager->itemPatientAeContent->insert([
'data' => json_encode($this->postData),
'patient_id' => $this->validator->attributes['patient_id'],
'item_id' => $this->validator->attributes['item_id'],
'branch' => $relationData['branch'],
'csae_id' => $this->validator->attributes['csae_id'],
'itemsig_id' => $this->validator->attributes['itemsig_id'],
'ae_type' => $this->validator->attributes['ae_type'],
'new_ae_list' => $this->validator->attributes['new_ae_list'] ? 0 : $this->validator->attributes['csae_id'],
'is_skip' => 0,
'form_id' => $this->getAeForm()['id'],
'is_complete' => $this->getIsComplete($this->validator->attributes,$this->getAeForm()['id'])
]);
Laminas::$serviceManager->itemCsaeRelation->update([
'content_id' => $contentId
], ['content_id' => $this->validator->attributes['result_id']]);
Laminas::$serviceManager->itemPatientAeContent->update(['is_del' => 1], [
'id' => $this->validator->attributes['result_id']
]);
Laminas::$serviceManager->itemCsaeChecked->update([
'content_id' => $contentId
], ['content_id' => $this->validator->attributes['result_id']]);
Laminas::$serviceManager->patientFormContentUpdated->changeAeErrorId(
$this->validator->attributes['result_id'],
$contentId,
$this->validator->attributes['patient_id'],
$this->getAeForm()['id'],
$newData,$oldData
);
} elseif ($this->validator->attributes['id'] == 0) {
$delContentId = $this->validator->attributes['result_id'];
//新增AE
$contentId = Laminas::$serviceManager->itemPatientAeContent->insert([
'data' => json_encode(DataHelper::handleFormData($this->validator->attributes, $this->getAeForm()['id'])),
'patient_id' => $this->validator->attributes['patient_id'],
'item_id' => $this->validator->attributes['item_id'],
'csae_id' => $this->validator->attributes['csae_id'],
'branch' => $relationData['branch'],
'itemsig_id' => $this->validator->attributes['itemsig_id'],
'ae_type' => $this->validator->attributes['ae_type'],
'new_ae_list' => $this->validator->attributes['new_ae_list'] ?: $this->validator->attributes['csae_id'],
'is_skip' => 0,
'form_id' => $this->getAeForm()['id'],
'is_complete' => $this->getIsComplete($this->validator->attributes,$this->getAeForm()['id'])
]);
Laminas::$serviceManager->itemPatientAeContent->update([
'is_del' => 1
], ['id' => $this->validator->attributes['result_id']]);
Laminas::$serviceManager->itemCsaeRelation->update([
'content_id' => $contentId
], ['content_id' => $this->validator->attributes['result_id']]);
Laminas::$serviceManager->itemCsaeChecked->update([
'content_id' => $contentId
], ['content_id' => $this->validator->attributes['result_id']]);
Laminas::$serviceManager->patientFormContentUpdated->changeAeErrorId(
$this->validator->attributes['result_id'],
$contentId,
$this->validator->attributes['patient_id'],
$this->getAeForm()['id'],$newData,$oldData
);
//更新SDV、Review
} elseif ($this->validator->attributes['id']) {
$contentId = $this->validator->attributes['id'];
Laminas::$serviceManager->itemPatientAeContent->update([
'data' => json_encode(DataHelper::handleFormData($this->validator->attributes, $this->getAeForm()['id'])),
], ['id' => $this->validator->attributes['id']]);
Laminas::$serviceManager->patientFormContentUpdated->changeAeErrorId(
$this->validator->attributes['id'],
$this->validator->attributes['id'],
$this->validator->attributes['patient_id'],
$this->getAeForm()['id'],$newData,$oldData
);
}
$oldContentId = Laminas::$serviceManager->itemPatientAeContent->getOneFieldVal('id',[
'branch' => $relationData['branch']
]);
$this->logger->setContentId($oldContentId)->flush();
Db::commit();
if(!empty($delContentId) && !empty($contentId)){
Laminas::$serviceManager->projectPatientworkinfo->update(['content_id'=>$contentId],[
'is_del' => 0,
'checktime_id' => -1,
'content_id' => $delContentId,
]);
}
if(!empty($contentId)){
//异步处理访视进度情况信息
$form_content_arr = isset($contentId) && !empty($contentId) ? [$contentId] : [];
Laminas::$serviceManager->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => $this->validator->attributes['item_id'],
'itemsig_id' => $this->validator->attributes['itemsig_id'],
'patient_id' => $this->validator->attributes['patient_id'],
'checktime_id' => -1,
'form_id' => $this->getAeForm()['id'],
'operate_type'=>11,
'content_id'=>!empty($form_content_arr) ? $form_content_arr : [],
'user_id' => Laminas::$serviceManager->identity->getId()
]
]);
unset($form_content_arr);
}
}
public function getIsChangeRelationAeId(): bool
{
$query = Laminas::$serviceManager->itemCsae->fetchOne([
'where' => [
'id' => $this->validator->attributes['id']
]
]);
if ($query['relation_ae_id'] == 0 && !$this->validator->attributes['new_ae_list']) {
return false;
}
if ($query && $query['relation_ae_id'] != $this->validator->attributes['new_ae_list']) {
return true;
}
return false;
}
public function getIsChangeAeResult(): bool
{
if ($this->validator->attributes['id'] == 0) {
return false;
}
$query = Laminas::$serviceManager->itemCsae->fetchOne([
'where' => [
'id' => $this->validator->attributes['id']
]
]);
if ($query && $query['ae_type'] != $this->validator->attributes['ae_type']) {
return true;
}
return false;
}
/**
* 编辑 - 属于已有AE - 重新选择指标项, 或者编辑指标项数据
*/
public function editIsHasAe($relationData,$newData,$oldData): int
{
// 移除旧content
Laminas::$serviceManager->itemPatientAeContent->update(['is_del' => 1], [
'id' => $this->validator->attributes['result_id']
]);
// 插入新content
$contentId = Laminas::$serviceManager->itemPatientAeContent->insert([
'data' => json_encode(DataHelper::handleFormData($this->validator->attributes, $this->getAeForm()['id'])),
'patient_id' => $this->validator->attributes['patient_id'],
'item_id' => $this->validator->attributes['item_id'],
'branch' => $relationData['branch'],
'csae_id' => $this->validator->attributes['csae_id'],
'new_ae_list' => $this->validator->attributes['new_ae_list'],
'itemsig_id' => $this->validator->attributes['itemsig_id'],
'form_id' => $this->getAeForm()['id'],
'ae_type' => $this->validator->attributes['ae_type'],
]);
Laminas::$serviceManager->itemCsaeChecked->update([
'is_del' => 1,
], (new Where())
->equalTo('csae_id', $this->validator->attributes['csae_id'])
->notIn('new_id', [$this->validator->attributes['new_ae_list']]));
Laminas::$serviceManager->itemCsaeChecked->insert([
'csae_id' => $this->validator->attributes['csae_id'],
'new_id' => $this->validator->attributes['new_ae_list'],
'content_id' => $contentId,
'branch' => $relationData['branch']
]);
Laminas::$serviceManager->itemCsaeRelation->update([
'content_id' => $contentId,
'new_ae_list_id' => $this->validator->attributes['new_ae_list']
], ['id' => $relationData['id']]);
Laminas::$serviceManager->itemCsae->update([
'relation_ae_id' => $this->validator->attributes['new_ae_list'],
], ['id' => $this->validator->attributes['csae_id']]);
Laminas::$serviceManager->patientFormContentUpdated->changeAeErrorId(
$this->validator->attributes['result_id'],
$contentId,
$this->validator->attributes['patient_id'],
$this->getAeForm()['id'],$newData,$oldData
);
return (int)$contentId;
}
/**
* 移除所有勾选过的关联ae
*/
public function removeAllCheckedByChangeAeType()
{
}
private function getCsae(int $id)
{
return Laminas::$serviceManager->itemCsae->fetchOne([
'where' => ['id' => $id]
]);
}
/**
* 是否可以删除
*/
private function canDeleteNewAe(int $id)
{
return !(bool)Laminas::$serviceManager->itemCsaeChecked->fetchOne([
'where' => ['new_id' => $id, 'is_del' => 0]
]);
}
/**
* 判断能否修改ae状态
* @return bool
*/
public function canChangeAeResult()
{
$query = Laminas::$serviceManager->itemCsae->fetchOne([
'where' => [
'id' => $this->validator->attributes['id']
]
]);
if ($query && ($query['ae_type'] == 6 && $this->validator->attributes['ae_type'] == 5)) {
throw new \Application\Service\Exceptions\InvalidArgumentException('新增ae不能修改成已有ae');
}
return true;
}
public function rollbackContent()
{
if ($this->validator->attributes['id'] !== null) {
// 新增ae切走, 要把原来的指标删除掉
if ($this->getCsae($this->validator->attributes['id'])['ae_type'] == 6) {
Laminas::$serviceManager->itemCsaeRelation->update(['is_del' => 1], [
'csae_id' => $this->validator->attributes['id']
]);
return;
}
// 所有勾选中的指标
$originCheckedData = Laminas::$serviceManager->itemCsaeChecked->fetchAll([
'where' => ['csae_id' => $this->validator->attributes['id'], 'is_del' => 0, new IsNotNull('branch')]
]);
$rollbackData = [];
foreach ($originCheckedData as $item) {
// 设置skip
Laminas::$serviceManager->itemPatientAeContent->update(['is_skip' => 1, 'is_del' => 1], [
'csae_id' => $this->validator->attributes['id'],
'new_ae_list' => $item['new_id'],
'branch' => $item['branch']
]);
$rollbackData[] = $item;
}
foreach ($rollbackData as $value) {
$lastNode = $this->getLastNode($value['new_id'], $value['branch']);
Laminas::$serviceManager->itemCsaeRelation->update([
'content_id' => $lastNode
], ['csae_id' => $value['new_id'], 'branch' => $value['branch']]);
}
}
}
public function rollbackIsHasAe()
{
// 所有勾选中的指标
$originCheckedData = Laminas::$serviceManager->itemCsaeChecked->fetchOne([
'where' => ['is_del' => 0, 'csae_id' => $this->validator->attributes['csae_id'], 'content_id' => $this->validator->attributes['content_id']]
]) ?: [];
Laminas::$serviceManager->itemCsaeChecked->update([
'is_del' => 1
], ['id' => $originCheckedData['id']]);
if ($_POST['delete_all'] == 1) {
$branch = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
'where' => ['id' => $this->validator->attributes['content_id']]
])['branch'];
Laminas::$serviceManager->itemCsaeRelation->update([
'is_del' => 1
], ['branch' => $branch]);
}
}
protected function getLastNode($csaeId, string $branch)
{
$lastNode = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
'order' => 'id DESC',
'where' => ['new_ae_list' => $csaeId, 'is_skip' => 0, 'branch' => $branch]
])['id'] ?? false;
if (!$lastNode) {
$lastNode = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
'order' => 'id DESC',
'where' => ['csae_id' => $csaeId, 'is_skip' => 0, 'branch' => $branch]
])['id'] ?? false;
}
if (!$lastNode) {
throw new \Application\Service\Exceptions\InvalidArgumentException('没找到要回滚的id');
}
return $lastNode;
}
/**
* 渲染ae表单结构
* @return mixed
* @throws Exception
*/
public function renderNewAeTable($showAll = false)
{
if (!$aeForm = $this->getAeForm()) {
throw new InvalidArgumentException("没有AE表单呀~~");
}
$config = Laminas::$serviceManager->itemForm;
if (isset($_POST['ae_type']) && $_POST['ae_type'] == 2) {
$config->setPreviewScenario('CM_LIST_VIEW');
}
$config = $config->getPreviewConfig($aeForm['id']);
if ($showAll === true) {
$prop = '111-222-333';
$config['table'] = ArrayHelper::merge([['prop' => $prop, 'label' => '受试者编号']], $config['table']);
}
return ArrayHelper::merge($config, [
'type' => "0",
'show_type' => $aeForm['show_type'] ?: 'right',
]);
}
public function view()
{
if ($this->validator->attributes['ae_type'] == 6) {
return Laminas::$serviceManager->itemPatientAeContent->fetchAllWithPagination([
'where' => [
'csae_id' => $this->validator->attributes['csae_id'],
'is_del' => 0
]
]);
}
}
public function delAeLog($id,$data)
{
$this->postData = DataHelper::handleFormData($this->validator->attributes, $this->getAeForm()['id']);
$this->postData['form_id'] = $data['form_id'];
$this->event = EventEnumV2::getVal(EventEnumV2::EVENT_FORM_CONTENT_DELETE);
$this->initFormContentLog();
$this->postOriginData = ArrayUtils::merge($this->postData, [
'old_data_str' => $data,
]);
$this->logger->setContentId($id)->flush();
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Application\Form\project;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\ErrorHandler;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Laminas\Db\Sql\Predicate\Operator;
class LogicAeForm extends AeForm
{
protected int $currentContentId = 0;
// 把已有ae变成受试者ae
public function updateAeType($csaeId)
{
if ($this->validator->attributes['type'] == 6) {
$this->updateToPatientAE($csaeId);
return;
}
// 取消勾选
$originCheckedData = Laminas::$serviceManager->itemCsaeChecked->fetchAll([
'where' => ['is_del' => 0, 'csae_id' => $csaeId]
]) ?: [];
Laminas::$serviceManager->itemCsaeChecked->update([
'is_del' => 1
], ['id' => ArrayHelper::getColumn($originCheckedData, 'id')]);
// 变成未判断
Laminas::$serviceManager->itemCsae->update(['ae_type' => 0, 'is_ae_sure' => 0], ['id' => $csaeId]);
Laminas::$serviceManager->itemCsae->isAnnulChecknameSaveAction($csaeId);
}
protected function updateToPatientAE($csaeId)
{
Laminas::$serviceManager->itemPatientAeContent->update(['csae_id' => 0, 'new_ae_list' => 0, 'ae_type' => 0], ['csae_id' => $csaeId, 'ae_type' => 6]);
Laminas::$serviceManager->itemCsaeRelation->update(['csae_id' => 0, 'new_ae_list_id' => 0], ['csae_id' => $csaeId]);
Laminas::$serviceManager->itemCsaeChecked->update(['new_id' => 0], ['new_id' => $csaeId]);
}
protected function getPrevNode($branch)
{
$content = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
'order' => 'id desc',
'where' => [
'branch' => $branch,
new Operator('id', Operator::OP_LT, $this->currentContentId)
]
]);
if ($content) {
return $content['id'];
}
throw new InvalidArgumentException('获取上一个node失败');
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
*
* @authorllbjj
* @DateTime2024/5/28 23:11
* @Description
*
*/
namespace Application\Listeners;
use Application\Common\Container;
use Laminas\EventManager\EventManagerInterface;
use Psr\Container\ContainerInterface;
class BaseListener extends \Laminas\EventManager\AbstractListenerAggregate
{
private ContainerInterface $container;
public function __construct(Containerinterface $container)
{
$this->container = $container;
}
public function LocalService(): Container
{
return new Container($this->container);
}
public function attach(EventManagerInterface $events, $priority = 1)
{
// TODO: Implement attach() method.
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace Application\Models\logic;
use Application\Service\DB\Db;
use Application\Service\Extension\Event\Event;
use Application\Service\Extension\Logger\BaseLogger;
use Application\Service\Extension\Logger\BasicLogger;
use Exception;
class BaseLogic
{
public ?BaseLogger $logger = null;
private array $_destructCallableList = [];
public function __destruct()
{
foreach ($this->_destructCallableList as $item) {
$item();
}
}
public function beforeExecute()
{
// 自动执行回滚
$this->_destructCallableList[] = fn() => Db::rollback();
}
public function afterExecute()
{
if ($this->logger) {
$this->logger->flush();
}
}
/**
* 使用事务执行给定的方法
*
* @param string $method 要执行的方法名
* @param array $args 传递给方法的参数数组
* @return mixed 执行方法的返回值
*/
public function executeWithTransaction(string $method, array $args = [])
{
// 注册并触发前置事件,以便执行任何需要的前置逻辑
Event::app()->attach('before.logicModel.execute', [$this, 'beforeExecute']);
Event::app()->trigger('before.logicModel.execute');
// 开始数据库事务
Db::beginTransaction();
// 执行指定的方法,并传递参数
$val = $this->{$method}(...$args);
// 提交事务,确保所有数据库操作生效
Db::commit();
// 注册并触发后置事件,以便执行任何需要的后置逻辑
Event::app()->attach('after.logicModel.execute', [$this, 'afterExecute']);
Event::app()->trigger('after.logicModel.execute');
// 返回执行方法的结果
return $val;
}
public function setLogger(BaseLogger $logger): BaseLogic
{
$this->logger = $logger;
return $this;
}
/**
* @return BaseLogger|null|BasicLogger
* @throws Exception
*/
public function getLogger(): ?BaseLogger
{
if ($this->logger === null) {
throw new Exception('没设置logger!!。');
}
return $this->logger;
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace Application\Models\logic\patientForm;
use Application\Models\logic\BaseLogic;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\DB\Item\PatientFormContentUpdatedLog;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\HelperV2\Helper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Params\Params;
class PatientFormLogic extends BaseLogic
{
/**
* 受试者表单 失活/激活
* 默认是激活的
*/
public function inactive()
{
$patientFormId = Helper::app()->patient->getPatientForm(Params::app()->must()->patientId, Params::app()->formId, Params::app()->checkTimeId);
// 是否已经失活了
$isInactive = array_sum(ArrayHelper::getColumn($patientFormId, 'is_inactive')) > 0;
$this->getLogger()->event = $isInactive ? PatientFormContentUpdatedLog::EVENT_PATIENT_FORM_ACTIVE : PatientFormContentUpdatedLog::EVENT_PATIENT_FORM_INACTIVE;
$this->getLogger()->data = json_encode(Params::app()->getValuesToArray());
Laminas::$serviceManager->patientForm->update(['is_inactive' => intval(!$isInactive)], ['id' => ArrayHelper::getColumn($patientFormId, 'id')]);
//异步处理访视进度情况信息
$content_where = [
'is_del' => 0,
'patient_id' => Params::app()->must()->patientId,
'form_id' => Params::app()->formId,
];
if(!in_array(Helper::app()->form->getGroupId(Params::app()->formId),[FormGroup::THROUGH_PROCESS,FormGroup::AE,FormGroup::SAE,FormGroup::TEST_SUMMARY])){
$content_where['checktime_id'] = Params::app()->checkTimeId;
}
$form_content_arr = Laminas::$serviceManager->patientFormContent->fetchCol('id',$content_where);
$form_content_arr = !empty($form_content_arr) ? array_values($form_content_arr) : [];
//更新明细为失活状态
if(!empty($form_content_arr)){
Laminas::$serviceManager->patientFormContent->update(['is_inactive' => intval(!$isInactive)], ['id' => $form_content_arr]);
}
unset($content_where);
Laminas::$serviceManager->swTaskClient->send([
'svName' => 'projectPatientworkbatch',
'methodName' => 'multipleUpdateData',
'params' => [
'item_id' => 0,
'itemsig_id' => 0,
'patient_id' => Params::app()->must()->patientId,
'checktime_id' => Params::app()->must()->checktime_id,
'form_id' => Params::app()->must()->formId,
'operate_type'=>11,
'content_id'=>!empty($form_content_arr) ? $form_content_arr : [],
'user_id' => Laminas::$serviceManager->identity->getId()
]
]);
unset($form_content_arr);
}
}

View File

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Application;
use Application\Service\Extension\Laminas;
use Laminas\Http\Header\SetCookie;
use Laminas\Http\Response;
use Laminas\Mvc\MvcEvent;
class Module
{
/**
* @return array<string,mixed>
*/
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
public function onBootstrap($e)
{
Laminas::initialize($e->getApplication());
// 全局设置响应头
$e->getApplication()->getEventManager()->attach(MvcEvent::EVENT_RENDER, [$this, 'addHeader']);
}
public function addHeader(MvcEvent $e)
{
$response = $e->getResponse();
if ($response instanceof Response) {
$headers = $response->getHeaders();
$responseHeaderConfig = $e->getApplication()->getServiceManager()->get('config')['response'];
foreach(($responseHeaderConfig['header'] ?? []) as $key => $value) {
if ($key == 'Set-Cookie') {
$cookies = $e->getApplication()->getRequest()->getCookie();
if(! empty($cookies)) {
$setCookie = new SetCookie();
foreach ($cookies as $cookieName => $cookieValue) {
$setCookie->setName($cookieName)
->setValue($cookieValue)
->setPath('/')
->setSecure(true)
->setHttpOnly(true);
}
$headers->addHeader($setCookie);
}
}else {
$headers->addHeaderLine($key, $value);
}
}
}
}
}

View File

@ -0,0 +1,355 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 13:23
* @Description
*
*/
namespace Application\Mvc\Controller;
use Application\Common\Container;
use Application\Common\StatusCode;
use Application\Mvc\Controller\Plugins\RenderApiJson;
use Application\Service\Extension\Document\Document;
use Application\Service\Extension\Helper\DocumentHelper;
use Application\Service\Extension\Params\Params;
use Application\Service\Extension\Validator\ValidatorApplication;
use Application\Service\Login\Adapter\AccoutPwd;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\MvcEvent;
use Laminas\Validator\Exception\InvalidArgumentException;
/**
* Class BasicController
* @package Application\Mvc\Controller
* @method Container|mixed LocalService()
* @method RenderApiJson RenderApiJson()
* @property ValidatorApplication $validator
*/
class BasicController extends AbstractActionController
{
public function __get($name)
{
if ($name === 'validator') {
$this->validator = new ValidatorApplication();
return $this->validator;
}
}
public function onDispatch(MvcEvent $e)
{
try {
// 初始化 Params 组件
new Params($this->params()->fromPost());
$rf = new \ReflectionClass($this);
$matchedAction = $e->getRouteMatch()->getParams()['action'];
$documentString = $rf->getMethod("{$matchedAction}Action")->getDocComment();
// 初始化 document 组件
new Document($documentString);
// SDMHelper::app()->log->handleDocument($doc);
DocumentHelper::load($documentString);
} catch (\Throwable $e) {
var_dump($e->getMessage());die;
}
return parent::onDispatch($e);
}
/**
* Notes: 绑定默认的监听事件
* User: llbjj
* DateTime: 2022/5/4 13:40
*
*/
protected function attachDefaultListeners()
{
$event = $this->getEventManager();
// 检测路由的访问方式['POST', 'GET', 'PUT', 'DELETE'], 未设置默认为POST
$event->attach(MvcEvent::EVENT_DISPATCH, [$this, 'checkRouterMethod'], 98);
// 检测用户是否被锁定
$event->attach(MvcEvent::EVENT_DISPATCH, [$this, 'checkLocked'], 100);
// 检测用户登录信息
$event->attach(MvcEvent::EVENT_DISPATCH, [$this, 'checkLogin'], 99);
parent::attachDefaultListeners(); // TODO: Change the autogenerated stub
}
public function checkLocked() {
$redisExtend = $this->LocalService()->redisExtend->setNamespace(AccoutPwd::LOGIN_LOCKED_NAMESPACE);
// 验证IP是否锁定
$ipAddressKey = AccoutPwd::formatRedisKey(AccoutPwd::IP_ADDRESS_KEY, $_SERVER['REMOTE_ADDR']);
if( $redisExtend->getItem($ipAddressKey) ) {
throw new \Application\Service\Exceptions\InvalidArgumentException(
sprintf("您的IP地址已被锁定请%s分钟后重试", call_user_func(function() use (&$redisExtend, &$ipAddressKey) {
$ttl = $redisExtend->getRedisInstance()->ttl(sprintf("%s:%s", AccoutPwd::LOGIN_LOCKED_NAMESPACE, $ipAddressKey)) ?? 0;
return ceil( $ttl / 60 );
})
)
);
}
// 验证账户是否锁定
$loginAccountKey = AccoutPwd::formatRedisKey(AccoutPwd::LOGIN_ACCOUNT_KEY, $this->LocalService()->identity->getMobile());
if( $redisExtend->getItem($loginAccountKey) ) {
throw new \Application\Service\Exceptions\InvalidArgumentException(sprintf("账户已被锁定,请%s分钟后重试!", call_user_func(function() use(&$redisExtend, &$loginAccountKey) {
$ttl = $redisExtend->getRedisInstance()->ttl(sprintf("%s:%s", AccoutPwd::LOGIN_LOCKED_NAMESPACE, $loginAccountKey)) ?? 0;
return ceil( $ttl / 60 );
})));
}
}
/**
* Notes: 检测路由的访问方式
* User: llbjj
* DateTime: 2022/9/6 11:53
*
* @return \Laminas\View\Model\JsonModel|void
*/
function checkRouterMethod() {
$allowMethod = $this->getEvent()->getRouteMatch()->getParam('http_method');
$allowMethod = $allowMethod ?: ['post'];
// 全部转换为小写
foreach($allowMethod as $k => $v) {
$allowMethod[$k] = strtolower($v);
}
if(!in_array(strtolower($this->getRequest()->getMethod()), $allowMethod)) throw new InvalidArgumentException(StatusCode::E_ACCESS['msg']);
}
/**
* Notes: 检测用户是否登录
* User: llbjj
* DateTime: 2022/5/4 13:41
*
* @param MvcEvent $event
*/
function checkLogin(MvcEvent $event){
$headers = $this->getRequest()->getHeaders()->toArray();
if(!isset($headers['Token'])){
$defaultTokenData = $this->LocalService()->config['defaultToken'];
if($defaultTokenData['is_open']) $headers['Token'] = $defaultTokenData['default_token'];
$headersObj = new \Laminas\Http\Headers();
$headersObj->addHeaders($headers);
$this->getRequest()->setHeaders($headersObj);
}
//验证token的有效性
$this->LocalService()->identity->getIdentityData();
}
//获取用户ID
public function GetUserId(){
return $this->LocalService()->identity->getId();
}
/**
* 新增项目时批量添加real角色
* param $itemId 项目id
* param $userId 添加人的id
*/
public function itemRealRoleAction($itemId,$userId){
$time = time();
$sortNum = 10;
$whereArr['where'] = [
'is_del' => 0,
'item_id' => $itemId,
];
$realSortArr = $this->LocalService()->realRole->getAdminRealRoleData($whereArr['where'],3,'sort');
!empty($realSortArr) && $sortNum = max($realSortArr)+10;
//默认角色信息
$itemRealRoles = [
['name'=>'研究医生','code'=>'yjys'],
['name'=>'研究助理','code'=>'yjzl'],
['name'=>'申办者','code'=>'sbz'],
['name'=>'医学','code'=>'yx'],
['name'=>'PM','code'=>'pm'],
['name'=>'CRA','code'=>'cra'],
['name'=>'CRC','code'=>'crc'],
['name'=>'DM','code'=>'dm']
];
//查询real端菜单
$whereMArr['where'] = [
'is_del' => 0,
'menu_type' => 1,
new Operator('parent_id', Operator::OP_GT, 0)
];
$whereMArr['order'] = 'menu_order';
$menuLists = $this->LocalService()->adminMenu->getAdminMenuData($whereMArr,1);
//增加默认角色以及权限
foreach($itemRealRoles as $k=>$itemRealRole){
$v = $itemRealRole['name'];
$role_code = $itemRealRole['code'];
$realRoleArr = [
'status' => 0,
'is_del' => 0,
'update_time' => $time,
'create_time' => $time,
'update_user_id' => $userId,
'create_user_id' => $userId,
'item_id' => $itemId,
'sort' => $sortNum,
'code' => $role_code,
];
$realRoleArr['role_name'] = $v;
if ($k > 1){
$realRoleArr['source_type'] = 1;
}
$sortNum = $sortNum+10;
$realRoleId = $this->LocalService()->realRole->save($realRoleArr);
//新增项目时 默认角色权限
if (!empty($menuLists)){
foreach ($menuLists as $menuList) {
$value = $menuList['id'];
$role_power_arr = !is_null($menuList['role_code_power']) && !empty($menuList['role_code_power']) ? json_decode($menuList['role_code_power'],true) : [];
$role_power = isset($role_power_arr[$role_code]) && !empty($role_power_arr[$role_code]) ? intval($role_power_arr[$role_code]) : 0;
if(!empty($role_power)){
$look_write = 0;
if($role_power == 2){
$look_write = 1;
}
$realRolemodulerelationArr = [
'role_id'=>$realRoleId,
'module_id'=>$value,
'item_id'=>$itemId,
'look_write'=>$look_write
];
$this->LocalService()->realRolemodulerelation->save($realRolemodulerelationArr);
}
}
}
}
return $realRoleId;
}
/**
* 新增项目时批量添加real角色
* param $itemId 项目id
* param $userId 添加人的id
*/
public function OLDitemRealRoleAction($itemId,$userId){
$time = time();
$sortNum = 10;
$whereArr['where'] = [
'is_del' => 0,
'item_id' => $itemId,
];
$realSortArr = $this->LocalService()->realRole->getAdminRealRoleData($whereArr['where'],3,'sort');
!empty($realSortArr) && $sortNum = max($realSortArr)+10;
$itemRealRoleName = ['研究医生','研究助理','PM','CRA','CRC','DM'];
$itemRealRoleCode = ['yjys','yjzl','pm','cra','crc','dm'];
$whereMArr['where'] = ['is_del' => 0, 'menu_type' => 1];
$whereMArr['order'] = 'menu_order';
$menuList = $this->LocalService()->adminMenu->getAdminMenuData($whereMArr,1);
$menuIdArr = [];
if (!empty($menuList)){
$menuIdArr = array_column($menuList,'id');
}
foreach($itemRealRoleName as $k=>$v){
$realRoleArr = [
'status' => 0,
'is_del' => 0,
'update_time' => $time,
'create_time' => $time,
'update_user_id' => $userId,
'create_user_id' => $userId,
'item_id' => $itemId,
'sort' => $sortNum,
'code' => $itemRealRoleCode[$k],
];
$realRoleArr['role_name'] = $v;
if ($k > 1){
$realRoleArr['source_type'] = 1;
}
$sortNum = $sortNum+10;
$realRoleId = $this->LocalService()->realRole->save($realRoleArr);
if (!empty($menuIdArr)){
foreach ($menuIdArr as $key => $value) {
//新增项目时 默认角色没有揭盲、紧急揭盲权限
if($value == 53 || $value == 54) continue;
$realRolemodulerelationArr['role_id'] = $realRoleId;
$realRolemodulerelationArr['module_id'] = $value;
$realRolemodulerelationArr['item_id'] = $itemId;
if(($k < 2) || ($k == 4)){
$realRolemodulerelationArr['look_write'] = 1;
}else{
$realRolemodulerelationArr['look_write'] = 0;
}
$realRolemodulerelationId = $this->LocalService()->realRolemodulerelation->save($realRolemodulerelationArr);
}
}
}
return $realRoleId;
}
//验证
/**
* @param $config
* @throws \Exception
*/
public function Check($config, array $fnParams = [], array $postData = []){
$target = '';
if(strpos($config, '.')){
list($config, $target) = explode('.', $config);
}
$validator= new ValidatorApplication($postData);
$validator->attach(
[[], 'form', 'config' => ucfirst($config), 'target' => $target, 'fnParams' => $fnParams]
// ['form', 'class' => new FormValidator([
// 'config' => ucfirst($config)
// ]), 'target' => $target, 'fnParams' => $fnParams]
);
if(!$validator->isValid()){
throw new InvalidArgumentException($validator->getFirstErrorToString());
}
}
//引入
public function Introduce($formValidator, array $params = []){
$path=APP_PATH.'/formData/';
$fromMap=include $path.'formMap.php';
$fromData=include $path.ucfirst($formValidator).'Data.php';
if (!empty($fromData)){
if(is_callable($fromData)) return $fromData($params);
return $fromData;
}else{
return [];
}
}
//数据返回
public function return_data($code='200',$msg='ok',$data=[],$FormFileData=[],$FormInfo=[]){
exit(
json_encode([
'code'=>$code,
'msg'=>$msg,
'data'=>$data,
'FormFileData'=>$FormFileData,
'FormInfo'=>$FormInfo,
])
);
}
/**
* 获取id
* param $arr 要处理的数据
* param $field 字段
*/
public function GetSelectStr(array $arr,$field){
$field_str='';
foreach ($arr as $k=>$v){
if(!empty($v[$field])){
$field_str.=$v[$field].',';
}
}
$field_str=trim($field_str,',');
return $field_str;
}
}

View File

@ -0,0 +1,43 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 13:26
* @Description
*
*/
namespace Application\Mvc\Controller\Plugins;
use Application\Service\DB\Db;
use Application\Service\DB\Item\PatientFormContentUpdatedLog;
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
use Psr\Container\ContainerInterface;
class LocalService extends AbstractPlugin
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function __get($name)
{
if (Db::isInTransaction()) {
return $this->container->build($name);
}
return $this->container->get($name);
}
/**
* @param string $chainIndex
* @return PatientFormContentUpdatedLog
*/
public function patientFormContentUpdatedLog(string $index = ''): PatientFormContentUpdatedLog
{
return $this->container->build('patientFormContentUpdatedLog', [
'index' => is_numeric($index) ? $index : null
]);
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/4 13:50
* @Description
*
*/
namespace Application\Mvc\Controller\Plugins;
use Application\Service\DB\AbstractDb;
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
use Laminas\View\Model\JsonModel;
use Application\Common\StatusCode;
use Zend\Stdlib\ArrayUtils;
class RenderApiJson extends AbstractPlugin
{
/**
* Notes: 成功
* User: llbjj
* DateTime: 2022/5/5 8:30
*
* @param array $data
* @return JsonModel
*/
public function Success(array $data = [], $message = 'OK', array $extendData = [])
{
return self::renderView(StatusCode::SUCCESS, $message, $data, $extendData);
}
/**
* Notes: 其他提示
* User: llbjj
* DateTime: 2022/5/5 8:30
*
* @param array $defaultStatus
* @param String $msg
* @return JsonModel
*/
public function Error(array $defaultStatus, String $msg = '')
{
return self::renderView($defaultStatus, $msg);
}
/**
* Notes:
* User: llbjj
* DateTime: 2022/5/5 8:30
*
* @param array $defaultStatus
* @param String $msg
* @param array $data
* @return JsonModel
*/
private function renderView(array $defaultStatus, String $msg = '', array $data = [], array $extendData = [])
{
$defaultStatus = $defaultStatus ?? StatusCode::SUCCESS;
$code = $defaultStatus['code'];
$msg = $msg ?: $defaultStatus['msg'];
$result = [
'code' => $code,
'msg' => $msg,
'data' => $data
];
if ($dbProfile = AbstractDb::getDbProfile()) {
$extendData = ArrayUtils::merge($extendData, ['profile' => $dbProfile]);
}
if(!empty($extendData)) $result = ArrayUtils::merge($result, $extendData);
return new JsonModel($result);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Application\Mvc\Controller;
use Application\Common\Container;
use Application\Mvc\Controller\Plugins\RenderApiJson;
use Application\Service\Exceptions\InvalidArgumentException;
use Laminas\Cache\Exception\ExceptionInterface;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\MvcEvent;
/**
* @method Container|mixed LocalService()
* @method RenderApiJson RenderApiJson()
* @method BasicController Introduce()
*/
class ThirdToolController extends AbstractActionController
{
public function attachDefaultListeners()
{
// 验证第三方登录信息
$event = $this->getEventManager();
$event->attach(MvcEvent::EVENT_DISPATCH, [$this, 'checkLogin'], 99);
parent::attachDefaultListeners(); // TODO: Change the autogenerated stub
}
/**
* @throws ExceptionInterface
*/
public function checkLogin(MvcEvent $event) {
$headers = $this->getRequest()->getHeaders()->toArray();
if($this->LocalService()->toolSys->getAccessToken() !== $headers['Token']) {
throw new InvalidArgumentException('授权失败!');
}
}
}

View File

@ -0,0 +1,201 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/9/8 15:18
* @Description
*
*/
namespace Application\SdmWork;
use Application\Service\BaseService;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Item\Listeners\CacheItemSetListener;
use Laminas\Json\Json;
class WorkUser extends BaseService {
/**
* Notes: 获取指定项目下研究医生角色的id值
* User: llbjj
* DateTime: 2022/9/8 15:32
*
* @param int $item_id
* @return \phpDocumentor\Reflection\Types\Mixed|string|void|null
*/
private function getStudyDoctorRole(int $item_id) {
$studyDoctorRoleCode = $this->LocalService()->config['work']['studyDoctorRoleCode'];
return $this->LocalService()->realRole->getOneFieldVal('id', [
'code' => $studyDoctorRoleCode,
'is_del' => 0,
'item_id' => $item_id,
]);
}
function handleRedisList() {
$database = $this->LocalService()->config['caches']['Redis']['adapter']['options']['database'];
$redisExtend = $this->LocalService()->redisExtend->setDatabase($database);
$syncList = [];
for ($i = 0; $i < 20; $i ++ ){
$cacheData = $redisExtend->rPop(CacheItemSetListener::SYNC_QY_WORK_USER);
if ( empty($cacheData) ) break;
$syncList[] = $cacheData;
}
if(!empty($syncList)) {
foreach($syncList as $sync) {
$sync = Json::decode($sync, true);
$this->LocalService()->{$sync['svName']}->{$sync['methodName']}(...array_values($sync['params']));
}
}
}
/**
* Notes: 同步合作方联系人到企业微信( 暂时屏蔽 )
* 暂时先支持研究医生的角色,一个联系人只能再一个中心中担任研究医生
* User: llbjj
* DateTime: 2022/9/8 15:22
*
* @param int $signatoryUserId
*/
function syncUserToWork(int $item_id, int $itemsig_id, int $signatoryUserId) {
return ;
$studyDoctorRole_id = $this->getStudyDoctorRole($item_id);
if(!$studyDoctorRole_id) return ;
$roleSignatoryRelationData = $this->LocalService()->roleSignatoryRelation->fetchOne([
'where' => [
'signatory_user' => $signatoryUserId,
'role_id' => $studyDoctorRole_id,
'item_id' => $item_id,
'item_sign_id' => $itemsig_id,
]
]);
if(!empty($roleSignatoryRelationData)) {
if($roleSignatoryRelationData['is_del']) {
$this->LocalService()->wechatWork->delUser($signatoryUserId);
// 删除用户后,将对应的【联系我】配置删除
$contactWayId = $this->LocalService()->signatoryUser->getOneFieldVal('contact_way_id', [
'id' => $signatoryUserId
]);
if($contactWayId) $this->LocalService()->wechatWork->delContactWay($contactWayId);
} else {
if($roleSignatoryRelationData['status']){
$this->LocalService()->wechatWork->setUserEnable($signatoryUserId, 0);
} else {
self::saveUser($itemsig_id, $signatoryUserId);
}
}
}
}
/**
* Notes: 同步受试者信息到企业微信
*
* DateTime: 2024/4/17 14:07
*
* @param int $item_id
* @param int $itemsig_id
* @param int $patient_id
*/
function syncPatientToWork(int $item_id, int $itemsig_id, int $patient_id) {
$patientData = $this->LocalService()->patient->fetchOne([
'where' => ['is_del' => 0, 'id' => $patient_id, 'item_id' => $item_id, 'itemsig_id' => $itemsig_id],
'columns' => ['patient_number', 'patient_tel']
]);
if(!empty($patientData)) {
if($this->syncDepartmentToWork($itemsig_id)) {
$this->LocalService()->wechatWork->saveUser($patient_id, $patientData['patient_number'], $patientData['patient_tel'], $itemsig_id, 1, 'patient');
}
}
}
/**
* @throws InvalidConfigException
*/
function delDepatrmentFromWork(int $item_id) {
$itemsigIdData = $this->LocalService()->itemSignatory->fetchCol('id', ['item_id' => $item_id]);
if( !empty($itemsigIdData) ) {
foreach($itemsigIdData as $itemsigId) {
$this->LocalService()->wechatWork->delDepartment($itemsigId, 'itemsig');
}
}
$this->LocalService()->wechatWork->delDepartment($item_id);
}
/**
* Notes: 新增/更新用户
* User: llbjj
* DateTime: 2022/9/8 16:10
*
* @param int $itemsigId
* @param int $signatoryUserId
*/
private function saveUser(int $itemsigId, int $signatoryUserId) {
$signatoryUserData = $this->LocalService()->signatoryUser->fetchOne([
'where' => [
'is_del' => 0,
'status' => 0,
'id' => $signatoryUserId,
],
'colomns' => ['id', 'user_name', 'user_tel']
]);
if(!empty($signatoryUserData)) {
// 新增用户之前,要保证部门都存在
if(self::syncDepartmentToWork($itemsigId)) {
// saveUser 返回是用户是否存在,也就同步用户是新增还是更新,存在则表示的是更新
$isUp = $this->LocalService()->wechatWork->saveUser($signatoryUserId, $signatoryUserData['user_name'], $signatoryUserData['user_tel'], $itemsigId);
if(!$isUp) {
// 自动创建【联系我】
$result = $this->LocalService()->wechatWork->addContactWay($signatoryUserId);
//将 【联系我】 的信息存入数据库中
$this->LocalService()->signatoryUser->update([
'contact_way_qrcode' => $result['qr_code'],
'contact_way_id' => $result['config_id']
], "id = {$signatoryUserId}");
}
}
}
}
/**
* Notes: 同步部门信息
* User: llbjj
* DateTime: 2022/9/8 16:27
*
* @param int $itemsigID
* @return false|void
*/
private function syncDepartmentToWork(int $itemsigID) {
$itemsigData = $this->LocalService()->itemSignatory->fetchOne([
'where' => [
'id' => $itemsigID,
'is_del' => 0,
],
'columns' => ['id', 'item_id', 'signatory_id']
]);
if(empty($itemsigData)) return false;
$itemName = $this->LocalService()->itemInfo->getOneFieldVal('name', [
'id' => $itemsigData['item_id'],
'is_del' => 0
]);
if($itemName == '') return false;
$this->LocalService()->wechatWork->saveDepartment($itemsigData['item_id'], $itemName);
// 创建中心
$signatoryName = $this->LocalService()->signatoryInfo->getOneFieldVal('info_name', [
'id' => $itemsigData['signatory_id'],
'is_del' => 0
]);
if($signatoryName == '') return false;
$this->LocalService()->wechatWork->saveDepartment($itemsigID, $signatoryName, 'itemsig', $itemsigData['item_id']);
return true;
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* @authorllbjj
* @DateTime2023/4/28 15:11
* @Description
*/
return [
'doubleCols' => [
'代号',
'项目名称',
'中文名称',
'编码',
'代码',
'序',
'英文',
'检验项目',
'检验项目名称',
'范围',
'取值范围',
'取值区间',
'参考范围',
'参考区间',
'正常范围',
'参考值',
],
'ocrHeader' => [
'unit' => '单位',
'item_name' => '项目名称',
'range' => '参考区间',
'result' => '结果',
'code' => '项目代号'
],
];

View File

@ -0,0 +1,196 @@
<?php
/**
*
* @authorllbjj
* @DateTime2023/4/11 10:34
* @Description
*
*/
namespace Application\Service\Baidu;
use Application\Common\Com;
use Application\Service\BaseService;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Uploader\adapter\Oss;
use Gumlet\ImageResizeException;
use Laminas\Stdlib\ArrayUtils;
use Psr\Container\ContainerInterface;
/**
*
* Class Ocr
* @package Application\Service\Baidu
*
* @property $ocrClient
*/
class Ocr extends BaseService
{
protected OcrClient $ocrClient;
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
$this->_initOcr();
}
private function _getFileContent($data) :string
{
$imageFile = $data['annex_path'] ?? '';
$bucket = $data['bucket'] ?? 'etracing';
$style = $data['style'] ?? 'ocr';
$fileUpLoader = new Oss(Laminas::$app->getConfig()['image_uploader'], $bucket);
// style => ['iphone' => 最不清楚的, 'sample' => 还挺清楚的, 'origin' => 原图, 'thumb' => 高度为100的缩略图]
$imageFile = $fileUpLoader->getSignUrl($imageFile, $style);
[$imageContent] = file_get_contents($imageFile);
return $imageContent;
}
/**
* Notes:
* User: llbjj
* DateTime: 2023/8/14 13:28
*
* @param $data
* @return array
*/
public function basicGeneral($data) : array
{
$imageContent = self::_getFileContent($data);
$ocrApi = 'basicGeneral';
$ocrResult = $this->ocrClient->{$ocrApi}($imageContent, [
'detect_direction' => "true" // 检测图片朝向
]);
if(!isset($ocrResult['words_result'])) return [];
if(empty($ocrResult['words_result'])) return [];
return ['table' => array_column($ocrResult['words_result'], 'words')];
}
public function medicalReport(array $data): array
{
$imageContent = self::_getFileContent($data);
$ocrResult = $this->ocrClient->medicalReport($imageContent);
if(empty($ocrResult)) return [];
if(!$ocrResult['Item_row_num']) return [];
$date = array_flip(array_intersect(array_column($ocrResult['words_result']['CommonData'], 'word_name'), ['时间']));
$dateKey = $date['时间'];
$date = $ocrResult['words_result']['CommonData'][$dateKey]['word'];
return $this->_formatMedicalReportResult($ocrResult['words_result']['Item'], $date);
}
/**
* Notes: 自定义OCR识别
* User: llbjj
* DateTime: 2023/5/5 14:47
*
* @param array $data
* @return array
* @throws ImageResizeException
* @throws UserException
*/
public function custom(array $data): array
{
$templateId = $data['templateId'] ?? 0;
$classifierId = $data['classifierId'] ?? 0;
$imageContent = self::_getFileContent($data);
if($templateId) {
$ocrOptions = [
'templateSign' => $templateId
];
}else {
if(!$classifierId) {
return [];
}
$ocrOptions = [
'classifierId' => $classifierId
];
}
$ocrResult = $this->ocrClient->custom($imageContent, $ocrOptions);
if($ocrResult['error_code']) return [];
return $ocrResult['data']['ret'] ? $this->_formatOcrCustomWordsResult($ocrResult['data']['ret']) : [];
}
private function _formatMedicalReportResult(array $ocrDatas, string $date = ''): array
{
$result['table'] = [];
if(empty($ocrDatas)) return $result;
$ocrHeader = (include __DIR__ . '/Config/Config.php')['ocrHeader'];
$_ocrHeader = array_flip($ocrHeader);
foreach($ocrDatas AS &$ocrData) {
$word_name_arr = array_column($ocrData, 'word_name');
$word_name_arr = array_intersect($word_name_arr, $ocrHeader);
$_result = [
'date' => $date
];
foreach($word_name_arr as $key => $val) {
if($val === '项目名称') $_result[$_ocrHeader[$val]] .= $ocrData[$key]['word'];
else if($val === '项目代号') $_result[$_ocrHeader['项目名称']] = $ocrData[$key]['word'];
else $_result[$_ocrHeader[$val]] = $ocrData[$key]['word'];
}
$result['table'][] = $_result;
}
return $result;
}
private function _formatOcrCustomWordsResult(array $ocrDatas, Bool $isMedicalTable = false): array
{
$result = [];
$_result = [];
if(empty($ocrDatas)) return $result;
foreach($ocrDatas as &$ocrData) {
$arrKey = $ocrData['word_name'];
$arrKeyArr = explode('#', $arrKey);
if(count($arrKeyArr) === 1) $_result[$arrKey] = $ocrData['word'];
else {
$row = $arrKeyArr[1];
$key = $arrKeyArr[2];
if(mb_strpos($arrKeyArr[2], '-1') !== false) {
$row = 100 + $row;
$key = mb_substr($arrKeyArr[2], 0, -2);
}
if($key === 'other' and !$isMedicalTable) continue;
if(in_array($key, ['item_name'])) {
$preg = '/[0-9]*/';
$ocrData['word'] = preg_replace($preg, '', $ocrData['word'], 1);
}
$ocrData['word'] = str_ireplace(' ', '', $ocrData['word']);
$result[$arrKeyArr[0]][$row][$key] = $ocrData['word'];
if(!empty(array_filter(array_values($result[$arrKeyArr[0]][$row])))) {
$result[$arrKeyArr[0]][$row] = ArrayUtils::merge($result[$arrKeyArr[0]][$row], $_result);
}else {
unset($result[$arrKeyArr[0]][$row]);
}
}
}
if(!empty($result['table'])) ksort($result['table']);
return $result;
}
private function _initOcr() {
$baiduConfig = $this->LocalService()->config['baidu'];
$this->ocrClient = new OcrClient($baiduConfig['app_id'], $baiduConfig['api_key'], $baiduConfig['aecret_key']);
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* @authorllbjj
* @DateTime2023/5/9 11:56
* @Description
*
* Class OcrClient
*/
declare(strict_types=1);
namespace Application\Service\Baidu;
use AipOcr;
use function array_merge;
use function base64_encode;
class OcrClient extends AipOcr
{
private string $tableV2Url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/table';
private string $medicalReportDetectionUrl = 'https://aip.baidubce.com/rest/2.0/ocr/v1/medical_report_detection';
/**
* tableV2识别
*
* @param string $imageContent
* @param array $options - 可选参数对象key: value都为string类型
* @return array
* @description options列表:
*/
public function customOcrTableV2(string $imageContent, array $options = []): array
{
$data = [];
$data['image'] = base64_encode($imageContent);
$data = array_merge($data, $options);
return $this->request($this->tableV2Url, $data);
}
/**
* Notes: 通用医疗化验单
*
* @param string $imageContent - string $image - 图像数据base64编码要求base64编码后大小不超过4M最短边至少15px最长边最大4096px,支持jpg/png/bmp格式
* @param array $options - 可选参数对象key: value都为string类型
* @return array
*/
public function medicalReport(string $imageContent, array $options = []): array
{
$data = [];
$data['image'] = base64_encode($imageContent);
$data = array_merge($data, $options);
return $this->request($this->medicalReportDetectionUrl, $data);
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
*
* @authorllbjj
* @DateTime2022/5/7 21:19
* @Description
*
*/
namespace Application\Service;
use Application\Common\Container;
use Interop\Container\ContainerInterface;
class BaseService
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function LocalService(){
return new Container($this->container);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Appletsmenu extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_applets_menu';
parent::__construct($dbAdapter, $container);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Appletsrolemenurelation extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_applets_rolemenurelation';
parent::__construct($dbAdapter, $container);
}
/**
*保存小程序平台功能默认分配
*
*/
public function addappletsMenu($item_id){
//查询小程序功能列表
$adminAppletsmenuDatas = $this->LocalService()->adminAppletsmenu->fetchCol('id','is_del=0 and status = 0');
if(!empty($adminAppletsmenuDatas)){
foreach($adminAppletsmenuDatas as $key=>$val){
$menuData['item_id'] = $item_id;
$menuData['menu_id'] = $val;
$menuData['status'] = 0;
$this->LocalService()->adminAppletsrolemenurelation->insert($menuData);//新增
}
}
}
}

View File

@ -0,0 +1,381 @@
<?php
namespace Application\Service\DB\Admin;
use Application\Command\Swoole\Server\WebSocketCommand;
use Application\Service\Extension\ErrorHandler;
use Interop\Container\ContainerInterface;
use Swoole\Coroutine\Http\Client;
use Laminas\Db\TableGateway\TableGateway;
use function Co\run;
use Application\Common\Enum;
use Laminas\Db\Sql\Predicate\Like;
class Configtable extends \Application\Service\DB\AbstractDb
{
private $item_id;
private $senddata;
private $sqldata;
private $sqlcount;
private $site_item;
private $hash;
private $Adapter;
private $table_name = ['yikeen_item_csae_checked','yikeen_item_csae_relation','yikeen_item_file','yikeen_item_form_field_radio','yikeen_item_form_field_text','yikeen_item_form_group','yikeen_item_form_relation','yikeen_item_form_version','yikeen_item_identificationresult','yikeen_item_patient_form_unlock','yikeen_item_reply','yikeen_item_superrole','yikeen_signatory_user','yikeen_signatory_info','yikeen_admin_user','yikeen_dictionary_form_group'];
private $unisdelTable = ['yikeen_item_centerdata','yikeen_item_form_field_radio','yikeen_item_form_field_text','yikeen_item_form_version','yikeen_item_informedconsent_sign','yikeen_item_jobstaff'];
private $realrole;
private $sqldata_number = 1;
private $type;
//是否是第一次传输 0 第一次 1非第一次
private $is_send = 0;
//第二次传输 含有表单的表数组
private $formTableName = ['yikeen_item_patient_form','yikeen_item_patient_form_content','yikeen_item_patient_ae_content'];
//必填字段数组
private $Fieldrequired;
//必填字段未填写数组
private $Requiredfilled;
private $lockdata;
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_config_tablename';
parent::__construct($dbAdapter, $container);
}
private function _getWhere($type,$table_name)
{
$where['where'] = "1=1";
//是否有项目id字段并且判断大小项目
if(!in_array($table_name,$this->table_name)){
if($table_name == 'yikeen_item_info'){
$where['where'] = "id = $this->item_id or fid = $this->item_id";
}else{
if($type == 1){
$where['where'] = "item_id = ".$this->item_id;
}else{
$where['where'] = "item_id in "."($this->site_item)";
}
}
}
//是否有is_del字段
if(!in_array($table_name,$this->unisdelTable)){
$where['where'] .= " and is_del = 0";
}
$where['order'] = "id";
return $where;
}
//查询项目数据,进行项目发送
public function handleData($data)
{
$item_id = $data['item_id'];
$hash = $data['hash'];
$this->type = $data['type'];
//是否删除、大表分批处理
//大项目
$this->item_id = $item_id;
//hash值
$this->hash = $hash;
//小项目
$itemidArr = $this->LocalService()->itemInfo->fetchCol('id','is_del = 0 and fid = '.$item_id);//获取项目名称
$this->site_item = implode(',',$itemidArr);
// $this->site_item = 2236;
//查询EDC锁定的数据
$itemidArr = $this->LocalService()->EdcLock->fetchAll(['where'=>"is_del = 0 and item_id in ($this->site_item)",'columns'=>['checktime_id','form_id','patient_id']]);//获取项目名称
if(!empty($itemidArr)){
$lockdata = [];
foreach($itemidArr as $k=>$v){
$lockdata[$v['patient_id'].'-'.$v['checktime_id'].'-'.$v['form_id']] = 1;
}
$this->lockdata = $lockdata;
}
if($this->type == 1){
$tableWhere['where'] = "id = 61";
}else{
$tableWhere['where'] = "is_del = 0 and is_sync = 0";
}
$tableWhere['columns'] = ['id','table_name','table_name_db','table_type'];
$tableDatas = $this->fetchAll($tableWhere);
$this->createdir(APP_PATH . '/data/senddata'); //创建数据文件夹
$this->createdir(APP_PATH . '/data/sendsql'); //创建sql文件夹
//创建本次传输文件夹
$datapath = APP_PATH . '/data/senddata/'.$this->hash;
$sqlpath = APP_PATH . '/data/sendsql/'.$this->hash;
$this->createdir($datapath);
$this->createdir($sqlpath);
//=========================
//查询是否是第一次传输
// $senddata = $this->LocalService()->Send->fetchone(['where'=>"item_id = $this->item_id",'columns'=>['id']]);
// if(!empty($senddata))$this->is_send =1;
//=========================
// $this->formfieldrequireddata($this->site_item);
foreach($tableDatas as $k=>$v){
// if(!in_array($v['id'],[123])) continue;
//查询本库数据
$this->sdmData($v);
}
}
public function createdir($path)
{
if(file_exists($path) == false)
{
mkdir($path, 0777, true);
chmod($path,0777);
}
return true;
}
/**
* Notes :处理数据
* @param $arr
* @return bool
* Author:唐伯虎不虎
* Date:2023/3/29 11:49
*/
public function sdmData($arr)
{
set_time_limit(0);
if(empty($arr['table_name_db'])) return false;
$table = $arr['table_name_db'];
$where = $this->_getWhere($arr['table_type'],$arr['table_name']);
if($arr['table_name'] == 'yikeen_item_patient_form_content_updated'){
//查询上次同步时间
$sendWhere['where'] = "table_id = 123 and ";
$sendWhere['group'] = ['table_id'];
$sendWhere['order'] = ['id'];
$sendWhere['columns'] = ['create_time'];
$end_time = $this->LocalService()->Send->fetchOne($sendWhere);
if(!empty($end_time)){
$where['where'] .= " and create_time > ".$end_time['create_time'];
}
}
if($arr['table_name'] == 'yikeen_real_rolesignatoryrelation'){
$where['where'] .= " and role_id in (".implode(',',$this->realrole).")";
}
//====================
if($this->is_send == 1 && in_array($arr['table_name'],$this->formTableName)){
$where['where'] .= " and is_lock = 1";
}
//====================
$count = $this->LocalService()->$table->getCount($where['where']);
if(empty($count)){
$sendarr['table_id'] = $arr['id'];
$sendarr['batch'] = $this->hash;
$sendarr['send_type'] = 0;
$sendarr['item_id'] = $this->item_id;
$this->LocalService()->Send->save($sendarr);
return false;
}
$page = ceil($count / 5000);
$data = $this->yieldDbData($page, $where,$table,$arr);
$sqlData = '';
//删除当前项目所有数据
if(!in_array($arr['table_name'],$this->table_name)){
if($arr['table_name'] == 'yikeen_item_info'){
$this->sqldata .= 'DELETE FROM '.$arr['table_name'].' WHERE id = '.$this->item_id.' or id in ('.$this->site_item.')'.';'."\r\n";
}else{
if($arr['table_type'] == 1){
$this->sqldata .= 'DELETE FROM '.$arr['table_name'].' WHERE item_id = '.$this->item_id.';'."\r\n";
}else{
$this->sqldata .= 'DELETE FROM '.$arr['table_name'].' WHERE item_id in ('.$this->site_item.');'."\r\n";
}
}
}else{
$this->sqldata .= 'DELETE FROM '.$arr['table_name'].' WHERE id > 0;'."\r\n";
}
$attrDatas = [];
if($arr['table_name'] == 'yikeen_item_patient'){
//查询受试者拓展属性---隐私属性
$attrDatas = $this->LocalService()->patientattrs->fetchCol('id',"item_id in (".$this->site_item.") and is_del = 0 and is_hide = 1");
}
foreach($data as $k=> $value){
foreach($value as $kk=>$vv){
//锁定数据不进行转移 $this->lockdata
if($arr['table_name'] == 'yikeen_item_patient_form' || $arr['table_name'] == 'yikeen_item_patient_form_content' || $arr['table_name'] == 'yikeen_item_patient_ae_content'){
if(empty($vv['checktime_id'])) $vv['checktime_id'] = 0;
if(isset($this->lockdata[$vv['patient_id'].'-'.$vv['checktime_id'].'-'.$vv['form_id']])) continue;
}
if($arr['table_name'] == 'yikeen_real_role'){
$this->realrole[] = $vv['id'];
}
//虚拟键删除字段
if($arr['table_name'] == 'yikeen_item_patient')unset($vv['patient_number_name']);
if($arr['table_name'] == 'yikeen_item_info')unset($vv['item_number_name']);
if($arr['table_name'] == 'yikeen_item_patient' && !empty($attrDatas)){
$patient_content = json_decode($vv['patient_content'],true);
foreach($patient_content as $contentK =>$contentV){
if(in_array($contentV['id'],$attrDatas)){
if($contentV['field'] == 'number') $vv['patient_number'] = '';
if($contentV['field'] == 'name') $vv['patient_name'] = '';
if($contentV['field'] == 'sex') $vv['patient_sex'] = '';
if($contentV['field'] == 'ns') $vv['patient_name_easy'] = '';
unset($patient_content[$contentK]);
}
}
$vv['patient_content'] = json_encode($patient_content,true);
}
//json转移
if($arr['table_name'] == 'yikeen_patient_checktime_list'){
$vv['item_checktime_list'] = trim(json_encode($vv['item_checktime_list'],true),'"');
}
if($arr['table_name'] == 'yikeen_item_form_version'){
$vv['field'] = trim(json_encode($vv['field'],true),'"');
}
if($arr['table_name'] == 'yikeen_item_patient_form_content'){
$vv['data'] = trim(json_encode($vv['data'],true),'"');
}
if($k == 0){
$field = '`'.implode('`,`',array_keys($vv)).'`';
}
$values = "'".implode("','",array_values($vv))."'";
$this->sqldata.= 'INSERT INTO '.$arr['table_name'].' ('.$field.') VALUES('.$values.')'.';'."\r\n";
$value[$vv['id']] = $vv;
unset($value[$kk]);
}
$this->sqlcount += count($value);
file_put_contents(APP_PATH.'/data/senddata/'."$this->hash".'/'.$arr['table_name'].$k.'.txt',json_encode($value),FILE_USE_INCLUDE_PATH);
}
if($this->sqlcount >= 10000){
if($this->type == 1) $this->sqldata_number += 100;
file_put_contents(APP_PATH.'/data/sendsql/'."$this->hash".'/'.$this->sqldata_number.'.sql',$this->sqldata,FILE_USE_INCLUDE_PATH);
$this->sqldata = '';
$this->sqlcount = 0;
$this->sqldata_number += 1;
}elseif($arr['table_name'] == 'yikeen_signatory_user'){
file_put_contents(APP_PATH.'/data/sendsql/'."$this->hash".'/'.$this->sqldata_number.'.sql',$this->sqldata,FILE_USE_INCLUDE_PATH);
}
elseif($arr['table_name'] == 'yikeen_item_identificationresultchange'){
if($this->type == 1) $this->sqldata_number += 100;
file_put_contents(APP_PATH.'/data/sendsql/'."$this->hash".'/'.$this->sqldata_number.'.sql',$this->sqldata,FILE_USE_INCLUDE_PATH);
}
unset($data);
unset($sqlData);
//添加记录
$sendarr['table_id'] = $arr['id'];
$sendarr['batch'] = $this->hash;
$sendarr['send_type'] = 1;
$sendarr['item_id'] = $this->item_id;
$this->LocalService()->Send->save($sendarr);
return true;
}
/*
* 通过yield从数据库中分批取出数据也是为了防止数据量过大一次性抓取数据导致内存溢出的情况
*/
public function yieldDbData($page, $syslogWhere,$table,$arr){
$limit = 5000;
for($i = 1; $i <= $page; $i++){
$offset = ($i - 1) * $limit;
$syslogWhere['limit'] = $limit;
$syslogWhere['offset'] = $offset;
$tableData = $this->LocalService()->$table->fetchAll($syslogWhere);
yield $tableData;
}
}
/**
* Notes : 贯穿全程表单实时传输
* Author:唐伯虎不虎
* Date:2023/4/24 15:17
*/
public function runthroughForm(int $patientform_id,int $patientformcontent_id,bool $is_ae = false,$adapter)
{
$yikeen_item_patient_form = new TableGateway('yikeen_item_patient_form', $adapter);
$yikeen_item_patient_form_content = new TableGateway('yikeen_item_patient_form_content', $adapter);
$patientform_id = 197930;
$patientformcontent_id = 196529;
//查询数据
$patientformArr = $this->LocalService()->patientForm->fetchOne(['where'=>"id = $patientform_id"]);
$patientformcontentArr = $this->LocalService()->patientFormContent->fetchOne(['where'=>"id = $patientformcontent_id"]);
//处理受试者填写表单记录表
$is_patientform = $yikeen_item_patient_form->select(["id" => $patientform_id])->current();
if($is_patientform){
//修改
$yikeen_item_patient_form->update($patientformArr);
}else{
//添加
$yikeen_item_patient_form->insert($patientformArr);
}
//处理受试者表单数据表
$is_patientform = $patientformcontentArr->select(["id" => $patientformcontent_id])->current();
if($is_patientform){
//修改
$patientformcontentArr->update($patientformArr);
}else{
//添加
$patientformcontentArr->insert($patientformArr);
}
}
/**
* 表单字段必填数据处理
* 如果字段必填,受试者表单填写、则记录数据、如果表单没有填写则不记录
*/
public function formfieldrequireddata($site_item)
{
$site_item = explode(',',$site_item);
//查询当前项目所有必填字段
$fieldrequiredWhere['where'] = "is_del = 0 and item_id in (".$site_item.") and rules like '".'%"v-required";s:1:"1"%'."'";
$fieldrequiredWhere['columns'] = ['id','signatory_id','varname'];
$fieldrequireddatas = $this->LocalService()->itemFormField->fetchAll(['where'=>[
'item_id' => $site_item,
new Like('rules', '%"v-required";s:1:"1"%')
],'columns'=>['id','name','form_id','item_id']]);
if(!empty($fieldrequireddatas)){
foreach($fieldrequireddatas as $k=>$v){
$this->Fieldrequired[$v['item_id'].'-'.$v['form_id']][] = $v['id'];
}
}else{
return false;
}
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Log extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->is_update_info = 0;
$this->is_create_info = 0;
$this->tableName = 'yikeen_admin_log';
parent::__construct($dbAdapter, $container);
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Predicate\NotIn;
class Medicallock extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_medicallock';
parent::__construct($dbAdapter, $container);
}
/**
* Notes: 添加新药物
* User: llbjj
* DateTime: 2023/6/9 13:54
*
* @param array $params
*/
public function addMedicalData(array $params) {
$item_id = isset($params['item_id']) && !empty($params['item_id']) ? $params['item_id'] : 0;
$itemsig_id = isset($params['itemsig_id']) && !empty($params['itemsig_id']) ? $params['itemsig_id'] : 0;
$patient_id = isset($params['patient_id']) && !empty($params['patient_id']) ? $params['patient_id'] : 0;
$form_id = isset($params['form_id']) && !empty($params['form_id']) ? $params['form_id'] : 0;
$checktime_id = isset($params['checktime_id']) && !empty($params['checktime_id']) ? $params['checktime_id'] : 0;
$annex_id = isset($params['annex_id']) && !empty($params['annex_id']) ? $params['annex_id'] : 0;
$table_id = isset($params['table_id']) && !empty($params['table_id']) ? $params['table_id'] : 0;
$info_type = isset($params['info_type']) && !empty($params['info_type']) ? $params['info_type'] : 0;
$save_id_arr = isset($params['save_id_arr']) && !empty($params['save_id_arr']) ? $params['save_id_arr'] : [];
$lock_user = isset($params['lock_user']) && !empty($params['lock_user']) ? $params['lock_user'] : 0;
$lock_time = time();
if(!empty($annex_id)){
//删除已删除的数据
$delete_where = [
'is_del' => 0,
'annex_id' => $annex_id,
];
if(!empty($save_id_arr)){
$delete_where[] = new NotIn('info_Id', $save_id_arr);
}
$this->update(['is_del'=>1],$delete_where);
unset($delete_where);
//更新保存数据信息
if(!empty($save_id_arr)){
//获取已保存的数据
$old_save_arr = $this->fetchCol('info_id',[
'is_del' => 0,
'annex_id' => $annex_id,
]);
foreach($save_id_arr as $save_id){
if(!in_array($save_id,$old_save_arr)){
$saveData = [
'table_id'=>$table_id,
'info_type'=>$info_type,
'info_id'=>$save_id,
'item_id'=>$item_id,
'itemsig_id'=>$itemsig_id,
'patient_id'=>$patient_id,
'form_id'=>$form_id,
'checktime_id'=>$checktime_id,
'annex_id'=>$annex_id,
'is_lock'=>1,
'create_user_id'=>$lock_user,
'create_time'=>$lock_time
];
$this->isSetInfo(false)->save($saveData);
unset($saveData);
}
}
}
}
//释放空间
unset($item_id);
unset($itemsig_id);
unset($patient_id);
unset($form_id);
unset($checktime_id);
unset($annex_id);
unset($info_type);
unset($save_id_arr);
unset($lock_user);
unset($lock_time);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Menu extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_menu';
parent::__construct($dbAdapter, $container);
}
public function getAdminMenuData($whereData=[],$type = 0,$field=''){
$data = [];
switch ($type){
case 1:
$data = $this->LocalService()->adminMenu->fetchAll($whereData);
break;
case 2:
$data = $this->LocalService()->adminMenu->fetchOne($whereData);
break;
case 3:
$data = $this->LocalService()->adminMenu->fetchCol($field,$whereData);
break;
default:
$data['data'] = $this->LocalService()->adminMenu->fetchAll($whereData);
$data['count'] = $this->LocalService()->adminMenu->getCount($whereData['where']);
break;
}
return $data ;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class MenuEdc extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_menu';
parent::__construct($dbAdapter, $container);
}
public function getAdminMenuData($whereData=[],$type = 0,$field=''){
$data = [];
switch ($type){
case 1:
$data = $this->LocalService()->adminMenuEdc->fetchAll($whereData);
break;
case 2:
$data = $this->LocalService()->adminMenuEdc->fetchOne($whereData);
break;
case 3:
$data = $this->LocalService()->adminMenuEdc->fetchCol($field,$whereData);
break;
default:
$data['data'] = $this->LocalService()->adminMenuEdc->fetchAll($whereData);
$data['count'] = $this->LocalService()->adminMenuEdc->getCount($whereData['where']);
break;
}
return $data ;
}
}

View File

@ -0,0 +1,610 @@
<?php
namespace Application\Service\DB\Admin;
use Application\Service\Extension\Laminas;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Predicate\NotIn;
use Laminas\Db\Sql\Where;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Stdlib\ArrayUtils;
class Realrole extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_real_role';
parent::__construct($dbAdapter, $container);
}
public function getAdminRealRoleData($whereData=[],$type = 0,$field=''){
$data = [];
switch ($type){
case 1:
$data = $this->LocalService()->realRole->fetchAll($whereData);
break;
case 2:
$data = $this->LocalService()->realRole->fetchOne($whereData);
break;
case 3:
$data = $this->LocalService()->realRole->fetchCol($field,$whereData);
break;
default:
$data['data'] = $this->LocalService()->realRole->fetchAll($whereData);
$data['count'] = $this->LocalService()->realRole->getCount($whereData['where']);
break;
}
return $data ;
}
/** 添加中心角色和人员的关系
* Notes:
* User: llbjj
* DateTime: 2022/9/6 15:22
*
* @param int $item_id
* @param int $itemsig_id
* @param int $role_id
* @param array $signatoryUserData
*/
public function mapToSiguser(int $item_id, int $itemsig_id, int $role_id, array &$signatoryUserData) {
$signatoryUserData = array_filter($signatoryUserData);
$relationWhere = [
'is_del' => 0,
'status' => 0,
'item_id' => $item_id,
'item_sign_id' => $itemsig_id,
'role_id' => $role_id,
];
$relationCount = $this->LocalService()->roleSignatoryRelation->getCount($relationWhere);
if(!count($signatoryUserData)) {
if ($relationCount) {
$this->LocalService()->roleSignatoryRelation->update(['status' => 1], $relationWhere);
}
} else {
// 获取本次提交人之外的人员信息
$disabledRelationDatas = $this->LocalService()->roleSignatoryRelation->fetchCol('signatory_user', ArrayUtils::merge($relationWhere, [
'is_del' => 0,
new NotIn('signatory_user', $signatoryUserData),
]));
// 删除本次提交之外的人员
$this->LocalService()->roleSignatoryRelation->update(['status' => 1], ArrayUtils::merge($relationWhere,
[
'is_del' => 0,
new NotIn('signatory_user', $signatoryUserData),
]
));
// 获取本角色下的所有的人员(包含已删除)
$preUserData = $this->LocalService()->roleSignatoryRelation->fetchCol('signatory_user', [
'is_del' => 0,
'item_id' => $item_id,
'item_sign_id' => $itemsig_id,
'role_id' => $role_id,
]);
//查询手机号和userid对应的数组
/*$userInfoArr = $this->LocalService()->adminUser->fetchAll([
'where' => 'is_del = 0',
'columns' => ['id','mobile'],
]);
$userTelArr = array_column($userInfoArr,null,'mobile');
//获取yikeen_signatory_user的id和tel对应数组
$signatory_users = $this->LocalService()->signatoryUser->fetchCol('user_tel','is_del = 0');*/
$signatory_admin_user_arr = $this->LocalService()->signatoryUser->fetchCol('admin_user_id','is_del = 0');
foreach($signatoryUserData as $signatory_user_id) {
$user_id = isset($signatory_admin_user_arr[$signatory_user_id]) && !empty($signatory_admin_user_arr[$signatory_user_id]) ? $signatory_admin_user_arr[$signatory_user_id] : 0;
//获取到用户手机号
/*$user_tel = isset($signatory_users[$signatory_user_id]) && !empty($signatory_users[$signatory_user_id]) ? $signatory_users[$signatory_user_id] : '';
if(!empty($user_tel)){
//根据手机号查询adminuser表的用户ID
$user_id = isset($userTelArr[$user_tel]['id']) && !empty($userTelArr[$user_tel]['id']) ? $userTelArr[$user_tel]['id'] : 0;
}*/
$relationData = [
'item_id' => $item_id,
'item_sign_id' => $itemsig_id,
'role_id' => $role_id,
'signatory_user' => $signatory_user_id,
'admin_user_id' => $user_id,
'status' => 0
];
if(in_array($signatory_user_id, $preUserData)) $relationData['id'] = array_keys($preUserData, $signatory_user_id)[0];
$id = $this->LocalService()->roleSignatoryRelation->save($relationData);
// 同步企业微信
if($this->LocalService()->config['isOpenWechatWork']) $this->LocalService()->workUser->syncUserToWork($item_id, $itemsig_id, $signatory_user_id);
}
unset($signatory_users);
unset($userTelArr);
if(!empty($disabledRelationDatas) && $this->LocalService()->config['isOpenWechatWork']) {
foreach ($disabledRelationDatas as $signatory_user_id) {
$this->LocalService()->workUser->syncUserToWork($item_id, $itemsig_id, $signatory_user_id);
}
}
}
}
/**
* Notes:获取角色信息ID为键值名称+code值为值
* User: lltyy
* DateTime: 2022/11/1 15:02
*
* @param $where
* @return array
*/
public function fetchNameAndCodeById($where){
$arr = [];
$cond = [
'where'=>$where,
'columns'=>['id','role_name'],
'order'=>['sort asc']
];
$datas = $this->fetchAll($cond);
if(!empty($datas)){
foreach($datas as $data){
$data_id = $data['id'];
$arr[$data_id] = $data['role_name'];
}
}
return $arr;
}
/**
* 项目传输后给固定角色设置默认的权限
* param $itemId 项目id 默认为大项目id
* param $type 项目id类型0为大项目id1为小项目id
*/
public function itemRealRelation($itemId,$type=0){
//小项目id找大项目id
!empty($type) && $itemId = $this->LocalService()->itemInfo->getOneFieldVal('fid',['is_del'=>0,'id'=>$itemId]);
$realRolemodulerelationInfo = $this->LocalService()->realRolemodulerelationEdc->fetchOne(['where'=>['status'=>0,'item_id'=>$itemId]]);
if(!empty($realRolemodulerelationInfo)){
return false;
echo '已存在角色权限,不再同步';die;
return false;
}
//获取EDC菜单
$whereMArr['where'] = [
'is_del' => 0,
'menu_type' => 1,
new Operator('parent_id', Operator::OP_GT, 0)
];
$whereMArr['order'] = 'menu_order';
$menuLists = $this->LocalService()->adminMenuEdc->getAdminMenuData($whereMArr,1);
//获取项目权限
$relations = '';
$realRoleData = $this->LocalService()->realRole->fetchAll(['where' =>['is_del'=>0,'item_id'=>$itemId,'code'=>['yjys','yjzl','sbz','yx','pm','cra','crc','dm']]]);
if (!empty($realRoleData)) {
foreach($realRoleData as $realRoleDataK=>$realRoleDataV){
if (!empty($menuLists)){
$role_code = $realRoleDataV['code'];
foreach ($menuLists as $menuList) {
$role_power_arr = !is_null($menuList['role_code_power']) && !empty($menuList['role_code_power']) ? json_decode($menuList['role_code_power'],true) : [];
$role_power = isset($role_power_arr[$role_code]) && !empty($role_power_arr[$role_code]) ? intval($role_power_arr[$role_code]) : 0;
if(!empty($role_power)){
$look_write = 0;
if($role_power == 2){
$look_write = 1;
}
$realRolemodulerelationArr = [
'role_id'=>$realRoleDataV['id'],
'module_id'=>$menuList['id'],
'item_id'=>$itemId,
'look_write'=>$look_write
];
$realRolemodulerelationId = $this->LocalService()->realRolemodulerelationEdc->save($realRolemodulerelationArr);
$relations .= $realRolemodulerelationId.',';
}
}
}
}
}
return true;
$count = count($arr = explode(',',$relations))-1;
echo '成功关系表id'.$relations.'总数据:'.$count;die;
return true;
return $realRoleId;
}
/**
* 项目传输后给固定角色设置默认的权限
* param $itemId 项目id 默认为大项目id
* param $type 项目id类型0为大项目id1为小项目id
*/
public function OLDitemRealRelation($itemId,$type=0){
$itemRealRoleName = ['研究医生','研究助理','PM','CRA','CRC','DM'];
$itemRealRoleCode = ['yjys','yjzl','pm','cra','crc','dm'];
//小项目id找大项目id
!empty($type) && $itemId = $this->LocalService()->itemInfo->getOneFieldVal('fid',['is_del'=>0,'item_id'=>$itemId]);
$realRolemodulerelationInfo = $this->LocalService()->realRolemodulerelationEdc->fetchOne(['where'=>['status'=>0,'item_id'=>$itemId]]);
if(!empty($realRolemodulerelationInfo)){
return false;
echo '已存在角色权限,不再同步';die;
return false;
}
$whereMArr['where'] = [
'is_del' => 0,
'menu_type' => 1
];
$whereMArr['order'] = 'menu_order';
$menuList = $this->LocalService()->adminMenuEdc->getAdminMenuData($whereMArr,1);
//-1没有模块权限0只读1可读可写
//1-real菜单管理-,2-研究中心管理-hospital,3-角色设置-role,4-逻辑核查管理-logical,5-进度管理-progress,6-导出CRF-crf,7-导出SAS-saas
// $menuNameData = [
// 'yjys'=>['hospital'=>-1,'role'=>-1,'logical'=>-1,'progress'=>-1,'crf'=>-1,'saas'=>-1],
// 'yjzl'=>['hospital'=>-1,'role'=>-1,'logical'=>-1,'progress'=>-1,'crf'=>-1,'saas'=>-1],
// 'pm'=>['hospital'=>-1,'role'=>-1,'logical'=>-1,'progress'=>0,'crf'=>-1,'saas'=>-1],
// 'cra'=>['hospital'=>-1,'role'=>-1,'logical'=>1,'progress'=>1,'crf'=>-1,'saas'=>-1],
// 'crc'=>['hospital'=>-1,'role'=>-1,'logical'=>-1,'progress'=>-1,'crf'=>-1,'saas'=>-1],
// 'dm'=>['hospital'=>-1,'role'=>1,'logical'=>1,'progress'=>1,'crf'=>1,'saas'=>1,'export'=>1],
// ];
$menuNameData = [];
if (!empty($menuList)){
$menuNameDatas = array_filter(array_column($menuList,'name'));
//yjys===yjzl==crc
$craMenuNameData = $pmMenuNameData = $yjysMenuNameData = array_fill_keys($menuNameDatas,-1);
$dmMenuNameData = array_fill_keys($menuNameDatas,1);
//dm
if (!empty($dmMenuNameData) && isset($dmMenuNameData['hospital'])){
$dmMenuNameData['hospital'] = -1;
}
//pm
if (!empty($pmMenuNameData) && isset($pmMenuNameData['progress'])){
$pmMenuNameData['progress'] = 0;
}
//cra
if (!empty($craMenuNameData)){
if (isset($craMenuNameData['logical'])){
$craMenuNameData['logical'] = 1;
}
if (isset($craMenuNameData['progress'])){
$craMenuNameData['progress'] = 1;
}
}
$menuNameData['yjys'] = $menuNameData['yjzl'] = $menuNameData['crc'] = $yjysMenuNameData;
$menuNameData['dm'] = $dmMenuNameData;
$menuNameData['pm'] = $pmMenuNameData;
$menuNameData['cra'] = $craMenuNameData;
}
$relations = '';
$realRoleData = $this->LocalService()->realRole->fetchAll(['where' =>['is_del'=>0,'item_id'=>$itemId,'code'=>['yjys','yjzl','pm','cra','crc','dm']]]);
if (!empty($realRoleData)) {
foreach($realRoleData as $realRoleDataK=>$realRoleDataV){
if (!empty($menuList)){
if(isset($menuNameData[$realRoleDataV['code']])){
$realRelationData = $menuNameData[$realRoleDataV['code']];
foreach ($menuList as $menuListK => $menuListV) {
if(isset($realRelationData[$menuListV['name']]) && $realRelationData[$menuListV['name']] >=0){
$realRolemodulerelationArr['look_write'] = $realRelationData[$menuListV['name']];
$realRolemodulerelationArr['role_id'] = $realRoleDataV['id'];
$realRolemodulerelationArr['module_id'] = $menuListV['id'];
$realRolemodulerelationArr['item_id'] = $itemId;
$realRolemodulerelationId = $this->LocalService()->realRolemodulerelationEdc->save($realRolemodulerelationArr);
$relations .= $realRolemodulerelationId.',';
}
}
}
}
}
}
return true;
$count = count($arr = explode(',',$relations))-1;
echo '成功关系表id'.$relations.'总数据:'.$count;die;
return true;
return $realRoleId;
}
/**
* Notes:通过userID 查询人员对应的signatory_user_id
* @param $userid
* @return
* @author haojinhua
* @date 2024-06-06
*/
public function getUserRole($itemfid_filterConditions = ''){
$sig_user_arr = $user_role_arr = $siguser_role_arr = $itemsig_arr = [];
//获取人员和角色对应数组
//查询人员信息
$cond = [
'where'=>'is_del = 0',
'columns'=>['id','realname'],
'order'=>['id asc']
];
$user_datas = $this->LocalService()->adminUser->fetchAll($cond);
if(!empty($user_datas)){
//查询操作人的角色 1获取用户id对应手机号
$userPhoneArr = $this->LocalService()->adminUser->isShowMaskingField(true)->fetchCol('mobile', 'is_del = 0');
//手机号与合作方ID数组
$phoneSigidArr = $this->LocalService()->signatoryUser->isShowMaskingField(true)->getFiledRelation([], ['id','info_id', 'user_tel'], 'user_tel', 1);
foreach ($user_datas as $user_data){
$user_id = $user_data['id'];
//查询用户手机号
$user_tel = isset($userPhoneArr[$user_id]) && !empty($userPhoneArr[$user_id]) ? $userPhoneArr[$user_id] : '';
$sig_info_id = isset($phoneSigidArr[$user_tel]) && !empty($phoneSigidArr[$user_tel]) ? $phoneSigidArr[$user_tel]['info_id'] : '';
$sig_user_id = isset($phoneSigidArr[$user_tel]) && !empty($phoneSigidArr[$user_tel]) ? $phoneSigidArr[$user_tel]['id'] : '';
$sig_user_arr[$user_id] = [
'sig_info_id' => $sig_info_id,
'sig_user_id' => $sig_user_id
];
}
}
//获取role_id数组
$role_cond = [
'where' => !empty($itemfid_filterConditions) ? $itemfid_filterConditions+['status'=>0] :['status'=>0],
'columns' => ['item_id','role_id','signatory_user','item_sign_id'],
'order' => ['id'],
];
$role_datas = $this->LocalService()->roleSignatoryRelation->fetchAll($role_cond);
if(!empty($role_datas)){
foreach ($role_datas as $role_data){
$user_role_arr[$role_data['item_id']][$role_data['signatory_user']][] = $role_data['role_id'];
$siguser_role_arr[$role_data['item_id']][$role_data['item_sign_id']][$role_data['signatory_user']][] = $role_data['role_id'];
}
}
//根据项目ID和info_id 查询itemSig_id
$itemsig_cond = [
'where' => !empty($itemfid_filterConditions) ? $itemfid_filterConditions : 'id>0',
'columns' => ['item_id','signatory_id','id'],
'order' => ['id'],
];
$itemsig_datas = $this->LocalService()->itemSignatory->fetchAll($itemsig_cond);
if(!empty($itemsig_datas)){
foreach ($itemsig_datas as $itemsig_data){
$itemsig_arr[$itemsig_data['item_id']][$itemsig_data['signatory_id']] = $itemsig_data['id'];
}
}
unset($user_datas);
unset($role_datas);
unset($itemsig_datas);
return[$sig_user_arr,$user_role_arr,$siguser_role_arr,$itemsig_arr];
}
/**
* Notes:获取指定条件下的数据
* User: lltyy
* DateTime: 2024/5/28 9:50
*
* @param string $where 条件
* @param string[] $columns 字段
* @param string[] $order 排序
* @param string $key 键值
* @param int $is_more 是否有多笔【1 是 0 否】
* @return array
*/
public function fetchDataByKey($where='is_del = 0',$columns=['id'],$order=['id'],$key='id',$is_more=0){
$datas = [];
$cond = [
'where'=>$where,
'columns'=>$columns,
'order'=>$order
];
$infoDatas = $this->fetchAll($cond);
if(!empty($infoDatas)){
foreach($infoDatas as $infoData){
$data_key = $infoData[$key];
if($is_more == 1){
$datas[$data_key][] = $infoData;
}else{
$datas[$data_key] = $infoData;
}
}
}
unset($cond);
unset($infoDatas);
return $datas;
}
/**
* Notes: 查询角色下的人员数组
* @param
* @return
* @author haojinhua
* @date 2024-08-21
*/
public function getRolUser(){
$signatory_userArr = []; //角色下的人员ID
$role_cond = [
'where' => 'is_del = 0 and status = 0',
'columns' => ['item_id','role_id','signatory_user'],
'order' => ['id'],
];
$role_datas = $this->LocalService()->roleSignatoryRelation->fetchAll($role_cond);
if(!empty($role_datas)){
foreach ($role_datas as $role_data){
if(!empty($role_data['signatory_user'])){
$signatory_userArr[$role_data['item_id']][$role_data['role_id']][] = $role_data['signatory_user'];
}
}
}
return $signatory_userArr;
}
public function getRole($item_id=0,$itemsig_id=0)
{
$platForm = Laminas::$serviceManager->identity->getPlatform();
$userId = Laminas::$serviceManager->identity->getId();
$role = '';
if($platForm <> 'PC'){
if($platForm == 'MINI_PATIENT' || $platForm == 'H5_PATIENT') return 'Patient';
if($item_id == 0 || $itemsig_id == 0) return '';
//记录Real端角色
//获取用户合作方id
$fid = $this->LocalService()->itemInfo->getOneFieldVal('fid',['id'=>$item_id]);
$userMobile = $this->LocalService()->adminUser->getOneFieldVal('mobile',['id'=>$userId]);
$signUserId = $this->LocalService()->signatoryUser->getOneFieldVal('id',['user_tel'=>$userMobile]);
if(!$signUserId) return '';
$signRole = $this->LocalService()->roleSignatoryRelation->fetchCol('role_id',['signatory_user'=>$signUserId,'status'=>0,'is_del'=>0,'item_id'=>$fid,'item_sign_id'=>$itemsig_id]);
if($signRole){
$realRoleWhere = new Where();
$realRoleWhere->equalTo('status',0);
$realRoleWhere->in('id',$signRole);
$roleName = $this->LocalService()->realRole->fetchCol('role_name',$realRoleWhere);
$role = implode(',',$roleName);
}
return $role;
}else{
//记录PC端角色
$adminRole = $this->LocalService()->userRoleRelation->fetchCol('role_id',['user_id'=>$userId,'status'=>0]);
if(!empty($adminRole)){
$adminRoleWhere = new Where();
$adminRoleWhere->equalTo('status',0);
$adminRoleWhere->in('id',$adminRole);
$roleName = $this->LocalService()->adminRole->fetchCol('role_name',$adminRoleWhere);
$role = implode(',',$roleName);
}
return $role;
}
}
/**
* Notes: 更新权限人员关系表
* User: lltyy
* DateTime: 2025/6/4 9:52
*
*/
public function scanData(){
//获取人员信息
$adminUserArr = [
'id'=>[],
'tel'=>[]
];
$adminUsers = $this->LocalService()->adminUser->fetchAll([
'where'=>'id > 0 and mobile != "" and mobile is not null',
'columns'=>['id','mobile','is_del'],
'order'=>['id desc']
]);
if(!empty($adminUsers)){
foreach($adminUsers as $adminUserKey=>$adminUser){
$adminUserArr['id'][$adminUser['id']] = $adminUser;
if($adminUser['is_del'] == 0){
$adminUserArr['tel'][trim($adminUser['mobile'])] = $adminUser['id'];
}
unset($adminUsers[$adminUserKey]);
}
}
unset($adminUsers);
//获取中心人员信息
$sigUserArr = [
'id'=>[],
'tel'=>[]
];
$sigUsers = $this->LocalService()->signatoryUser->fetchAll([
'where'=>'id > 0 and user_tel != "" and user_tel is not null',
'columns'=>['id','user_tel','is_del'],
'order'=>['id desc']
]);
if(!empty($sigUsers)){
foreach($sigUsers as $sigUserKey=>$sigUser){
$sigUserArr['id'][$sigUser['id']] = $sigUser;
if($sigUser['is_del'] == 0){
$sigUserArr['tel'][trim($sigUser['user_tel'])] = $sigUser['id'];
}
unset($sigUsers[$sigUserKey]);
}
}
unset($sigUsers);
$where = 'id > 0 and (signatory_user > 0 or admin_user_id > 0)';
$bool = true;
$page = 0;
$limit = 1000;
$last_id = 0;
while ($bool) {
$page++;
echo "PAGE {$page}" . PHP_EOL;
$last_id = $this->mateData($where.' and id > '.$last_id,$limit,0,$adminUserArr,$sigUserArr);
if(!$last_id) $bool = false;
}
unset($where);
unset($adminUserArr);
unset($sigUserArr);
unset($last_id);
unset($bool);
unset($limit);
unset($page);
}
/**
* Notes: 执行更新权限人员关系表
* User: lltyy
* DateTime: 2025/6/4 10:00
*
* @param $where
* @param int $limit
* @param int $offset
* @param $adminUserDatas //人员信息
* @param $sigUserDatas //中心人员信息
* @return int
*/
public function mateData($where,$limit=0,$offset=0,&$adminUserDatas,&$sigUserDatas){
//获取指定条件下的医嘱数据
$cond = [
'where'=>$where,
'columns'=>['id','signatory_user','admin_user_id'],
'order'=>['id']
];
if(!empty($limit) || !empty($offset)){
$cond['limit'] = $limit;
$cond['offset'] = $offset;
}
$datas = $this->LocalService()->roleSignatoryRelation->fetchAll($cond);
$last_id = 0;
if(!empty($datas)){
foreach($datas as $dataKey=>$data){
$last_id = $data['id'];
$sig_user = !empty($data['signatory_user']) && isset($sigUserDatas['id'][$data['signatory_user']]) && !empty($sigUserDatas['id'][$data['signatory_user']]) ? $sigUserDatas['id'][$data['signatory_user']] : [];
$tel = !empty($sig_user) ? trim($sig_user['user_tel']) : '';
unset($sig_user);
$admin_user = !empty($data['admin_user_id']) && isset($adminUserDatas['id'][$data['admin_user_id']]) && !empty($adminUserDatas['id'][$data['admin_user_id']]) ? $adminUserDatas['id'][$data['admin_user_id']] : [];
if($tel == ''){
$tel = !empty($admin_user) ? trim($admin_user['mobile']) : '';
}
unset($admin_user);
$new_sig_user = $new_admin_user = 0;
if($tel != ''){
$new_sig_user = isset($sigUserDatas['tel'][$tel]) && !empty($sigUserDatas['tel'][$tel]) ? $sigUserDatas['tel'][$tel] : 0;
$new_admin_user = isset($adminUserDatas['tel'][$tel]) && !empty($adminUserDatas['tel'][$tel]) ? $adminUserDatas['tel'][$tel] : 0;
}
if($new_sig_user != $data['signatory_user'] || $new_admin_user != $data['admin_user_id']){
$this->LocalService()->roleSignatoryRelation->isSetInfo(false)->update(['signatory_user'=>$new_sig_user,'admin_user_id'=>$new_admin_user],'id = '.$data['id']);
}
unset($new_admin_user);
unset($new_sig_user);
unset($datas[$dataKey]);
}
}
//释放空间
unset($datas);
unset($cond);
return $last_id;
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Where;
class RealroleEdc extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_real_role';
parent::__construct($dbAdapter, $container);
}
public function getAdminRealRoleData($whereData=[],$type = 0,$field=''){
$data = [];
switch ($type){
case 1:
$data = $this->LocalService()->realRoleEdc->fetchAll($whereData);
break;
case 2:
$data = $this->LocalService()->realRoleEdc->fetchOne($whereData);
break;
case 3:
$data = $this->LocalService()->realRoleEdc->fetchCol($field,$whereData);
break;
default:
$data['data'] = $this->LocalService()->realRoleEdc->fetchAll($whereData);
$data['count'] = $this->LocalService()->realRoleEdc->getCount($whereData['where']);
break;
}
return $data ;
}
/** 添加中心角色和人员的关系
* Notes:
* User: llbjj
* DateTime: 2022/9/6 15:22
*
* @param int $item_id
* @param int $itemsig_id
* @param int $role_id
* @param array $signatoryUserData
*/
public function mapToSiguser(int $item_id, int $itemsig_id, int $role_id, array &$signatoryUserData) {
$signatoryUserData = array_filter($signatoryUserData);
$relationWhere = ['is_del'=>0,'status'=>0,'item_id'=>$item_id,'item_sign_id'=>$itemsig_id,'role_id'=>$role_id];
$relationCount = $this->LocalService()->roleSignatoryRelation->getCount($relationWhere);
if(!count($signatoryUserData)) {
if ($relationCount) {
$this->LocalService()->roleSignatoryRelation->update(['status' => 1], $relationWhere);
}
} else {
// 获取本次提交人之外的人员信息
$roleRelationWhere = new Where();
$roleRelationWhere->equalTo('is_del',0);
$roleRelationWhere->equalTo('status',0);
$roleRelationWhere->equalTo('item_id',$item_id);
$roleRelationWhere->equalTo('item_sign_id',$itemsig_id);
$roleRelationWhere->equalTo('role_id',$role_id);
$roleRelationWhere->notIn('signatory_user',$signatoryUserData);
$disabledRelationDatas = $this->LocalService()->roleSignatoryRelation->fetchCol('signatory_user', $roleRelationWhere);
// 删除本次提交之外的人员
$this->LocalService()->roleSignatoryRelation->update(['status' => 1], $roleRelationWhere);
// 获取本角色下的所有的人员(包含已删除)
$preUserData = $this->LocalService()->roleSignatoryRelation->fetchCol('signatory_user', ['is_del'=>0,'item_id'=>$item_id,'item_sign_id'=>$itemsig_id,'role_id'=>$role_id]);
foreach($signatoryUserData as $signatory_user_id) {
$relationData = [
'item_id' => $item_id,
'item_sign_id' => $itemsig_id,
'role_id' => $role_id,
'signatory_user' => $signatory_user_id,
'status' => 0
];
if(in_array($signatory_user_id, $preUserData)) $relationData['id'] = array_keys($preUserData, $signatory_user_id)[0];
$id = $this->LocalService()->roleSignatoryRelation->save($relationData);
// 同步企业微信
if($this->LocalService()->config['isOpenWechatWork']) $this->LocalService()->workUser->syncUserToWork($item_id, $itemsig_id, $signatory_user_id);
}
if(!empty($disabledRelationDatas) && $this->LocalService()->config['isOpenWechatWork']) {
foreach ($disabledRelationDatas as $signatory_user_id) {
$this->LocalService()->workUser->syncUserToWork($item_id, $itemsig_id, $signatory_user_id);
}
}
}
}
/**
* Notes:获取角色信息ID为键值名称+code值为值
* User: lltyy
* DateTime: 2022/11/1 15:02
*
* @param $where
* @return array
*/
public function fetchNameAndCodeById($where){
$arr = [];
$cond = [
'where'=>$where,
'columns'=>['id','role_name'],
'order'=>['sort asc']
];
$datas = $this->fetchAll($cond);
if(!empty($datas)){
foreach($datas as $data){
$data_id = $data['id'];
$arr[$data_id] = $data['role_name'];
}
}
return $arr;
}
}

View File

@ -0,0 +1,167 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Realrolesignatoryrelation extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_real_rolesignatoryrelation';
parent::__construct($dbAdapter, $container);
}
/*
* 将角色中用户变为字符串
* */
public function changeUser($item_id,$user_id = 0,$item_sign_id = 0){
//查询角色下的角色管理用户信息
$where = ['is_del'=>0,'status'=>0,'item_id'=>$item_id];
if(!empty($user_id))$where['signatory_user'] = $user_id;
if(!empty($item_sign_id))$where['item_sign_id'] = $item_sign_id;
$whereroleSignatoryRelation['where'] = $where;
$whereroleSignatoryRelation['columns'] = ['id', 'item_id', 'role_id', 'item_sign_id', 'signatory_user'];
$rolesignatoryrelationDate = $this->LocalService()->roleSignatoryRelation->fetchAll($whereroleSignatoryRelation);
//不是本合作方人员不展示
if(!empty($rolesignatoryrelationDate)){
foreach ($rolesignatoryrelationDate as $rolesignatoryrelationDateKey=>&$rolesignatoryrelationDateValue) {
$signUserInfoId = 0;
$signinfoId = $this->LocalService()->itemSignatory->getOneFieldVal('signatory_id', ['is_del'=>0,'id'=>$rolesignatoryrelationDateValue['item_sign_id']]);
$realRoleSourceType = $this->LocalService()->realRole->getOneFieldVal('source_type',['is_del'=>0,'id'=>$rolesignatoryrelationDateValue['role_id']]);
!empty($rolesignatoryrelationDateValue['signatory_user']) && $signUserInfoId = $this->LocalService()->signatoryUser->getOneFieldVal('info_id', ['is_del'=>0,'status'=>0,'id'=>$rolesignatoryrelationDateValue['signatory_user']]);
if (empty($signinfoId)){
unset($rolesignatoryrelationDate[$rolesignatoryrelationDateKey]);
continue;
}
if (empty($realRoleSourceType) && ($signinfoId != $signUserInfoId)){
unset($rolesignatoryrelationDate[$rolesignatoryrelationDateKey]);
}
}
}
//处理数据 将相同的项目-中心-角色下的用户以,格式组合
$RoleId = array_unique(array_column($rolesignatoryrelationDate, 'role_id'));
$ItemSignId = array_unique(array_column($rolesignatoryrelationDate, 'item_sign_id'));
$RoleData = [];
$i = 1;
foreach ($ItemSignId as $key=>$val) {
foreach ($RoleId as $k=>$v) {
$RoleData[$i]['role_id'] = $v;
$RoleData[$i]['item_sign_id'] = $val;
$i++;
}
}
$rolesignatoryrelationDates = [];
foreach($RoleData as $key=>$val){
$signatory_user = "";
foreach ($rolesignatoryrelationDate as $k=>$v) {
if($v['role_id'] == $val['role_id']){
if($v['item_sign_id'] == $val['item_sign_id']){
$rolesignatoryrelationDates[$key]['id'] = $v['id'];
$rolesignatoryrelationDates[$key]['role_id'] = $v['role_id'];
$rolesignatoryrelationDates[$key]['item_id'] = $v['item_id'];
$rolesignatoryrelationDates[$key]['item_sign_id'] = $v['item_sign_id'];
if(!empty($v['signatory_user']))$signatory_user .= $v['signatory_user'].",";
}
}
}
if(!empty($signatory_user)){
$rolesignatoryrelationDates[$key]['signatory_user'] = rtrim($signatory_user,",");
}else{
$rolesignatoryrelationDates[$key]['signatory_user'] = "";
}
}
return $rolesignatoryrelationDates;
}
/**
* Notes: 获取指定人员担任的中心角色信息
* User: lltyy
* DateTime: 2022/11/16 11:27
*
* @param $item_id
* @param int $user_id
*/
public function fetchUserRoleBySig($item_id,$user_id){
$arr = [];
$cond = [
'where'=>['is_del'=>0,'item_id'=>$item_id,'signatory_user'=>$user_id,'status'=>0],
'columns'=>['item_sign_id','role_id']
];
$datas = $this->fetchAll($cond);
if(!empty($datas)){
foreach($datas as $data){
$data_itemsig = $data['item_sign_id'];
$data_role = $data['role_id'];
$arr[$data_itemsig][$data_role] = $data_role;
}
}
return $arr;
}
/**
* Notes: 获取中心角色下的人员信息
* User: lltyy
* DateTime: 2022/11/16 11:27
*
* @param $item_id
* @param int $user_id
*/
public function fetchUserBySigRole($where){
//这个方法不用调整现在调用的上游没有指定对应ID
$arr = [];
$cond = [
'where'=>$where,
'columns'=>['item_sign_id','role_id','signatory_user']
];
$datas = $this->fetchAll($cond);
if(!empty($datas)){
foreach($datas as $data){
$data_itemsig = $data['item_sign_id'];
$data_role = $data['role_id'];
$data_signatory_user = $data['signatory_user'];
if(!empty($data_signatory_user)){
$arr[$data_itemsig][$data_role][$data_signatory_user] = $data_signatory_user;
}
}
}
return $arr;
}
/**
* Notes:获取指定条件下的数据
* User: lltyy
* DateTime: 2024/5/28 9:50
*
* @param string $where 条件
* @param string[] $columns 字段
* @param string[] $order 排序
* @param string $key 键值
* @param int $is_more 是否有多笔【1 是 0 否】
* @return array
*/
public function fetchDataByKey($where='is_del = 0',$columns=['id'],$order=['id'],$key='id',$is_more=0){
$datas = [];
$cond = [
'where'=>$where,
'columns'=>$columns,
'order'=>$order
];
$infoDatas = $this->fetchAll($cond);
if(!empty($infoDatas)){
foreach($infoDatas as $infoData){
$data_key = $infoData[$key];
if($is_more == 1){
$datas[$data_key][] = $infoData;
}else{
$datas[$data_key] = $infoData;
}
}
}
unset($cond);
unset($infoDatas);
return $datas;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Role extends \Application\Service\DB\AbstractDb
{
public const MASKING_ADMIN_CODE = 'MaskingAdmin';
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_role';
parent::__construct($dbAdapter, $container);
}
public function getAdminRoleData($whereData=[],$type = 0,$field=''){
$data = [];
switch ($type){
case 1:
$data = $this->LocalService()->adminRole->fetchAll($whereData);
break;
case 2:
$data = $this->LocalService()->adminRole->fetchOne($whereData);
break;
case 3:
$data = $this->LocalService()->adminRole->fetchCol($field,$whereData);
break;
default:
$data['data'] = $this->LocalService()->adminRole->fetchAll($whereData);
$data['count'] = $this->LocalService()->adminRole->getCount($whereData['where']);
break;
}
return $data ;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Application\Service\DB\Admin;
use Interop\Container\ContainerInterface;
class Rolemenurelation extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_admin_rolemenurelation';
parent::__construct($dbAdapter, $container);
}
public function getAdminRoleMenuData($whereData=[],$type = 0,$field=''){
$data = [];
switch ($type){
case 1:
$data = $this->LocalService()->roleMenuRelation->fetchAll($whereData);
// !is_array($data) && $data = [];
break;
case 2:
$data = $this->LocalService()->roleMenuRelation->fetchOne($whereData);
break;
case 3:
$data = $this->LocalService()->roleMenuRelation->fetchCol($field,$whereData);
break;
default:
$data['data'] = $this->LocalService()->roleMenuRelation->fetchAll($whereData);
$data['count'] = $this->LocalService()->roleMenuRelation->getCount($whereData['where']);
break;
}
return $data ;
}
}

View File

@ -0,0 +1,149 @@
<?php
namespace Application\Service\DB\Admin;
use Application\Command\Swoole\Server\WebSocketCommand;
use Interop\Container\Containerinterface;
use Swoole\Coroutine\Http\Client;
use function Co\run;
class Send extends \Application\Service\DB\AbstractDb
{
public function __construct($dbAdapter, ContainerInterface $container)
{
$this->tableName = 'yikeen_config_send';
parent::__construct($dbAdapter, $container);
}
public function fillUkData($item_id)
{
$fieldType = [
'2'=>'UK-UK-UK',
'20'=>"UK-UK-UK UK:UK",
'21'=>"UK-UK-UK UK:UK:UK",
'22'=>"UK:UK",
'23'=>"UK:UK:UK"
];
$fieldData = $this->LocalService()->itemFormField->fetchAll(['where'=>"item_id = $item_id and type in (2,20,21,22,23) and is_del = 0",'columns'=>['id','form_id','type']]);
if(empty($fieldData)) return false;
$field = [];
foreach($fieldData as $v){
$field[$v['form_id']][] = $v;
}
$form = implode(',',array_unique(array_column($fieldData,'form_id')));
$formContent = $this->LocalService()->patientFormContent->fetchCol('data',"is_del = 0 and form_id in ($form)");
foreach($formContent as $key=>$value){
$info = json_decode($value,true);
$flag = false;
foreach($field[$info['form_id']] as $v){
if(isset($info[$v['id']]) && $info[$v['id']] == ''){
$flag = true;
$info[$v['id']] = $fieldType[$v['type']];
}
}
if($flag == true) $this->LocalService()->patientFormContent->update(['data'=>json_encode($info,true)],['id'=>$key]);
}
$aeFormId = $this->LocalService()->itemForm->getOneFieldVal('id',"is_del = 0 and group_id = 5 and item_id = $item_id and id in ($form)");
if(!empty($aeFormId)){
$aeContent = $this->LocalService()->itemPatientAeContent->fetchCol('data',"item_id = $item_id and is_del = 0 and form_id = $aeFormId");
foreach($aeContent as $key=>$value){
$info = json_decode($value,true);
$flag = false;
foreach($field[$info['form_id']] as $v){
if(isset($info[$v['id']]) && $info[$v['id']] == ''){
$flag = true;
$info[$v['id']] = $fieldType[$v['type']];
}
}
if($flag == true) $this->LocalService()->itemPatientAeContent->update(['data'=>json_encode($info,true)],['id'=>$key]);
}
}
return true;
}
public function formatDate($item_id)
{
$fieldData = $this->LocalService()->itemFormField->fetchAll(['where'=>"item_id = $item_id and type in (2,20,21,22,23) and is_del = 0",'columns'=>['id','form_id','type']]);
$field = [];
foreach($fieldData as $k=>$v){
$field[$v['form_id']][] = $v;
}
$form = implode(',',array_unique(array_column($fieldData,'form_id')));
$formContent = $this->LocalService()->patientFormContent->fetchCol('data',"item_id = $item_id and is_del = 0 and form_id in ($form)");
foreach($formContent as $key=>$value){
$info = json_decode($value,true);
$flag = false;
foreach($field[$info['form_id']] as $v){
if(isset($info[$v['id']]) && $info[$v['id']] != ''){
$result = $this->normalizeTimeStringByType($info[$v['id']], $v['type']);
if(!empty($result)){
$flag = true;
$info[$v['id']] = $result;
}
}
}
if($flag == true) $this->LocalService()->patientFormContent->update(['data'=>json_encode($info,true)],['id'=>$key]);
}
$aeFormId = $this->LocalService()->itemForm->getOneFieldVal('id',"is_del = 0 and group_id = 5 and item_id = $item_id and id in ($form)");
if(!empty($aeFormId)){
$aeContent = $this->LocalService()->itemPatientAeContent->fetchCol('data',"item_id = $item_id and is_del = 0 and form_id = $aeFormId");
foreach($aeContent as $key=>$value){
$info = json_decode($value,true);
foreach($field[$info['form_id']] as $v){
if(isset($info[$v['id']]) && $info[$v['id']] != ''){
$result = $this->normalizeTimeStringByType($info[$v['id']], $v['type']);
if(!empty($result)){
$info[$v['id']] = $result;
$this->LocalService()->itemPatientAeContent->update(['data'=>json_encode($info,true)],['id'=>$key]);
}
}
}
}
}
echo "SUCCESS";die;
}
function normalizeTimeStringByType(string $time, int $type): string {
$formatMap = [
2 => 'Y-m-d',
20 => 'Y-m-d H:i',
21 => 'Y-m-d H:i:s',
22 => 'H:i',
23 => 'H:i:s',
];
if (!isset($formatMap[$type])) {
return '';
}
$targetFormat = $formatMap[$type];
// 尝试直接格式化
$dt = \DateTime::createFromFormat($targetFormat, $time);
if ($dt instanceof \DateTime && $dt->format($targetFormat) === $time) {
return $dt->format($targetFormat); // 已规范
}
// 使用正则补 0例如 9:3:2 => 09:03:02
$fixed = preg_replace_callback('/\b\d\b/', fn($m) => '0' . $m[0], $time);
// 尝试修正后的时间
$dt = \DateTime::createFromFormat($targetFormat, $fixed);
if ($dt instanceof \DateTime) {
return $dt->format($targetFormat);
}
return ''; // 非法时间,返回空
}
}

Some files were not shown because too many files have changed in this diff Show More