<?php

namespace app\admin\controller;

use app\admin\common\AdminController;
use app\common\api\ChuanglanSmsApi;
use app\common\api\TalentLogApi;
use app\common\model\MessageRecord;
use app\common\api\DictApi;
use app\common\api\EnterpriseApi;
use think\facade\Db;
use app\admin\model\User;
use app\common\api\MenuApi;
use app\admin\model\SysRelation;
use app\common\api\CompanyApi;
use app\common\api\IntegralRecordApi;
use app\common\state\ProjectState;
use app\common\state\IntegralState;
use app\common\model\IntegralRecord;
use app\common\model\IntegralDetail;
use app\common\state\CommonConst;

/**
 * Description of Talent
 *
 * @author sgq
 */
class IntegralVerify extends AdminController {

    public function fst_verify() {
        //test
        $enterprises = EnterpriseApi::getSimpleList();
        return view("", ["enterprises" => $enterprises]);
    }

    public function re_verify() {
        $enterprises = EnterpriseApi::getSimpleList();
        return view("", ["enterprises" => $enterprises]);
    }

    public function list() {
        $res = IntegralRecordApi::getListByProcess($this->request->param());
        return json($res);
    }

    public function detail() {
        $request = $this->request;
        $params = $request->param();
        $id = $params["id"];
        $row = IntegralRecordApi::getOne($id);
        foreach ($row["items"] as $key => $item) {
            $redis = \app\common\Redis::instance(\think\facade\Config::get("cache.stores.redis.select"));
            $integralItem = json_decode($redis->hGet("IntegralItem", $item["item_id"]), true);
            $integralProject = json_decode($redis->hGet("IntegralProject", $integralItem["projectId"]), true);
            $row["items"][$key]["itemName"] = $integralItem["name"];
            $row["items"][$key]["unit"] = $integralItem["unit"];
            $row["items"][$key]["projectName"] = $integralProject["name"];
            $row["items"][$key]["projectType"] = $integralProject["projectType"];
        }
        return view("", ["row" => $row]);
    }

    public function cancel_verify() {
        $params = $this->request->param();
        $ids = $params["ids"];
        $msg = $params["msg"];
        if ($msg == "") {
            return json(["msg" => "请填写审核不通过的原因"]);
        }
        $ids_arr = array_filter(explode(",", $ids));
        $counts = 0;
        foreach ($ids_arr as $id) {
            $record = IntegralRecordApi::getOne($id);
            $data["id"] = $id;
            if ($record["checkState"] == IntegralState::SUBMIT) {
                $data["checkState"] = IntegralState::VERIFY_FAIL;
                TalentLogApi::write(ProjectState::INTEGRAL, $id, IntegralState::VERIFY_FAIL, $msg, 1);
                IntegralRecord::update($data);
                $counts++;
            } else if ($record["checkState"] == IntegralState::VERIFY_PASS) {
                $data["checkState"] = IntegralState::REVERIFY_FAIL;
                TalentLogApi::write(ProjectState::INTEGRAL, $id, IntegralState::REVERIFY_FAIL, $msg, 1);
                IntegralRecord::update($data);
                $counts++;
            } else {
                return json(["msg" => "不在审核范围"]);
            }
        }
        return json(["code" => 200, sprintf("%d个申请已审核不通过", $counts)]);
    }

    /**
     * 预备积分库
     */
    public function pre_list() {
        if ($this->user["type"] == 1) {
            $message = [
                "typeName" => "晋江市现代产业体系人才积分评定", "address" => "聚才网/人才晋江微信公众号", "dep" => "中共晋江市委人才办、晋江市纪委监委驻市人力资源和社会保障局纪检监察组或晋江市公共就业和人才服务中心",
                "phone" => "0595-85633128", "email" => "jjrc85661234@163.com"
            ];
        } else {
            $message = [
                "typeName" => "晋江市集成电路产业优秀人才积分评定", "address" => "福建(晋江)集成电路产业园官方网站及微信公众号", "dep" => "集成电路产业园区",
                "phone" => "0595-82250007、0595-82250001", "email" => "jjjcdr@163.com"
            ];
        }
        $enterprises = EnterpriseApi::getSimpleList();
        return view("", ["message" => $message, "enterprises" => $enterprises]);
    }

    /**
     * 人才积分库
     */
    public function library() {
        $enterprises = EnterpriseApi::getSimpleList();
        return view("", ["enterprises" => $enterprises]);
    }

    public function veto() {
        $type = $this->request["type"];
        $card_type = $this->request["card_type"];
        $card_number = $this->request["card_number"];
        $enterprise_id = $this->request["enterprise_id"];
        $where = [];
        $enterpriseList = [];
        if ($type == 1) {
            $where[] = ["enterprise_id", "=", $enterprise_id];
            $enterpriseList = EnterpriseApi::getSimpleList([["type", "=", $this->user["type"]]]);
        } else {
            $where[] = ["card_type", "=", $card_type];
            $where[] = ["card_number", "=", $card_number];
            $whr[] = ["card_type", "=", $card_type];
            $whr[] = ["card_number", "=", $card_number];
            $whr[] = ["checkState", "=", IntegralState::SUCCESS];
            $irecord = Db::table("new_integral_record")->where($whr)->find();
        }
        $veto = Db::table("new_integral_veto")->where($where)->find();
        $veto["name"] = $irecord["name"];
        return json(["code" => 200, "veto" => $veto, "enterprises" => $enterpriseList]);
    }

