123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- <?php
- namespace frontend\modules\api\controllers;
- use common\models\AccidentCasesRelateToDictionary;
- use common\models\AccidentCasesStudy;
- use common\models\Dictionary;
- use common\models\EmergencyResponseRelateToRulesPoints;
- use common\models\OperationalAdjustmentsRelateToRulesPoints;
- use common\models\SearchHistory;
- use common\services\AdminLogService;
- use common\services\CaseService;
- use common\services\EmergencyResponseService;
- use common\services\EventOverviewService;
- use common\services\OperationalAdjustmentsService;
- use common\services\RulesPointsService;
- use common\services\RulesService;
- use Exception;
- use frontend\modules\api\components\BaseAdminController;
- use Yii;
- use yii\base\InvalidConfigException;
- use yii\web\Response;
- class CaseController extends BaseAdminController
- {
- /**
- * 搜索历史
- * @return Response
- */
- public function actionSearchHistory()
- {
- $SearchHistoryList = SearchHistory::find()->where(["uid" => $this->uid])->orderBy("update_time desc")->asArray()->limit(10)->all();
- if (isset($SearchHistoryList[9])) {
- //个人历史记录超过10条,就删掉
- SearchHistory::deleteAll(["and", ["uid" => $this->uid], ["<", "update_time", $SearchHistoryList[9]["update_time"]]]);
- }
- $list = array_column($SearchHistoryList, "content");
- return $this->asJson($list);
- }
- /**
- * 推荐案例
- * @param $accident_id
- * @return Response
- * @throws Exception
- */
- public function actionRecommend($accident_id)
- {
- /**
- * 推荐顺序为:1.相同的事件类型,2.相同的时间特征,3.相同的发生位置。
- * 逻辑:
- * 先找到相同的事件类型,
- * 如果没有,找相同的时间特征,如果没有,找相同的发生位置,如果没有,返回空
- * 如果有,找出10个
- * 如果不足10个,找相同的时间特征替代
- * 如果总数仍不足10个,找相同的发生位置。
- * 最多显示10条记录
- */
- $limit = 10;
- $AccidentCases = CaseService::getCaseById($accident_id);
- //事件类型目前按照一级字段来推荐
- $AccidentCasesList = CaseService::getCaseShowQuery()->andWhere(["and", ["type_first" => $AccidentCases->type_first], ["<>", "id", $AccidentCases->id]])->limit($limit)->orderBy("start_time desc")->all();
- $list = CaseService::dealWithFocusList($AccidentCasesList);
- $totalCount = count($list);
- if ($totalCount < $limit) {
- //查找相同时间特征
- $idNotIn = array_column($AccidentCasesList, "id");
- $AccidentCasesList = CaseService::getCaseShowQuery()->andWhere(["and", ["time_type" => $AccidentCases->time_type], ["<>", "id", $AccidentCases->id], ["NOT IN", "id", $idNotIn]])->limit($limit - $totalCount)->orderBy("start_time desc")->all();
- $list = array_merge($list, CaseService::dealWithFocusList($AccidentCasesList));
- }
- $totalCount = count($list);
- if ($totalCount < $limit) {
- //查找相同的发生位置
- $idNotIn = array_column($AccidentCasesList, "id");
- $AccidentCasesList = CaseService::getCaseShowQuery()->andWhere(["and", ["position_base_second" => $AccidentCases->position_base_second], ["position_extra_second" => $AccidentCases->position_extra_second], ["<>", "id", $AccidentCases->id], ["NOT IN", "id", $idNotIn]])->limit($limit - $totalCount)->orderBy("start_time desc")->all();
- $list = array_merge($list, CaseService::dealWithFocusList($AccidentCasesList));
- }
- $data["data"] = $list;
- return $this->asJson($data);
- }
- /**
- * 案例搜索
- * @param int $current
- * @param int $page
- * @return Response
- * @throws InvalidConfigException
- */
- public function actionListNew(int $current = 1, int $page = 10)
- {
- //通用
- $post = Yii::$app->request->post();
- $query = CaseService::getCaseShowQuery()
- ->limit($page)
- ->offset(($current - 1) * $page);
- //排序
- $this->initSequence($query, "start_time desc");
- //搜索
- if (!isset($post["action"])) {
- $post["action"] = "fulltext";
- }
- $needSaveHistoryLog = true;
- if ($post["action"] == "fulltext") {
- //全文搜索
- list($info, $total) = $this->fullSearch($query, $post);
- //保存搜索记录
- if (trim($post["fulltext_content"]) != "") {
- $SearchHistory = SearchHistory::findOne(["uid" => $this->uid, "content" => trim($post["fulltext_content"])]);
- if (!$SearchHistory) {
- $SearchHistory = new SearchHistory();
- $SearchHistory->uid = $this->uid;
- $SearchHistory->content = trim($post["fulltext_content"]);
- $SearchHistory->type = 1;
- }
- $SearchHistory->update_time = time();
- $SearchHistory->save();
- } else {
- if ($current == 1 && $page == 5) {
- $needSaveHistoryLog = false;
- }
- }
- } elseif ($post["action"] == "list") {
- //列表搜索
- list($info, $total) = $this->listSearch($query, $post);
- } else {
- //高级搜索
- list($info, $total) = $this->advanceSearch($query, $post);
- }
- //
- if ($needSaveHistoryLog) {
- $model = "";
- $origin = AdminLogService::getOrigin($model, $this->getAllParams());
- AdminLogService::saveLogWithUpdateHistory($origin, $model, 0, "", $this->getAllParams());
- }
- //
- $data["data"] = CaseService::dealWithList($info);
- $data["total"] = $total;
- return $this->asJson($data);
- }
- protected function fullSearch($query, $post)
- {
- $fulltextContent = trim($post["fulltext_content"]);
- if ($fulltextContent != "") {
- //先从字典表进行模糊查询,找出id并找到对应的表进行匹配
- $DictionaryIdList = array_column(Dictionary::find()->where(["and", ["<>", "pid", 0], ["like", "name", $fulltextContent]])->all(), "id");
- $AccidentCasesRelationship = array_column(AccidentCasesRelateToDictionary::find()->where(["accident_cases_id" => $DictionaryIdList])->select("distinct(accident_cases_id)")->asArray()->all(), "accident_cases_id");
- //规章制度
- $rulesList = RulesService::getQuery()->where(["or", ["like", "rule_name", $fulltextContent], ["like", "rule_content", $fulltextContent]])->asArray()->all();
- $rulesIds = array_column($rulesList, "id");
- $rulesPointsList = RulesPointsService::getRulesPointsQuery()->where([
- "or",
- ["like", "name", $fulltextContent],
- ["like", "content", $fulltextContent],
- ["rule_id" => $rulesIds]
- ])->asArray()->all();
- $rulesPointsIds = array_column($rulesPointsList, "id");
- //通过规章点找出相关的应急处置和运营调整
- $EmergencyResponseIds = array_column(EmergencyResponseRelateToRulesPoints::find()->where(["rules_point_id" => $rulesPointsIds])->all(), "emergency_response_id");
- $OperationalAdjustmentsIds = array_column(OperationalAdjustmentsRelateToRulesPoints::find()->where(["rules_point_id" => $rulesPointsIds])->all(), "operational_adjustments_id");
- //将事件概览、应急处置和运营调整的搜索加进来
- $EmergencyResponseList = EmergencyResponseService::getEmergencyResponseQuery()
- ->andWhere([
- "or",
- ["like", "content", $fulltextContent],
- ["like", "important_content", $fulltextContent],
- ["like", "assess", $fulltextContent],
- ["like", "assess_two", $fulltextContent],
- ["id" => $EmergencyResponseIds],
- ])
- ->select("distinct(accident_id)")
- ->asArray()->all();
- $EmergencyResponse = array_column($EmergencyResponseList, "accident_id");
- $EventOverviewList = EventOverviewService::getEventOverviewQuery()
- ->andWhere([
- "or",
- ["like", "content", $fulltextContent],
- ["like", "important_content", $fulltextContent],
- ["like", "assess", $fulltextContent],
- ["like", "assess_two", $fulltextContent],
- ["id" => $OperationalAdjustmentsIds],
- ])
- ->select("distinct(accident_id)")
- ->asArray()->all();
- $EventOverview = array_column($EventOverviewList, "accident_id");
- $OperationalAdjustmentsList = OperationalAdjustmentsService::getQuery()
- ->andWhere([
- "or",
- ["like", "content", $fulltextContent],
- ["like", "important_content", $fulltextContent],
- ["like", "assess", $fulltextContent],
- ["like", "assess_two", $fulltextContent],
- ])
- ->select("distinct(accident_id)")
- ->asArray()->all();
- $OperationalAdjustments = array_column($OperationalAdjustmentsList, "accident_id");
- //整合ids
- $ids = array_merge($AccidentCasesRelationship, $EmergencyResponse, $EventOverview, $OperationalAdjustments);
- $ids = array_values(array_unique($ids));
- $query->andWhere([
- "or",
- ["id" => $ids],
- ["like", "title", $fulltextContent],
- ["like", "train_number_times", $fulltextContent],
- ["like", "position", $fulltextContent],
- ]);
- }
- //组合数据
- return [$query->all(), $query->count()];
- }
- protected function listSearch($query, $post)
- {
- //应急处置表字段 emergency_response_type emergency_response fault abnormal
- $post["emergency_response_type"] = [];
- $post["emergency_response"] = "";
- //运营调整字段 operational_adjustments_type operational_adjustments
- $post["operational_adjustments_type"] = [];
- $post["operational_adjustments"] = "";
- // ids
- $ids = [];
- //post数据
- $hasIdsSearch = false;
- foreach ($post["list_content"] as $value) {
- if ($value["count"] != []) {
- switch ($value["name"]) {
- case "事件性质":
- $query = $this->addArrayConditionToQuery("level", $query, $value["count"]);
- break;
- case "事件类型":
- //事件类型 数组保存
- $AccidentCasesRelationship = array_column(AccidentCasesRelateToDictionary::find()->where(["dictionary_id" => $value["count"]])->select("distinct(accident_cases_id)")->asArray()->all(), "accident_cases_id");
- $ids = array_merge($ids, $AccidentCasesRelationship);
- $hasIdsSearch = true;
- break;
- case "所属线路":
- $query = $this->addArrayConditionToQuery("line", $query, $value["count"]);
- break;
- case "日期特征":
- $query = $this->addArrayConditionToQuery("day_type", $query, $value["count"]);
- break;
- case "时间特征":
- $query = $this->addArrayConditionToQuery("time_type", $query, $value["count"]);
- break;
- // case "应急处置信息":
- // $post["emergency_response_type"] = $value["count"];
- // break;
- // case "运营调整信息":
- // $post["operational_adjustments_type"] = $value["count"];
- // break;
- case "最大晚点":
- $orData = ["or"];
- $delayDataNums = 0;
- foreach ($value["count"] as $count) {
- $condition = $this->getMaximumDelay($count);
- if (isset($condition[0]) && isset($condition[1])) {
- $orData[] = ["and", [">=", "maximum_delay", $condition[0]], ["<=", "maximum_delay", $condition[1]]];
- } else if (isset($condition[0])) {
- $orData[] = [">=", "maximum_delay", $condition[0]];
- }
- $delayDataNums++;
- }
- if ($delayDataNums == 1) {
- $query->andWhere($orData[1]);
- } else {
- $query->andWhere($orData);
- }
- break;
- case "所属年份":
- $this->setYearSearch($query, $value["count"]);
- break;
- default:
- break;
- }
- }
- }
- // //应急处置表字段
- // $ids = array_merge($ids, $this->getIdsByEmergencyResponse($post));
- // //运营调整字段
- // $ids = array_merge($ids, $this->getIdsByOperationalAdjustments($post));
- if ($ids != []) {
- $query->andWhere(["id" => $ids]);
- }
- if ($hasIdsSearch && $query->where === ["delete_time" => 0, "status" => 1]) {
- //在有ids搜索的前提下其他搜索都没有
- return [[], 0];
- }
- //组合数据
- return [$query->all(), $query->count()];
- }
- protected function getMaximumDelay($maximum_delay)
- {
- $maximumDelayArray = [
- [0, 0],
- [2, 5],
- [5, 15],
- [15, 30],
- [30]
- ];
- return $maximumDelayArray[$maximum_delay];
- }
- protected function setYearSearch($query, $yearDictionaryIds)
- {
- $orData = ["or"];
- $delayDataNums = 0;
- /** @var Dictionary[] $yearInfoList */
- $yearInfoList = Dictionary::find()->where(["status" => 1, "id" => $yearDictionaryIds])->all();
- foreach ($yearInfoList as $yearInfo) {
- $yearStart = strtotime($yearInfo->name . "-01-01");
- $yearEnd = strtotime($yearInfo->name . "-12-31");
- $orData[] = ["and", [">=", "start_time", $yearStart], ["<=", "start_time", $yearEnd]];
- $delayDataNums++;
- }
- if ($delayDataNums == 1) {
- $query->andWhere($orData[1]);
- } else {
- $query->andWhere($orData);
- }
- }
- protected function advanceSearch($query, $post)
- {
- $hasIdsSearch = false;
- $ids = [];
- $dictionaryIds = [];
- //主要筛选条件
- if ($post["years"] !== []) {
- $this->setYearSearch($query, $post["years"]);
- }
- //字符串
- $query = $this->addConditionToQuery("title", $query, true);
- //下拉框
- $query = $this->addConditionToQuery("level", $query);
- if ($post["type_base"] !== []) {
- $dictionaryIds = array_merge($dictionaryIds, $post["type_base"]);
- }
- if (isset($post["duty_category"])) {
- $dictionaryIds[] = $post["duty_category"];
- }
- // $query = $this->addConditionToQuery("duty_category", $query);
- $query = $this->addConditionToQuery("day_type", $query);
- $query = $this->addConditionToQuery("time_type", $query);
- //时间范围
- $query = $this->addStartEndConditionToQuery("start_time", $query, true);
- $query = $this->addStartEndConditionToQuery("elimination_time", $query, true);
- $query = $this->addStartEndConditionToQuery("recovery_time", $query, true);
- //下拉框
- //发生位置
- if ($post["position_base_second"] !== "") {
- $dictionaryIds[] = $post["position_base_second"];
- }
- if ($post["substation_type"] !== "") {
- $dictionaryIds[] = $post["substation_type"];
- }
- // if(isset($post["train_number"])){
- // $dictionaryIds[] = $post["train_number"];
- // }
- $query = $this->addConditionToQuery("train_number", $query);
- // $query = $this->addConditionToQuery("substation_type", $query);
- $query = $this->addConditionToQuery("line", $query);
- $query = $this->addConditionToQuery("automation_level", $query);
- $query = $this->addConditionToQuery("train_group", $query);
- $query = $this->addConditionToQuery("train_model", $query);
- $query = $this->addConditionToQuery("incidence", $query);
- //数字min&&max array[0],array[1]
- $query = $this->addStartEndConditionToQuery("headway", $query);
- $query = $this->addStartEndConditionToQuery("online_trains_number", $query);
- $query = $this->addStartEndConditionToQuery("emergency_duration", $query);
- $query = $this->addStartEndConditionToQuery("affect_trains_number", $query);
- $query = $this->addStartEndConditionToQuery("power_loss_duration", $query);
- if (isset($post["maximum_delay"])) {
- $maximumDelay = $this->getMaximumDelay($post["maximum_delay"]);
- if ($maximumDelay < 4) {
- $query = $this->addStartEndConditionToQuery("maximum_delay", $query, false, $maximumDelay);
- } else {
- $query = $query->andWhere([">=", "maximum_delay", $maximumDelay]);
- }
- }
- $query = $this->addStartEndConditionToQuery("train_delayed_two_minutes", $query);
- $query = $this->addStartEndConditionToQuery("train_delayed_five_minutes", $query);
- $query = $this->addStartEndConditionToQuery("get_off_trains_number", $query);
- $query = $this->addStartEndConditionToQuery("skip_stop_trains_number", $query);
- //计算案例关系表
- if ($dictionaryIds != []) {
- $AccidentCasesRelationship = array_column(AccidentCasesRelateToDictionary::find()->where(["dictionary_id" => $dictionaryIds])->select("distinct(accident_cases_id)")->asArray()->all(), "accident_cases_id");
- $ids = array_merge($dictionaryIds, $AccidentCasesRelationship);
- $hasIdsSearch = true;
- }
- //附加表字段
- //应急处置表字段 emergency_response_type emergency_response fault abnormal
- if (isset($post["emergency_response_type"]) && $post["emergency_response_type"] != null) {
- $post["emergency_response_type"] = [$post["emergency_response_type"]];
- $ids = array_merge($ids, $this->getIdsByEmergencyResponse($post));
- $hasIdsSearch = true;
- }
- //事件概览字段 event_overview
- if (isset($post["event_overview"]) && $post["event_overview"] != "") {
- $EventOverview = array_column(EventOverviewService::getEventOverviewQuery()->andWhere(["like", "content", $post["event_overview"]])->select("distinct(accident_id)")->asArray()->all(), "accident_id");
- $ids = array_merge($ids, $EventOverview);
- $hasIdsSearch = true;
- }
- //运营调整字段 operational_adjustments_type operational_adjustments
- if (isset($post["operational_adjustments_type"]) && $post["operational_adjustments_type"] != "") {
- $post["operational_adjustments_type"] = [$post["operational_adjustments_type"]];
- $ids = array_merge($ids, $this->getIdsByOperationalAdjustments($post));
- $hasIdsSearch = true;
- }
- if ($ids != []) {
- $query->andWhere(["id" => $ids]);
- }
- error_log(json_encode($ids));
- if ($hasIdsSearch && $query->where === ["delete_time" => 0, "status" => 1]) {
- //在有ids搜索的前提下其他搜索都没有
- return [[], 0];
- }
- //组合数据
- return [$query->all(), $query->count()];
- }
- protected function getIdsByOperationalAdjustments($post)
- {
- $ids = [];
- if ($post["operational_adjustments_type"] != [] || $post["operational_adjustments"] != "") {
- $OperationalAdjustments = OperationalAdjustmentsService::getQuery();
- if ($post["operational_adjustments_type"] != []) {
- $OperationalAdjustments->andWhere(["type_first" => $post["operational_adjustments_type"]]);
- }
- if ($post["operational_adjustments"] != "") {
- $OperationalAdjustments->andWhere(["content" => $post["operational_adjustments"]]);
- }
- $OperationalAdjustments = array_column($OperationalAdjustments->select("distinct(accident_id)")->asArray()->all(), "accident_id");
- $ids = array_merge($ids, $OperationalAdjustments);
- }
- return $ids;
- }
- protected function getIdsByEmergencyResponse($post)
- {
- $ids = [];
- if ($post["emergency_response_type"] != [] || $post["emergency_response"] != "") {
- $EmergencyResponse = EmergencyResponseService::getEmergencyResponseQuery();
- if ($post["emergency_response_type"] != []) {
- $EmergencyResponse->andWhere(["type_first" => $post["emergency_response_type"]]);
- }
- if ($post["emergency_response"] != "") {
- $EmergencyResponse->andWhere(["like", "content", $post["emergency_response"]]);
- }
- $EmergencyResponse = array_column($EmergencyResponse->select("distinct(accident_id)")->asArray()->all(), "accident_id");
- $ids = array_merge($ids, $EmergencyResponse);
- }
- return $ids;
- }
- /**
- * 案例详情
- * @param $id
- * @return Response
- * @throws Exception
- */
- public function actionDetail($id): Response
- {
- $data = CaseService::getCaseDetail($id, "detail");
- //返回数据
- $model = "";
- $origin = AdminLogService::getOrigin($model, $this->getAllParams());
- AdminLogService::saveLogWithUpdateHistory($origin, $model, $data["id"], $data["title"], $this->getAllParams());
- return $this->asJson($data);
- }
- /**
- * 案例详情(通过日历里面点查看)
- * @param $id
- * @return Response
- * @throws Exception
- */
- public function actionDetailLog($id): Response
- {
- $data = CaseService::getCaseDetail($id, "detail");
- return $this->asJson($data);
- }
- /**
- * 案例对比
- * @param $ids
- * @return Response
- * @throws Exception
- */
- public function actionCompare($ids): Response
- {
- $ids = explode(",", $ids);
- $data = [];
- foreach ($ids as $id) {
- $data[] = CaseService::getCaseDetail($id, "detail");
- }
- return $this->asJson($data);
- }
- /**
- * @throws InvalidConfigException
- */
- public function actionStudyList(int $current = 1, int $page = 10)
- {
- $query = AccidentCasesStudy::find()->alias("s")
- ->join('LEFT JOIN', 'accident_cases a', 'a.id = s.accident_id')
- ->select(CaseService::getCaseStudySqlSelectInfo())
- ->asArray()
- ->limit($page)->offset(($current - 1) * $page);
- $this->initSequence($query, "s.id desc");
- $query = $this->addConditionToQueryNew('s.username','username', $query, true);
- $query = $this->addConditionToQueryNew('s.name','name', $query, true);
- $query = $this->addConditionToQueryNew('a.title','title', $query, true);
- $query = $this->addStartEndConditionToQueryNew("s.start_time",'start_time', $query);
- $data['data'] = $query->all();
- $data['total'] = $query->count();
- return $this->asJson($data);
- }
- /**
- * @throws InvalidConfigException
- */
- public function actionMyStudyList(int $current = 1, int $page = 10)
- {
- $query = AccidentCasesStudy::find()->alias("s")
- ->join('LEFT JOIN', 'accident_cases a', 'a.id = s.accident_id')
- ->select(CaseService::getCaseStudySqlSelectInfo())
- ->asArray()
- ->limit($page)->offset(($current - 1) * $page);
- $this->initSequence($query, "s.id desc");
- $query = $this->addConditionToQueryNew('s.username', $query, true);
- $query = $this->addConditionToQueryNew('s.name', $query, true);
- $query = $this->addConditionToQueryNew('a.title', $query, true);
- $query = $this->addStartEndConditionToQueryNew("s.start_time", $query);
- $query = $query->andWhere(["uid" => $this->userInfo->id]);
- $data['data'] = $query->all();
- $data['total'] = $query->count();
- return $this->asJson($data);
- }
- }
|