    public function submitVeto() {
        $checkState = $this->request["checkState"];
        $checkMsg = $this->request["checkMsg"];
        $type = $this->request["type"];
        $card_type = $this->request["card_type"];
        $card_number = $this->request["card_number"];
        $enterprise_id = $this->request["enterprise_id"];
        $active = 0;
        if ($checkState == 1)
            $active = 1;
        if (!$type)
            return json(["msg" => "不确定的类型"]);
        if (!$checkMsg)
            return json(["msg" => "请填写意见"]);
        if ($type == 1) {
            if (!$enterprise_id)
                return json(["msg" => "不确定的企业"]);
            $where[] = ["enterprise_id", "=", $enterprise_id];
        } else {
            if (!$card_type || !$card_number)
                return json(["msg" => "不确定的个人"]);
            $where[] = ["card_type", "=", $card_type];
            $where[] = ["card_number", "=", $card_number];
        }
        $veto = Db::table("new_integral_veto")->where($where)->find();
        $checkActive = $veto["active"] == 1 ? 1 : 0;
        if ($active == $checkActive && $active == 1) {
            return json(["msg" => "已经被一票否决,无需重复操作"]);
        }
        if ($active == $checkActive && $active === 0) {
            return json(["msg" => "未被一票否决或者已经恢复,操作失败"]);
        }
        try {
            $data["active"] = $active;
            $data["description"] = $checkMsg;
            if ($veto) {
                $data["id"] = $veto["id"];
                $data["updateTime"] = date("Y-m-d H:i:s");
                $data["updateUser"] = $this->user["uid"];
            } else {
                if ($type == 1) {
                    $data["enterprise_id"] = $enterprise_id;
                } else {
                    $data["card_type"] = $card_type;
                    $data["card_number"] = $card_number;
                }
                $data["createTime"] = date("Y-m-d H:i:s");
                $data["createUser"] = $this->user["uid"];
            }
            Db::table("new_integral_veto")->save($data);
            return json(["code" => 200, "msg" => "提交成功"]);
        } catch (\think\db\exception\DbException $e) {
            return json(["msg" => "数据异常,操作失败\n\r" . $e->getMessage()]);
        }
    }

    /**
     * 历史积分
     */
    public function integralLog() {
        $cardType = $this->request["cardType"];
        $cardNumber = $this->request["cardNumber"];
        $where[] = ["card_type", "=", $cardType];
        $where[] = ["card_number", "=", $cardNumber];
        $where[] = ["checkState", "=", IntegralState::SUCCESS];
        $enterprise_ids = IntegralRecord::where($where)->column("enterprise_id");
        $enterprises = EnterpriseApi::getSimpleList([["id", "in", $enterprise_ids]]);
        return view("", ["enterprises" => $enterprises, "cardType" => $cardType, "cardNumber" => $cardNumber]);
    }

    public function selectNeedCheckData() {
        $params = $this->request->param();
        return json(["code" => 200, "obj" => IntegralRecordApi::getPublicList($params)]);
    }

    /**
     * 预备人才库-核查征信
     */
    public function prepareHczx() {
        $ids = $this->request->param("ids");
        $ids_arr = array_filter(explode(",", $ids));
        if (!$ids_arr) {
            $res = ["code" => 500, "msg" => "没有选择导出的名单"];
            echo sprintf("<script>TalentInfo.callBack(%s);</script>", json_encode($res));
        }
        $where[] = ["ir.id", "in", $ids_arr];
        $list = IntegralRecord::alias("ir")->leftJoin("un_enterprise e", "e.id=ir.enterprise_id")->field("ir.name,ir.card_type,ir.card_number,e.name as enterpriseName,e.description")->where($where)->select();
        if (!$list) {
            $res = ["code" => 500, "msg" => "没有可以导出的内容"];
            echo sprintf("<script>IntegralInfo.callBack(%s);</script>", json_encode($res));
        }
        $columns = ["序号", "姓名", "证件类型", "证件号码", "工作单位", "备注"];
        $rows = [];
        $i = 1;
        $card_types = DictApi::selectByParentCode("card_type");
        foreach ($list as $item) {
            $row = [
                $i, $item["name"], $card_types[$item["card_type"]], $item["card_number"], $item["enterpriseName"], $item["description"]
            ];
            $rows[] = $row;
            $i++;
        }
        $filename = "积分申报核查征信名单导出";
        if ($rows) {
            export($columns, $rows, $filename);
            exit();
        }
        echo "<script>parent.layer.alert('没有可以导出的数据');</script>";
    }

    /**
     * 预备人才库-征信通过
     */
    public function hczxPass() {
        $params = $this->request->param();
        $ids = $params["ids"];
        $ids = array_filter(explode(",", $ids));

        $msg = "征信通过";
        $state = IntegralState::ZX_PASS; //征信通过

        $total = count($ids);
        $error = 0;
        $success = 0;
        foreach ($ids as $id) {
            $record = IntegralRecordApi::getOne($id);
            if ($record["checkState"] != IntegralState::REVERIFY_PASS) {
                $error++;
                continue;
            }
            if (IntegralRecordApi::setPublic($id, $state, $msg)) {
                $success++;
            } else {
                $error++;
            }
        }
        return json(["code" => 200, "msg" => sprintf("核查征信完成:共提交%d个人才,通过%d个,失败%d个", $total, $success, $error)]);
    }

    /**
     * 预备人才库-征信失信
     */
    public function hczxReject() {
        $params = $this->request->param();
        $id = $params["id"];
        $msg = $params["outMsg"];
        if (!$msg)
            return json(["msg" => "请填写审核意见"]);
        $msg = "征信失信:" . $msg;
        $state = IntegralState::ZX_FAIL; //征信不通过
        $record = IntegralRecordApi::getOne($id);
        if ($record["checkState"] != IntegralState::REVERIFY_PASS) {
            return json(["msg" => "当前记录不是待核查征信状态,无法核查"]);
        }
        if (IntegralRecordApi::setPublic($id, $state, $msg)) {
            return json(["code" => 200, "msg" => "已设置征信失信"]);
        }
        return json(["msg" => "设置征信失信失败"]);
    }

    /**
     * 预备人才库-公示预览
     */
    public function publicExportBefore() {
        $params = $this->request->param();
        $ids_arr = array_filter(explode(",", $params["ids"]));
        $columns = ["序号", "批次", "姓名", "证件类型", "证件号码", "工作单位", "申请积分项目", "拟认定获得积分", "审核状态", "备注"];
        if ($ids_arr) {
            $where[] = ["ir.id", "in", $ids_arr];
            $list = IntegralRecord::alias("ir")->where($where)
                            ->leftJoin("sys_batch b", "b.id=ir.batch_id")
                            ->leftJoin("un_enterprise e", "e.id=ir.enterprise_id")
                            ->leftJoin("(select description,mainId,last_state,new_state,state,createTime from new_talent_checklog where md5(concat(createTime,mainId,`type`)) in (select md5(concat(max(createTime),mainId,`type`)) from `new_talent_checklog` where `type`=20 and `step` is null and active=1 and typeFileId is null group by mainId,`type`)) tl", "`tl`.`mainId`=ir.id")
                            ->field("ir.*,e.name as enterpriseName,b.batch as apply_year,tl.state as real_state,tl.last_state,tl.description")->order("createTime asc")->select();
            $rows = [];
            $i = 1;
            $card_types = DictApi::selectByParentCode("card_type");
            foreach ($list as $item) {
                $tmp_items = [];
                $total_points = 0;
                foreach ($item["detail"] as $_item) {
                    $integral_item_info = getCacheById("IntegralItem", $_item["item_id"]);
                    $tmp_items[] = sprintf("%s(%s%s)+%d积分", $integral_item_info["name"], $_item["amount"], $integral_item_info["unit"], $_item["point"]);
                    $total_points += $_item["point"];
                }
                $row = [
                    $i, $item["apply_year"], $item["name"], $card_types[$item["card_type"]], $item["card_number"], $item["enterpriseName"], implode(";", $tmp_items), $total_points, $item["checkState"] == IntegralState::ZX_PASS ? "审核通过" : "审核不通过", $item["description"]
                ];
                $rows[] = $row;
                $i++;
            }
        }
        if ($rows) {
            $filename = "积分申报公示预览导出";
            export($columns, $rows, $filename);
            exit();
        }
        echo "<script>parent.layer.alert('没有可以导出的数据');</script>";
    }

    /**
     * 预备人才库-公示导出
     */
    public function publicExport() {
        $params = $this->request->param();
        $columns = ["序号", "批次", "姓名", "证件类型", "证件号码", "工作单位", "申请积分项目", "当前总积分", "当前人才层次", "增加后的总积分", "增加积分后的层次", "审核状态", "备注"];
        $startTime = $params["startTime"];
        $endTime = $params["endTime"];
        if (!strtotime($startTime) || !strtotime($endTime))
            return json(["msg" => "时间格式错误"]);
        $where[] = ["ir.checkState", "=", IntegralState::ANNOUNCED];
        $where[] = ["publicBatch", "between", [$startTime, $endTime]];
        $list = IntegralRecord::alias("ir")->where($where)
                        ->leftJoin("sys_batch b", "b.id=ir.batch_id")
                        ->leftJoin("un_enterprise e", "e.id=ir.enterprise_id")
                        ->leftJoin("(select description,mainId,last_state,new_state,state,createTime from new_talent_checklog where md5(concat(createTime,mainId,`type`)) in (select md5(concat(max(createTime),mainId,`type`)) from `new_talent_checklog` where `type`=20 and `step` is null and active=1 and typeFileId is null group by mainId,`type`)) tl", "`tl`.`mainId`=ir.id")
                        ->field("ir.*,e.name as enterpriseName,b.batch as apply_year,tl.state as real_state,tl.last_state,tl.description")->order("createTime asc")->select();
        $rows = [];
        $i = 1;
        $card_types = DictApi::selectByParentCode("card_type");
        foreach ($list as $item) {
            $tmp_items = [];
            $total_points = 0;
            foreach ($item["detail"] as $_item) {
                $integral_item_info = getCacheById("IntegralItem", $_item["item_id"]);
                $tmp_items[] = sprintf("%s(%s%s)+%d积分", $integral_item_info["name"], $_item["amount"], $integral_item_info["unit"], $_item["point"]);
                $total_points += $_item["point"];
            }
            $where = [];
            $where[] = ["card_type", "=", $item["card_type"]];
            $where[] = ["card_number", "=", $item["card_number"]];
            $log = Db::table("new_integral_log")->where($where)->order("createTime desc")->find();
            $row = [
                $i, $item["apply_year"], $item["name"], $card_types[$item["card_type"]], $item["card_number"], $item["enterpriseName"], implode(";", $tmp_items), $log["nowPoints"], CommonConst::getLayerNameByLayer($log["talentLevel"]), $log["nowPoints"] + $total_points, CommonConst::getLayerNameByLayer(CommonConst::getLayerByPoints($log["nowPoints"] + $total_points)), $item["checkState"] == IntegralState::ANNOUNCED ? "审核通过" : "审核不通过", $item["description"]
            ];
            $rows[] = $row;
            $i++;
        }
        if ($rows) {
            $filename = "积分申报公示导出";
            export($columns, $rows, $filename);
            exit();
        }
        echo "<script>parent.layer.alert('没有可以导出的数据');</script>";
    }

    /**
     * 预备人才库-公示
     */
    public function preparePublic() {
        $params = $this->request->param();
        $ids = $params["ids"];
        $publicBatch = $params["batch"];
        if (!$publicBatch || strlen($publicBatch) != 6 || !is_numeric($publicBatch))
            return json(["msg" => "公示批次错误"]);

        $isMessage = $params["isMessage"] == 1 ? true : false;
        if ($isMessage && (!$params["typeName"] || !$params["address"] || !$params["publicStartTime"] || !$params["publicEndTime"] || !$params["dep"] || !$params["phone"] || !$params["email"])) {
            return json(["msg" => "短信参数不能为空"]);
        }


        $ids = array_filter(explode(",", $ids));

        $msg = "已公示";
        $state = IntegralState::ANNOUNCED; //公示

        $total = count($ids);
        $error = 0;
        $success = 0;
        $phones = [];
        foreach ($ids as $id) {
            $record = IntegralRecordApi::getOne($id);
            if ($record["checkState"] != IntegralState::ZX_PASS) {
                $error++;
                continue;
            }
            if (IntegralRecordApi::setPublic($id, $state, $msg, $publicBatch)) {
                $success++;
                $phones[] = $record["enterprise"]->agentPhone;
            } else {
                $error++;
            }
        }
        $phones = array_unique(array_filter($phones));
        if ($isMessage && $phones) {
            $sms = new \app\common\api\ChuanglanSmsApi();
            $tpl_content = sprintf("【晋江市人才服务平台】您好!您提交申请的%s已完成初步审核,现通过%s将审核结果予以公示,公示时间%s至%s。公示期间如有异议,请及时向%s反映。电话%s,电子邮箱%s。",
                    $params["typeName"], $params["address"], $params["publicStartTime"], $params["publicEndTime"], $params["dep"], $params["phone"], $params["email"]);
            while ($phone = array_shift($phones)) {
                $result = $sms->sendSMS($phone, $tpl_content);

                $result = json_decode($result, true);

                $recordId = getStringId();

                $record_data = [
                    'id' => $recordId,
                    'bizId' => $result["msgId"],
                    'type' => 2,
                    'smsType' => 1,
                    'phone' => $phone,
                    'params' => '公示',
                    'templateCode' => $tpl_content,
                    'state' => $result['code'] == 0 ? 2 : 3,
                    'sendingDate' => date("Y-m-d H:i:s", time()),
                    'createTime' => date("Y-m-d H:i:s", time()),
                    'msg' => $result['errorMsg']
                ];

                MessageRecord::create($record_data);
            }
        }
        return json(["code" => 200, "msg" => sprintf("公示完成:共提交%d个人才,通过%d个,失败%d个", $total, $success, $error)]);
    }

    /**
     * 预备人才库-公示再审核
     */
    public function prepareCheck() {
        $params = $this->request->param();
        $id = $params["id"];
        $checkState = $params["checkState"];
        $msg = $params["checkMsg"];
        if (!$msg)
            return json(["msg" => "请填写审核意见"]);
        if ($checkState == 1) {
            $msg = "公示再审核通过:" . $msg;
            $state = IntegralState::ANNOUNCED_REVERIFY_PASS; //公示再审核通过
        } else {
            $msg = "公示再审核不通过:" . $msg;
            $state = IntegralState::ANNOUNCED_REVERIFY_FAIL; //公示再审核不通过
        }
        $record = IntegralRecordApi::getOne($id);
        if ($record["checkState"] != IntegralState::ANNOUNCED) {
            return json(["msg" => "当前记录不是公示状态,无法审核"]);
        }
        if (IntegralRecordApi::setPublic($id, $state, $msg)) {
            return json(["code" => 200, "msg" => "公示再审核完成"]);
        }
        return json(["msg" => "公示再审核失败"]);
    }

    /**
     * 预备人才库-公示通过(批量)
     */
    public function publicPass() {
        $params = $this->request->param();
        $ids = $params["ids"];
        $ids = array_filter(explode(",", $ids));
        $msg = "公示再审核批量通过";
        $state = IntegralState::ANNOUNCED_REVERIFY_PASS; //公示再审核通过

        $total = count($ids);
        $error = 0;
        $success = 0;
        foreach ($ids as $id) {
            $record = IntegralRecordApi::getOne($id);
            if ($record["checkState"] != IntegralState::ANNOUNCED) {
                $error++;
                continue;
            }
            if (IntegralRecordApi::setPublic($id, $state, $msg)) {
                $success++;
            } else {
                $error++;
            }
        }
        return json(["code" => 200, "msg" => sprintf("公示再审核完成:共提交%d个人才,通过%d个,失败%d个", $total, $success, $error)]);
    }

    /**
     * 预备人才库-公布预览
     */
    public function publishExportBefore() {
        $params = $this->request->param();
        $ids = $params["ids"];
        $ids = array_filter(explode(",", $ids));
        if ($ids) {
            $where[] = ["ir.id", "in", $ids];
            $list = IntegralRecord::alias("ir")->where($where)
                            ->leftJoin("sys_batch b", "b.id=ir.batch_id")
                            ->leftJoin("un_enterprise e", "e.id=ir.enterprise_id")
                            ->leftJoin("(select description,mainId,last_state,new_state,state,createTime from new_talent_checklog where md5(concat(createTime,mainId,`type`)) in (select md5(concat(max(createTime),mainId,`type`)) from `new_talent_checklog` where `type`=20 and `step` is null and active=1 and typeFileId is null group by mainId,`type`)) tl", "`tl`.`mainId`=ir.id")
                            ->field("ir.*,e.name as enterpriseName,b.batch as apply_year,tl.state as real_state,tl.last_state,tl.description")->order("createTime asc")->select();
            $rows = [];
            $i = 1;

            $card_types = DictApi::selectByParentCode("card_type");
            foreach ($list as $item) {
                $tmp_items = [];
                $total_points = 0;
                foreach ($item["detail"] as $_item) {
                    $integral_item_info = getCacheById("IntegralItem", $_item["item_id"]);
                    $tmp_items[] = sprintf("%s(%s%s)+%d积分", $integral_item_info["name"], $_item["amount"], $integral_item_info["unit"], $_item["point"]);
                    $total_points += $_item["point"];
                }
                $row = [
                    $i, $item["apply_year"], $item["name"], $card_types[$item["card_type"]], $item["card_number"], $item["enterpriseName"], implode(";", $tmp_items), $total_points, $item["checkState"] == IntegralState::ANNOUNCED_REVERIFY_PASS ? "审核通过" : "审核不通过", $item["description"]
                ];
                $rows[] = $row;
                $i++;
            }
        }
        $columns = ["序号", "批次", "姓名", "证件类型", "证件号码", "工作单位", "申请积分项目", "拟认定获得积分", "审核状态", "备注"];
        $filename = "积分申报" . date("Ym") . "公布预览名单导出(公示批次-" . $list[0]["publicBatch"] . ")";
        if ($rows) {
            export($columns, $rows, $filename);
            exit();
        }
        echo "<script>parent.layer.alert('没有可以导出的数据');</script>";
    }

    /**
     * 预备人才库-公布导出
     */
    public function publishExport() {
        $params = $this->request->param();
        $startTime = $params["startTime"];
        $endTime = $params["endTime"];
        if (!strtotime($startTime) || !strtotime($endTime))
            return json(["msg" => "时间格式错误"]);
        $where[] = ["ir.checkState", "=", IntegralState::PUBLISH_PASS];
        $where[] = ["ir.getTime", "between", [$startTime, $endTime]];

        $list = IntegralRecord::alias("ir")->where($where)
                        ->leftJoin("sys_batch b", "b.id=ir.batch_id")
                        ->leftJoin("un_enterprise e", "e.id=ir.enterprise_id")
                        ->leftJoin("(select description,mainId,last_state,new_state,state,createTime from new_talent_checklog where md5(concat(createTime,mainId,`type`)) in (select md5(concat(max(createTime),mainId,`type`)) from `new_talent_checklog` where `type`=20 and `step` is null and active=1 and typeFileId is null group by mainId,`type`)) tl", "`tl`.`mainId`=ir.id")
                        ->field("ir.*,e.name as enterpriseName,b.batch as apply_year,tl.state as real_state,tl.last_state,tl.description")->order("createTime asc")->select();
        $rows = [];
        $i = 1;

        $card_types = DictApi::selectByParentCode("card_type");
        foreach ($list as $item) {
            $tmp_items = [];
            $total_points = 0;
            foreach ($item["detail"] as $_item) {
                $integral_item_info = getCacheById("IntegralItem", $_item["item_id"]);
                $tmp_items[] = sprintf("%s(%s%s)+%d积分", $integral_item_info["name"], $_item["amount"], $integral_item_info["unit"], $_item["point"]);
                $total_points += $_item["point"];
            }
            $row = [
                $i, $item["apply_year"], $item["name"], $card_types[$item["card_type"]], $item["card_number"], $item["enterpriseName"], implode(";", $tmp_items), $total_points, $item["checkState"] == IntegralState::PUBLISH_PASS ? "审核通过" : "审核不通过", $item["description"]
            ];
            $rows[] = $row;
            $i++;
        }
        $columns = ["序号", "批次", "姓名", "证件类型", "证件号码", "工作单位", "申请积分项目", "拟认定获得积分", "审核状态", "备注"];
        $filename = "积分申报" . date("Ym") . "公布名单导出(公示批次-" . $list[0]["publicBatch"] . ")";
        if ($rows) {
            export($columns, $rows, $filename);
            exit();
        }
        echo "<script>parent.layer.alert('没有可以导出的数据');</script>";
    }

    /**
     * 预备人才库-公布
     */
    public function publish() {
        $params = $this->request->param();
        $id = $params["id"];
        $msg = $params["checkMsg"];
        $checkState = $params["checkState"];
        $batch = $params["batch"];
        if ($checkState == 1) {
            $state = IntegralState::PUBLISH_PASS;
            $msg = "公布审核通过:" . $msg;
        } else {
            $state = IntegralState::PUBLISH_FAIL;
            $msg = "公布审核不通过:" . $msg;
        }
        if (!$batch || !strtotime($batch))
            return json(["msg" => "公布批次时间错误"]);
        if (!$msg)
            return json(["msg" => "请填写审核意见"]);
        $state = IntegralState::PUBLISH_PASS; //公示再审核通过
        $batch = $params["batch"];
        if (!strtotime($batch))
            return json(["msg" => "公布批次时间错误"]);
        $record = IntegralRecordApi::getOne($id);
        if ($record["checkState"] != IntegralState::ANNOUNCED_REVERIFY_PASS) {
            return json(["msg" => "当前记录不是公示再审核通过状态,无法审核"]);
        }
        if (IntegralRecordApi::setPublic($id, $state, $msg, $batch)) {
            return json(["code" => 200, "msg" => "公布审核完成"]);
        }
        return json(["msg" => "公布审核失败"]);
    }

    /**
     * 预备人才库-批量公布通过
     */
    public function preparePublish() {
        $params = $this->request->param();
        $ids = $params["ids"];
        $ids = array_filter(explode(",", $ids));
        $msg = "批量公布";
        $state = IntegralState::PUBLISH_PASS; //公示再审核通过
        $batch = $params["batch"];
        if (!strtotime($batch))
            return json(["msg" => "公布批次时间错误"]);
        $total = count($ids);
        $error = 0;
        $success = 0;
        foreach ($ids as $id) {
            $record = IntegralRecordApi::getOne($id);
            if ($record["checkState"] != IntegralState::ANNOUNCED_REVERIFY_PASS) {
                $error++;
                continue;
            }
            if (IntegralRecordApi::setPublic($id, $state, $msg, $batch)) {
                $success++;
            } else {
                $error++;
            }
        }
        return json(["code" => 200, "msg" => sprintf("公布完成:共提交%d个人才,通过%d个,失败%d个", $total, $success, $error)]);
    }

    /**
     * 预备人才库-批量发放人才码
     */
    public function prepareCertification() {
        $lockFile = fopen("send_certificate.lock", "a");
        if (flock($lockFile, LOCK_EX | LOCK_NB)) {//文件锁(独占)
            $params = $this->request->param();
            $ids = array_filter(explode(",", $params["ids"]));
            Db::startTrans();
            $user = $this->user;
            try {
                $record_list = IntegralRecordApi::getListByIds($ids);
                $year = date("Y");
                foreach ($record_list as $record) {
                    if ($record["checkState"] != IntegralState::PUBLISH_PASS) {
                        Db::rollback();
                        return json(["msg" => "只能对公布通过的对象发放积分,请核查待发放积分名单后再重新发放积分"]);
                    }

                    $data["id"] = $record["id"];
                    $data["checkState"] = IntegralState::SUCCESS;
                    $data["isPublic"] = 5;
                    Db::table("new_integral_record")->update($data);

//写入日志
                    $log["last_state"] = IntegralState::PUBLISH_PASS;
                    $log["id"] = getStringId();
                    $log["state"] = $log["new_state"] = IntegralState::SUCCESS;
                    $log["type"] = ProjectState::INTEGRAL;
                    $log["mainId"] = $record["id"];
                    $log["companyId"] = $user["companyId"];
                    $log["active"] = 1;
                    $log["description"] = "积分申报成功";
                    $log["createUser"] = sprintf("%s(%s)", $user["account"], $user["companyName"] ?: $user["rolename"]);
                    $log["createTime"] = date("Y-m-d H:i:s");
                    Db::table("new_talent_checklog")->insert($log);
                }
                Db::commit();
                $_ids = array_column($record_list, "id");
                for ($i = 0; $i < count($_ids); $i++) {
                    queue("app\job\Integral", ["type" => 1, "id" => $_ids[$i]]);
                }
                return json(["code" => 200, "msg" => "发放积分成功"]);
            } catch (\Exception $e) {
                Db::rollback();
                return json(["msg" => "发放积分失败:" . $e->getMessage()]);
            }
            flock($lockFile, LOCK_UN);
        } else {
            return json(["msg" => "同一时间只能有一个管理员进行发放积分操作"]);
        }
    }

    /**
     * 预备人才库-撤销公布
     */
    public function pre_cancel_publish() {
        
    }

    /**
     * 初审-提交未保存
     * @param \think\Request $request
     * @param type $record
     * @return type json
     */
    private function fstCheck(\think\Request $request, $record) {
        $params = $request->param();
        if ($params["checkState"] == 1) {
//审核成功,并取消设置越过部门并审
            $log_checkState = $checkState = IntegralState::VERIFY_PASS; //初审成功
        } else if ($params["checkState"] == 2) {
//审核驳回并记录需要修改的字段和上传文件
            $checkState = IntegralState::SAVE; //退回材料编辑状态
            $log_checkState = IntegralState::VERIFY_REJECT; //日志记录拒绝状态
        } else {
            $checkState = IntegralState::VERIFY_FAIL;
        }
        $log = TalentLogApi::getLastLog($record["id"], ProjectState::INTEGRAL);
        if (!$log)
            return json(["msg" => "日志数据异常,保存失败"]);
        if ($log["active"] == 0) {
            TalentLogApi::rewrite($log["id"], [$log_checkState, $checkState], $params["checkMsg"]);
        } else {
            TalentLogApi::write(ProjectState::INTEGRAL, $record["id"], [$log_checkState, $checkState], $params["checkMsg"]);
        }
        $data["id"] = $record["id"];
        $data["modify_files"] = $params["files"];
        $data["modify_fields"] = $params["fields"];
        IntegralRecord::update($data);
        return json(["code" => 200, "msg" => "保存成功"]);
    }

    /**
     * 初审-提交审核
     * @param type $record
     * @return type json
     */
    private function fstSubmitCheck($record) {
        $log = TalentLogApi::getLastLog($record["id"], ProjectState::INTEGRAL);
        if (!$log || $log["active"] == 1)
            return json(["msg" => "请先保存审核状态,再提交审核"]);
        if ($log["new_state"] == IntegralState::VERIFY_PASS) {
            $data["modify_files"] = null;
            $data["modify_fields"] = null;
        }
        $data["id"] = $record["id"];
        $data["checkState"] = $log["new_state"];
        IntegralRecord::update($data);
        TalentLogApi::setActive($log["id"], 1);
        $userIds = [];
        if (in_array($log["state"], [IntegralState::VERIFY_PASS])) {
            //初审成功需要发送短信给复核部门,复核的其它状态发送通知给用户,调用此方法的还有基础审核的每个状态都要发送通知给用户
            //从复核权限,逆推复核人员
            $codes = ["integralVerify_reCheck"];
            $menuIds = MenuApi::getMenuIdsByCodes($codes);

            $where = [];
            $where[] = ["menuid", "in", $menuIds];
            $roleIds = SysRelation::where($where)->group("roleid")->having("count(*)=" . count($codes))->column("roleid");

            $where = [];
            $where[] = ["status", "=", 1];
            $where[] = ["type", "=", $this->user["type"]];
            $where[] = ["roleid", "<>", 1];
            $regstr = ",(" . implode("|", $roleIds) . "),";
            $whereRaw = "concat(',',roleid,',') REGEXP '$regstr'";
            $userIds = User::where($where)->whereRaw($whereRaw)->column("id");
        }
        $this->sendMsgByState($record, $log["state"], $userIds);
        return json(["code" => 200, "msg" => "审核成功"]);
    }

    /**
     * 复审-提交未保存
     * @param \think\Request $request
     * @param type $record
     * @param type json
     */
    private function reCheck(\think\Request $request, $record) {
        $params = $request->param();
        $data["modify_files"] = null;
        $data["modify_fields"] = null;
        $totalPoints = 0;
        if ($params["checkState"] == 1) {
            //审核成功
            $log_checkState = $checkState = IntegralState::REVERIFY_PASS; //复核成功
            foreach ($record->detail as $item) {
                $result = IntegralRecordApi::calIntegral($record["enterprise_id"], $record["card_type"], $record["card_number"], $item["item_id"], $item["amount"]);
                $totalPoints += $result->points;
                $iData["id"] = $item["id"];
                $iData["point"] = $result->points;
                IntegralDetail::update($iData);
            }
            $data["totalPoints"] = $totalPoints;
        } else if ($params["checkState"] == 2) {
            //审核驳回并记录需要修改的字段和上传文件
            $checkState = IntegralState::SUBMIT; //退回待初审
            $log_checkState = IntegralState::REVERIFY_REJECT; //日志记录拒绝状态
            $data["modify_files"] = $params["files"];
            $data["modify_fields"] = $params["fields"];
        } else {
            $log_checkState = $checkState = IntegralState::REVERIFY_FAIL; //审核失败
        }
        $log = TalentLogApi::getLastLog($record["id"], ProjectState::INTEGRAL);
        if (!$log)
            return json(["msg" => "日志数据异常,保存失败"]);
        if ($log["active"] == 0) {
            TalentLogApi::rewrite($log["id"], [$log_checkState, $checkState], $params["checkMsg"]);
        } else {
            TalentLogApi::write(ProjectState::INTEGRAL, $record["id"], [$log_checkState, $checkState], $params["checkMsg"]);
        }
        $data["id"] = $record["id"];
        IntegralRecord::update($data);
        return json(["code" => 200, "msg" => "保存成功"]);
    }

    /**
     * 复审-提交审核
     * @param type $record
     * @return type json
     */
    private function reSubmitCheck($record) {
        $log = TalentLogApi::getLastLog($record["id"], ProjectState::INTEGRAL);
        if (!$log || $log["active"] == 1)
            return json(["msg" => "请先保存审核状态,再提交审核"]);
        $data["id"] = $record["id"];
        $data["checkState"] = $log["new_state"];
        IntegralRecord::update($data);
        TalentLogApi::setActive($log["id"], 1);
        $userIds = [];
        if (in_array($log["state"], [IntegralState::REVERIFY_PASS, IntegralState::REVERIFY_REJECT])) {
            //复核成功需要发送短信给征信部门,复核的其它状态发送通知给用户,调用此方法的还有基础审核的每个状态都要发送通知给用户
            //从征信审核权限,逆推征信部门

            if ($data["checkState"] == IntegralState::REVERIFY_PASS) {
                $codes = ["integralVerify_hczxReject", "integralVerify_hczxPass"];
            } else {
                $codes = ["integralVerify_firstCheck"];
            }

            $menuIds = MenuApi::getMenuIdsByCodes($codes);

            $where = [];
            $where[] = ["menuid", "in", $menuIds];
            $roleIds = SysRelation::where($where)->group("roleid")->having("count(*)=" . count($codes))->column("roleid");

            $where = [];
            $where[] = ["status", "=", 1];
            $where[] = ["type", "=", $this->user["type"]];
            $where[] = ["roleid", "<>", 1];
            $regstr = ",(" . implode("|", $roleIds) . "),";
            $whereRaw = "concat(',',roleid,',') REGEXP '$regstr'";
            $userIds = User::where($where)->whereRaw($whereRaw)->column("id");
        }
        $this->sendMsgByState($record, $log["state"], $userIds);
        return json(["code" => 200, "msg" => "审核成功"]);
    }

    private function sendMsgByState($record, $state, $userIds = []) {
        $phones = [];
        $template = "";
        $type = 0;
        $processName = "";
        $userId = 0;
        $name = null;
        switch ($state) {
            case IntegralState::VERIFY_PASS://初审通过发送短信通知并审部门
                $type = 1;
                $processName = "积分申报-初级审核";
                $template = "【晋江市人才服务平台】您的部门有新的积分申报需要审批,请及时登录审批系统处理。";
                break;
            case IntegralState::VERIFY_REJECT; //初审驳回发送短信通知用户
                $type = 2;
                $processName = "积分申报-初级审核";
                $template = "【晋江市人才服务平台】尊敬的用户,您提交的积分申报审核驳回,原因是:{$log['description']},请及时登录申报系统修改并重新提交。";
                break;
            case IntegralState::VERIFY_FAIL://初审不通过发送短信通知用户
                $type = 2;
                $processName = "积分申报-初级审核";
                $template = "【晋江市人才服务平台】尊敬的用户,您提交的积分申报审核不通过,原因是:{$log['description']}。";
                break;
            case IntegralState::REVERIFY_PASS://复核通过发短信通知征信部门
                $type = 1;
                $processName = "积分申报-复审";
                $template = "【晋江市人才服务平台】有新的积分申报通过复审进入征信阶段,请及时登录审批系统处理。";
                break;
            case IntegralState::REVERIFY_REJECT://复核驳回发短信通知初审部门
                $type = 1;
                $processName = "积分申报-复审";
                $template = "【晋江市人才服务平台】有积分申报在复审阶段被驳回,原因是:{$log['description']},请及时登录审批系统处理。";
                break;
            case IntegralState::REVERIFY_FAIL://并审驳回发送短信通知初审部门
                $type = 2;
                $processName = "积分申报-复审";
                $template = "【晋江市人才服务平台】尊敬的用户,您提交的积分申报审核不通过,原因是:{$log['description']}。";
                break;
        }
        if ($type == 1) {
            $where = [];
            $where[] = ["id", "in", $userIds];
            $phones = User::where($where)->column("phone");
            $phones = array_unique(array_filter($phones));
        }
        if ($type == 2) {
            $ep = EnterpriseApi::getOne($record['enterprise_id']);
            $phones[] = $ep->agentPhone;
            $userId = $ep->id;
            $name = $ep->name;
        }
        if ($phones && $template) {
            while ($phone = array_shift($phones)) {
                $smsapi = new ChuanglanSmsApi();
                $result = $smsapi->sendSMS($phone, $template);
                $result = json_decode($result, true);
                $id = getStringId();
                $record_data = [
                    'id' => $id,
                    'userId' => $userId,
                    'bizId' => $result["msgId"],
                    'type' => $type,
                    'smsType' => 2,
                    'name' => $name,
                    'phone' => $phone,
                    'params' => $processName,
                    'templateCode' => $template,
                    'state' => $result['code'] == 0 ? 2 : 3,
                    'sendingDate' => date("Y-m-d H:i:s", time()),
                    'createTime' => date("Y-m-d H:i:s", time()),
                    'msg' => $result['errorMsg']
                ];

                MessageRecord::create($record_data);
            }
        }
    }

    public function check() {
//公共调度方法
        $request = $this->request;
        $params = $request->param();
        $check = $params["checkState"];
        $check_msg = trim($params["checkMsg"]);
        $files = $params["files"];
        $fields = $params["fields"];
        $id = $params["id"];
        $record = IntegralRecordApi::getOne($id);
        $checkState = $record["checkState"];
        if (!$record) {
            return json(["msg" => "数据错误"]);
        }
        if (!$check) {
            return json(["msg" => "请选择审核状态"]);
        }
        if (!$check_msg) {
            return json(["msg" => "请填写审核说明"]);
        }
        if ($check == 2 && !$files && !$fields) {
            return json(["msg" => "请选择可修改的字段或项目"]);
        }
        if ($checkState == IntegralState::SUBMIT) {
            return $this->fstCheck($request, $record);
        } else if ($checkState == IntegralState::VERIFY_PASS) {
            return $this->reCheck($request, $record);
        } else {
            return json(["msg" => "不在审核范围内,保存失败"]);
        }
    }

    public function submitCheck() {
//公共调度方法
        $id = $this->request->param("id");
        $record = IntegralRecordApi::getOne($id);
        $checkState = $record["checkState"];
        if (!$record) {
            return json(["msg" => "数据错误"]);
        }
        if ($checkState == IntegralState::SUBMIT) {
            return $this->fstSubmitCheck($record);
        } else if ($checkState == IntegralState::VERIFY_PASS) {
            return $this->reSubmitCheck($record);
        } else {
            return json(["msg" => "不在审核范围内,审核失败"]);
        }
    }

    public function validateIsCheck() {
        $params = $this->request->param();
        $id = $params["id"];
        $record = IntegralRecordApi::getOne($id);
        $enterprise = \app\common\model\Enterprise::findOrEmpty($record["enterprise_id"]);
        if ($record) {
            $items = $record["detail"]->toArray(); //项目明细
            $checkState = $record["checkState"];
            if (in_array($checkState, [IntegralState::SUBMIT, IntegralState::VERIFY_PASS])) {
                $fields = DictApi::getIntegralFields();
                $field_tmp = [];
                foreach ($fields as $key => $field) {
                    $field_tmp[] = ["key" => $key, "value" => $field];
                }
                $record["files"] = $record["modify_files"];
                $record["fields"] = array_filter(explode(",", $record["modify_fields"]));
                return json(["code" => 200, "obj" => ["record" => $record, "fieldList" => $field_tmp]]);
            } else {
                return json(["msg" => "该申报不在审核范围内,无法审核"]);
            }
        }
    }

    public function findFieldsAndFiles() {
        $id = $this->request["id"];
        $record = IntegralRecordApi::getOne($id);
        $lastLog = TalentLogApi::getLastLog($id, ProjectState::INTEGRAL);
        $responseObj = new \stdClass();
        if ($record["checkState"] == IntegralState::SAVE && $lastLog["state"] == IntegralState::VERIFY_REJECT) {
            $items = $record["detail"]->toArray(); //项目明细
            $checkState = $record["checkState"];
            $fields = DictApi::getIntegralFields();
            $field_tmp = [];
            foreach ($fields as $key => $field) {
                $field_tmp[] = ["key" => $key, "value" => $field];
            }
            $record["files"] = $record["modify_files"];
            $record["fields"] = array_filter(explode(",", $record["modify_fields"]));
            return json(["code" => 200, "obj" => ["record" => $record, "fieldList" => $field_tmp]]);
            $responseObj->code = 200;
            $responseObj->id = $id;
            $responseObj->obj = ["record" => $record, "fieldList" => $field_tmp];
        } else {
            $responseObj->msg = "不是驳回状态不可以编辑驳回内容";
        }
        return json($responseObj);
    }

    public function updateFieldsAndFiles() {
        $id = $this->request["id"];
        $fields = array_filter(explode(",", $this->request["fields"]));
        $files = array_filter(explode(",", $this->request["files"]));

        $record = IntegralRecordApi::getOne($id);
        $lastLog = TalentLogApi::getLastLog($id, ProjectState::INTEGRAL);
        $responseObj = new \stdClass();
        if ($record["checkState"] == IntegralState::SAVE && $lastLog["state"] == IntegralState::VERIFY_REJECT) {
            if (!$fields && !$files) {
                $responseObj->msg = "请选择可修改的字段或附件!";
                return json($responseObj);
            }
            try {
                $data["id"] = $id;
                $data["modify_fields"] = $fields ? implode(",", $fields) : null;
                $data["modify_files"] = $files ? implode(",", $files) : null;
                IntegralRecord::update($data);
                $responseObj->code = 200;
                $responseObj->msg = "驳回字段修改成功";
                return json($responseObj);
            } catch (\think\db\exception\DbException $e) {
                $responseObj->msg = $e->getMessage();
                return json($responseObj);
            }
        } else {
            $responseObj->msg = "不是驳回状态不可以编辑驳回内容";
            return json($responseObj);
        }
    }

    public function fstVerifyListExport() {
        $this->commonExport(1);
    }

    public function reVerifyListExport() {
        $this->commonExport(2);
    }

    public function preListExport() {
        $this->commonExport(3);
    }

    private function commonExport($process) {
        $params = $this->request->param();
        $fields = $params["export"];
        if (!$fields)
            return json(["msg" => "请选择要导出的数据"]);
        $names = DictApi::getIntegralFields();
        $names["enterpriseName"] = "单位名称";
        $names["street"] = "所属镇街";
        $names["project"] = "申报项目";
        $names["checkState"] = "审核状态";
        $names["checkMsg"] = "审核意见";
        $names["year"] = "申报年度";
        $list = IntegralRecordApi::getExportDatas($process, $fields);
        foreach ($fields as $field) {
            $columns[] = $names[$field];
        }
        $datas = [];
        for ($i = 0; $i < count($list); $i++) {
            $data = [];
            for ($n = 0; $n < count($fields); $n++) {
                $data[] = $list[$i][$fields[$n]];
            }
            $datas[] = $data;
        }
        if ($datas) {
            export($columns, $datas);
            exit();
        }
        echo "<script>parent.layer.alert('没有可以导出的数据');window.history.go(-1);</script>";
    }

    public function getPhones() {
        $list = VerifyApi::getListByProcess($this->request->param());
        $result = [];
        if ($list) {
            foreach ($list as $item) {
                if ($item["phone"] && $item["name"]) {
                    $result[] = sprintf("%s:%s", $item["name"], $item["phone"]);
                }
            }
        }
        return json(["code" => 200, "obj" => implode(";", $result)]);
    }

    public function getEnterprisePhones() {
        $list = VerifyApi::getListByProcess($this->request->param());
        $result = [];
        if ($list) {
            foreach ($list as $item) {
                if ($item["agentName"] && $item["agentPhone"]) {
                    $result[] = sprintf("%s:%s", $item["agentName"], $item["agentPhone"]);
                }
            }
        }
        return json(["code" => 200, "obj" => implode(";", $result)]);
    }

}