package com.template.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qcloud.cos.utils.IOUtils;
import com.seewo.open.sdk.DefaultSeewoClient;
import com.seewo.open.sdk.SeewoClient;
import com.seewo.open.sdk.auth.Account;
import com.template.api.SmartUserControllerAPI;
import com.template.common.utils.*;
import com.template.config.ControlConfig;
import com.template.config.SeewoConfig;
import com.template.model.enumModel.*;
import com.template.model.pojo.SmartClass;
import com.template.model.pojo.SmartDepartment;
import com.template.model.pojo.SmartGrade;
import com.template.model.pojo.SmartUser;
import com.template.model.request.*;
import com.template.model.result.CommonResult;
import com.template.model.result.PageUtils;
import com.template.model.seewo.*;
import com.template.model.vo.*;
import com.template.services.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Array;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;

import static com.template.common.utils.AesTestOne.decrypt;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ceshi
 * @since 2023-12-04
 */
@RestController
public class SmartUserController implements SmartUserControllerAPI {

    @Resource
    private SeewoConfig seewoConfig;

    @Resource
    private ControlConfig controlConfig;

    @Autowired
    private SmartUserService smartUserService;

    @Autowired
    private SmartGradeService smartGradeService;

    @Autowired
    private SmartClassService smartClassService;

    @Autowired
    private SmartUploadService smartUploadService;

    @Autowired
    private SmartDepartmentService smartDepartmentService;

    @Override
    public CommonResult logoffAccount(useridsRequest ur, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        int user = smartUserService.getSmartUserCountByIds(ur.getUserIds());
        if (user != ur.getUserIds().size()) {
            return CommonResult.fail("用户信息已失效");
        }

//        for (:) {
//
//        }
//        user.setIsCancel(eLogOff.Logout.getValue());
//
//        int updateResult = smartUserService.updateSmartUser(user);

        return 0 > 0 ? CommonResult.ok("注销成功") : CommonResult.fail("注销失败");
    }

    @Override
    public CommonResult changeDepartment(changeDepartmentRequest cdr, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        List<SmartUser> users = smartUserService.getSmartUserByIds(cdr.getUserIds());
        if (users == null) {
            return CommonResult.fail("用户信息无效，移动失败！");
        }

        if (users.size() != cdr.getUserIds().size()) {
            return CommonResult.fail("存在无效用户数据，移动失败！");
        }

        for (SmartUser user : users) {
            user.setDepartmentId(cdr.getDepartmentId());

        }
        boolean result = smartUserService.updateUserBatchById(users);

        return result ? CommonResult.ok("移动成功") : CommonResult.fail("移动失败");
    }

    @Override
    public CommonResult importExcelUsers(MultipartFile excelFile, String headImage) throws IOException {
        List<SmartUser> result = new ArrayList<>();

        //先解析excel如果excel不满足格式就提示错误信息 避免提前占用带宽上传头像
        if (excelFile.isEmpty() || excelFile.getSize() == 0) {
            return CommonResult.fail("压缩包中的excel文件不能为空");
        }

        String ContentType = excelFile.getContentType();
        InputStream inputStream = excelFile.getInputStream();

        //xls格式文件
        if (ContentType.equals(eFileType.Xls.getValue())) {
            CommonResult<List<SmartUser>> resultData = readXls(inputStream);
            if (!resultData.isSuccess()) {
                return resultData;
            }
            result = resultData.getData();
        } else if (ContentType.equals(eFileType.Xlsx.getValue())) {
            CommonResult<List<SmartUser>> resultData = readXlsx(inputStream);
            if (!resultData.isSuccess()) {
                return resultData;
            }
            result = resultData.getData();
        } else {
            return CommonResult.fail("用户导入只支持Xls、Xlsx");
        }

        List<String> uploadImages = Arrays.asList(headImage.split(","));
        for (SmartUser user : result) {
            Optional<String> image = uploadImages == null ? null : uploadImages.stream().filter(e -> e.equals("https://wanzai-1306339220.cos.ap-shanghai.myqcloud.com/headImage/" + user.getHeadImage())).findFirst();
            if (image != null && image.isPresent()) {
                user.setHeadImage(image.get());
            }
        }

        //批量存储用户信息
        boolean resultBool = smartUserService.saveBatch(result);

        return resultBool ? CommonResult.ok("导入成功") : CommonResult.fail("导入失败");
    }


    /**
     * 批量导入用户信息
     * 以身份证号作为判断依据 如果存在重复数据就提示存在重复数据
     * 开发流程：建议先去拿到excel中的所有数据的身份证号去数据库中找一遍是否存在重复数据
     * 如果不存在重复数据就把附件文件夹中的附件文件上传到cos服务器上
     * 然后手动拼接一个人脸照片文件地址存入对应的数据中
     *
     * @param zipFile zip压缩包
     * @return
     */
    @Override
    public CommonResult importZipUsers(MultipartFile zipFile) throws IOException {
        List<SmartUser> result = new ArrayList<>();
        MultipartFile excelFile = null;
        List<MultipartFile> multipartFileHashMap = new ArrayList<>();
        String excelStr = null;
        if (zipFile != null) {
            //解压压缩文件并上传文件
            ByteArrayOutputStream byteOut = null;
            ZipInputStream zipIn = null;
            try {
                java.util.zip.ZipEntry zipEntry = null;
                zipIn = new ZipInputStream(zipFile.getInputStream(), Charset.forName("GBK"));
                while ((zipEntry = zipIn.getNextEntry()) != null) {
                    String fileName = zipEntry.getName();
                    if (fileName.contains("人脸照片") && (fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".jpeg"))) {
                        byteOut = new ByteArrayOutputStream();
                        IOUtils.copy(zipIn, byteOut);
                        InputStream inputStream = new ByteArrayInputStream(byteOut.toByteArray());
                        MultipartFile multipartFile = FileUtils.getMultipartFile(inputStream, fileName);
                        multipartFileHashMap.add(multipartFile);
                    } else if (fileName.contains("人员信息采集表") && (fileName.endsWith(".xlsx") || fileName.endsWith(".xls"))) {
                        excelStr = fileName.endsWith(".xlsx") ? "xlsx" : "xls";
                        byteOut = new ByteArrayOutputStream();
                        IOUtils.copy(zipIn, byteOut);
                        InputStream inputStream = new ByteArrayInputStream(byteOut.toByteArray());
                        excelFile = FileUtils.getMultipartFile(inputStream, fileName);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (byteOut != null) {
                    byteOut.close();
                }
                if (zipIn != null) {
                    zipIn.close();
                }
            }
        }

        //先解析excel如果excel不满足格式就提示错误信息 避免提前占用带宽上传头像
        if (excelFile.isEmpty() || excelFile.getSize() == 0) {
            return CommonResult.fail("压缩包中的excel文件不能为空");
        }

        String ContentType = excelFile.getContentType();
        InputStream inputStream = excelFile.getInputStream();

        //xls格式文件
        if (excelStr.equals("xls")) {
            CommonResult<List<SmartUser>> resultData = readXls(inputStream);
            if (!resultData.isSuccess()) {
                return resultData;
            }
            result = resultData.getData();
        } else if (excelStr.equals("xlsx")) {
            CommonResult<List<SmartUser>> resultData = readXlsx(inputStream);
            if (!resultData.isSuccess()) {
                return resultData;
            }
            result = resultData.getData();
        } else {
            return CommonResult.fail("用户导入只支持Xls、Xlsx");
        }

        //cos上传 返回图片地址
        String uploadResult = smartUploadService.upload(multipartFileHashMap.toArray(new MultipartFile[0]));
        List<String> uploadImages = Arrays.asList(uploadResult.split(","));
        for (SmartUser user : result) {
            Optional<String> headImage = uploadImages == null ? null : uploadImages.stream().filter(e -> e.equals("https://wanzai-1306339220.cos.ap-shanghai.myqcloud.com/headImage/" + user.getHeadImage())).findFirst();
            if (headImage != null && headImage.isPresent()) {
                user.setHeadImage(headImage.get());
            }
        }

        //批量存储用户信息
        boolean resultBool = smartUserService.saveBatch(result);

        return resultBool ? CommonResult.ok("导入成功") : CommonResult.fail("导入失败");
    }

    /**
     * Xlsx文件读取方法
     *
     * @param inputStream 文件流
     * @return
     * @throws IOException
     */
    private CommonResult<List<SmartUser>> readXlsx(InputStream inputStream) throws IOException {
        List<String> phones = new ArrayList<>();
        List<String> idCards = new ArrayList<>();
        List<String> cardNos = new ArrayList<>();
        List<SmartUser> result = new ArrayList<>();
        XSSFWorkbook sheets = new XSSFWorkbook(inputStream);

        List<SmartDepartment> departments = smartDepartmentService.list(null);
        List<SmartGrade> grades = smartGradeService.list(null); //年级
        List<SmartClass> classs = smartClassService.list(null);//班级
        //读取第一张sheet
        XSSFSheet sheetAt = sheets.getSheetAt(0);

        DataFormatter dataFormatter = new DataFormatter();
        try {
            for (int rowNum = 0; rowNum < sheetAt.getLastRowNum() + 1; rowNum++) {
                XSSFRow row = sheetAt.getRow(rowNum);

                if (row != null) {
                    //使用了getStringCellValue()方法来获取值，POI会判断单元格的类型，如果非字符串类型就会抛出上面的异常。
                    //所以先使用setCellType()方法先将该单元格的类型设置为STRING
                    //然后poi会根据字符串读取它
                    //标题 校验
                    if (rowNum == 0) {
                        String cardNo = dataFormatter.formatCellValue(row.getCell(0));//学号
                        if (!cardNo.equals("学号")) {
                            return CommonResult.fail("导入数据第一列为学号");
                        }
                        String name = dataFormatter.formatCellValue(row.getCell(1));//姓名
                        if (!name.equals("姓名")) {
                            return CommonResult.fail("导入数据第二列为姓名");
                        }
                        String identity = dataFormatter.formatCellValue(row.getCell(2));//身份
                        if (!identity.equals("身份")) {
                            return CommonResult.fail("导入数据第三列为身份");
                        }
                        String idCard = dataFormatter.formatCellValue(row.getCell(3));//身份证
                        if (!idCard.equals("身份证")) {
                            return CommonResult.fail("导入数据第四列为身份证");
                        }
                        String sex = dataFormatter.formatCellValue(row.getCell(4));//性别
                        if (!sex.equals("性别")) {
                            return CommonResult.fail("导入数据第五列为性别");
                        }
                        String department = dataFormatter.formatCellValue(row.getCell(5));//部门
                        if (!department.equals("部门")) {
                            return CommonResult.fail("导入数据第六列为部门");
                        }
                        String headImage = dataFormatter.formatCellValue(row.getCell(6));//人脸照片
                        if (!headImage.equals("人脸照片")) {
                            return CommonResult.fail("导入数据第七列为人脸照片");
                        }
                        String dormitoryNumber = dataFormatter.formatCellValue(row.getCell(7));//宿舍号
                        if (!dormitoryNumber.equals("宿舍号")) {
                            return CommonResult.fail("导入数据第八列为宿舍号");
                        }
                        String grade = dataFormatter.formatCellValue(row.getCell(8));//年级
                        if (!grade.equals("年级")) {
                            return CommonResult.fail("导入数据第九列为年级");
                        }
                        String schoolClass = dataFormatter.formatCellValue(row.getCell(9));//班级
                        if (!schoolClass.equals("班级")) {
                            return CommonResult.fail("导入数据第十列为班级");
                        }
                        String phone = dataFormatter.formatCellValue(row.getCell(10));//手机号
                        if (!phone.equals("手机号")) {
                            return CommonResult.fail("导入数据第十一列为手机号");
                        }
                        String affiliate = dataFormatter.formatCellValue(row.getCell(11));//关联人
                        if (!affiliate.equals("关联人")) {
                            return CommonResult.fail("导入数据第十二列为关联人");
                        }
                        String title = dataFormatter.formatCellValue(row.getCell(12));//职称
                        if (!title.equals("职称")) {
                            return CommonResult.fail("导入数据第十三列为职称");
                        }
                        String address = dataFormatter.formatCellValue(row.getCell(13));//家庭住址
                        if (!address.equals("家庭住址")) {
                            return CommonResult.fail("导入数据第十四列为家庭住址");
                        }
                        String nation = dataFormatter.formatCellValue(row.getCell(14));//民族
                        if (!nation.equals("民族")) {
                            return CommonResult.fail("导入数据第十五列为民族");
                        }
                        String ofStudent = dataFormatter.formatCellValue(row.getCell(15));//生源地
                        if (!ofStudent.equals("生源地")) {
                            return CommonResult.fail("导入数据第十六列为生源地");
                        }
                        String graduate = dataFormatter.formatCellValue(row.getCell(16));//毕业学校
                        if (!graduate.equals("毕业学校")) {
                            return CommonResult.fail("导入数据第十七列为毕业学校");
                        }
                        String duties = dataFormatter.formatCellValue(row.getCell(17));//职务
                        if (!duties.equals("职务")) {
                            return CommonResult.fail("导入数据第十八列为职务");
                        }
                    } else {
                        SmartUser user = new SmartUser();
                        String name = dataFormatter.formatCellValue(row.getCell(1));
                        if (ObjectUtils.isEmpty(name)) {
                            return CommonResult.fail("第" + (rowNum + 2) + "条数据的名称不能为空");
                        }

                        //身份是否为空判断
                        String identity = dataFormatter.formatCellValue(row.getCell(2));
                        if (ObjectUtils.isEmpty(identity)) {
                            return CommonResult.fail(name + "的身份不能为空");
                        }

                        String dormitoryNumber = dataFormatter.formatCellValue(row.getCell(7));//宿舍号
                        String grade = dataFormatter.formatCellValue(row.getCell(8));//年级
                        String schoolClass = dataFormatter.formatCellValue(row.getCell(9));//班级
                        //身份为学生的情况下 宿舍号、年级、班级不能为空
                        if (eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Student.getValue()) {
                            if (ObjectUtils.isEmpty(dormitoryNumber)) {
                                return CommonResult.fail(name + "的宿舍号不能为空");
                            }
                            if (ObjectUtils.isEmpty(grade)) {
                                return CommonResult.fail(name + "的年级不能为空");
                            }
                            if (ObjectUtils.isEmpty(schoolClass)) {
                                return CommonResult.fail(name + "的班级不能为空");
                            }
                        }

                        //手机号重复判断
                        String phone = dataFormatter.formatCellValue(row.getCell(10));
                        if (eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Parent.getValue() || eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Teacher.getValue()) {
                            if (ObjectUtils.isEmpty(phone)) {
                                return CommonResult.fail(name + "的手机号不能为空");
                            }
                        }
                        if (!ObjectUtils.isEmpty(phone)) {
                            phones.add(phone);
                        }
                        if (phones.stream().distinct().count() != phones.size()) {
                            return CommonResult.fail("导入的Excel中，手机号：" + phone + "存在重复数据");
                        }

                        String affiliate = dataFormatter.formatCellValue(row.getCell(11));//关联人
                        if (eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Parent.getValue()) {
                            if (ObjectUtils.isEmpty(affiliate)) {
                                return CommonResult.fail(name + "的关联人不能为空");
                            }
                        }

                        //性别是否为空判断
                        String sex = dataFormatter.formatCellValue(row.getCell(4));
                        if (ObjectUtils.isEmpty(sex)) {
                            return CommonResult.fail(name + "的性别不能为空");
                        }

                        //家庭住址是否为空判断
                        String address = dataFormatter.formatCellValue(row.getCell(13));
                        if (ObjectUtils.isEmpty(address)) {
                            return CommonResult.fail(name + "的家庭住址不能为空");
                        }

                        //民族是否为空判断
                        String nation = dataFormatter.formatCellValue(row.getCell(14));
                        if (ObjectUtils.isEmpty(nation)) {
                            return CommonResult.fail(name + "的民族不能为空");
                        }

                        //部门是否为空判断
                        String department = dataFormatter.formatCellValue(row.getCell(5));
                        if (ObjectUtils.isEmpty(department)) {
                            return CommonResult.fail(name + "的部门不能为空");
                        }
                        int lastIndex = department.lastIndexOf("/");
                        Integer departmentId = null;
                        if (lastIndex >= 0) {
                            Optional<SmartDepartment> departModel = departments.stream().filter(e -> e.getName().equals(department.substring(lastIndex))).findFirst();
                            if (departModel != null && departModel.isPresent()) {
                                departmentId = departModel.get().getId();
                            }
                        }

                        //学号重复判断
                        String cardNo = dataFormatter.formatCellValue(row.getCell(0));
                        if (!ObjectUtils.isEmpty(cardNo)) {
                            cardNos.add(cardNo);
                        }
                        if (cardNos.stream().distinct().count() != cardNos.size()) {
                            return CommonResult.fail("导入的Excel中，卡号：" + cardNo + "存在重复数据");
                        }

                        //身份证重复判断
                        String idCard = dataFormatter.formatCellValue(row.getCell(3));
                        if (!ObjectUtils.isEmpty(idCard)) {
                            idCards.add(idCard);
                        }
                        //List<String> noEmptyIdCards = idCards.stream().filter(e -> !e.equals("") || e != null).collect(Collectors.toList());
                        if (idCards.stream().distinct().count() != idCards.size()) {
                            return CommonResult.fail("导入的Excel中，身份证号：" + idCard + "存在重复数据");
                        }
                        user.setCardNo(cardNo == null ? "" : cardNo);
                        user.setName(name == null ? "" : name);
                        user.setIdentityId(identity == null ? eIdentityStatu.Student.getValue() : eIdentityStatu.integerOf(identity));
                        user.setIdCard(idCard == null ? "" : idCard);
                        user.setSexId(sex == null ? eSexStatu.Man.getValue() : eSexStatu.integerOf(sex));
                        user.setDepartmentId(departmentId);
                        String cellImage = dataFormatter.formatCellValue(row.getCell(6));
                        user.setHeadImage(cellImage);
                        user.setDormitoryNumber(dormitoryNumber == null ? "" : dormitoryNumber);
                        user.setGrade(grade == null ? "" : grade);
                        Optional<SmartGrade> oGrade = grades.stream().filter(e -> e.getName().equals(grade)).findFirst();

                        if (oGrade != null && oGrade.isPresent()) {
                            Integer gradeId = oGrade.get().getId();

                            Optional<SmartClass> oClass = classs.stream().filter(e -> e.getName().equals(schoolClass) && e.getGradeId().equals(gradeId)).findFirst();

                            if (oClass != null && oClass.isPresent()) {
                                user.setSchoolClass(oClass.get().getId());
                            } else {
                                return CommonResult.fail(name + "的班级数据无效，导入失败");
                            }

                        } else {
                            return CommonResult.fail(name + "的年级数据无效，导入失败");
                        }

                        user.setCollege("");
                        user.setSpeciality("");
                        user.setCampus("");
                        user.setPhone(phone == null ? "" : phone);
                        user.setAffiliate(affiliate == null ? "" : affiliate);
                        String title = dataFormatter.formatCellValue(row.getCell(12));//职称
                        user.setTitle(title == null ? "" : title);
                        user.setAddress(address == null ? "" : address);
                        user.setNation(nation == null ? "" : nation);
                        String ofStudent = dataFormatter.formatCellValue(row.getCell(15));//生源地
                        user.setOfStudent(ofStudent == null ? "" : ofStudent);
                        String graduate = dataFormatter.formatCellValue(row.getCell(16));//毕业学校
                        user.setGraduate(graduate == null ? "" : graduate);
                        String duties = dataFormatter.formatCellValue(row.getCell(17));//职务
                        user.setDuties(duties == null ? null : Integer.valueOf(duties));
                        user.setIsCancel(eLogOff.Unlogout.getValue());

                        result.add(user);
                    }
                }
            }
        } catch (Exception e) {
            return CommonResult.fail("请按模板格式导入数据");
        }

        return CommonResult.ok(result);
    }

    /**
     * Xls文件读取方法
     *
     * @param inputStream 文件流
     * @return
     * @throws IOException
     */
    private CommonResult<List<SmartUser>> readXls(InputStream inputStream) throws IOException {
        List<String> phones = new ArrayList<>();
        List<String> idCards = new ArrayList<>();
        List<String> cardNos = new ArrayList<>();
        List<SmartUser> result = new ArrayList<>();
        HSSFWorkbook sheets = new HSSFWorkbook(inputStream);

        List<SmartDepartment> departments = smartDepartmentService.list(null);
        List<SmartGrade> grades = smartGradeService.list(null); //年级
        List<SmartClass> classs = smartClassService.list(null);//班级

        //读取第一张sheet
        HSSFSheet sheetAt = sheets.getSheetAt(0);

        DataFormatter dataFormatter = new DataFormatter();
        try {
            for (int rowNum = 0; rowNum < sheetAt.getLastRowNum() + 1; rowNum++) {
                HSSFRow row = sheetAt.getRow(rowNum);

                if (row != null) {
                    //使用了getStringCellValue()方法来获取值，POI会判断单元格的类型，如果非字符串类型就会抛出上面的异常。
                    //所以先使用setCellType()方法先将该单元格的类型设置为STRING
                    //然后poi会根据字符串读取它
                    //标题 校验
                    if (rowNum == 0) {
                        String cardNo = dataFormatter.formatCellValue(row.getCell(0));//学号
                        if (!cardNo.equals("学号")) {
                            return CommonResult.fail("导入数据第一列为学号");
                        }
                        String name = dataFormatter.formatCellValue(row.getCell(1));//姓名
                        if (!name.equals("姓名")) {
                            return CommonResult.fail("导入数据第二列为姓名");
                        }
                        String identity = dataFormatter.formatCellValue(row.getCell(2));//身份
                        if (!identity.equals("身份")) {
                            return CommonResult.fail("导入数据第三列为身份");
                        }
                        String idCard = dataFormatter.formatCellValue(row.getCell(3));//身份证
                        if (!idCard.equals("身份证")) {
                            return CommonResult.fail("导入数据第四列为身份证");
                        }
                        String sex = dataFormatter.formatCellValue(row.getCell(4));//性别
                        if (!sex.equals("性别")) {
                            return CommonResult.fail("导入数据第五列为性别");
                        }
                        String department = dataFormatter.formatCellValue(row.getCell(5));//部门
                        if (!department.equals("部门")) {
                            return CommonResult.fail("导入数据第六列为部门");
                        }
                        String headImage = dataFormatter.formatCellValue(row.getCell(6));//人脸照片
                        if (!headImage.equals("人脸照片")) {
                            return CommonResult.fail("导入数据第七列为人脸照片");
                        }
                        String dormitoryNumber = dataFormatter.formatCellValue(row.getCell(7));//宿舍号
                        if (!dormitoryNumber.equals("宿舍号")) {
                            return CommonResult.fail("导入数据第八列为宿舍号");
                        }
                        String grade = dataFormatter.formatCellValue(row.getCell(8));//年级
                        if (!grade.equals("年级")) {
                            return CommonResult.fail("导入数据第九列为年级");
                        }
                        String schoolClass = dataFormatter.formatCellValue(row.getCell(9));//班级
                        if (!schoolClass.equals("班级")) {
                            return CommonResult.fail("导入数据第十列为班级");
                        }
                        String phone = dataFormatter.formatCellValue(row.getCell(10));//手机号
                        if (!phone.equals("手机号")) {
                            return CommonResult.fail("导入数据第十一列为手机号");
                        }
                        String affiliate = dataFormatter.formatCellValue(row.getCell(11));//关联人
                        if (!affiliate.equals("关联人")) {
                            return CommonResult.fail("导入数据第十二列为关联人");
                        }
                        String title = dataFormatter.formatCellValue(row.getCell(12));//职称
                        if (!title.equals("职称")) {
                            return CommonResult.fail("导入数据第十三列为职称");
                        }
                        String address = dataFormatter.formatCellValue(row.getCell(13));//家庭住址
                        if (!address.equals("家庭住址")) {
                            return CommonResult.fail("导入数据第十四列为家庭住址");
                        }
                        String nation = dataFormatter.formatCellValue(row.getCell(14));//民族
                        if (!nation.equals("民族")) {
                            return CommonResult.fail("导入数据第十五列为民族");
                        }
                        String ofStudent = dataFormatter.formatCellValue(row.getCell(15));//生源地
                        if (!ofStudent.equals("生源地")) {
                            return CommonResult.fail("导入数据第十六列为生源地");
                        }
                        String graduate = dataFormatter.formatCellValue(row.getCell(16));//毕业学校
                        if (!graduate.equals("毕业学校")) {
                            return CommonResult.fail("导入数据第十七列为毕业学校");
                        }
                        String duties = dataFormatter.formatCellValue(row.getCell(17));//职务
                        if (!duties.equals("职务")) {
                            return CommonResult.fail("导入数据第十八列为职务");
                        }
                    } else {
                        SmartUser user = new SmartUser();
                        String name = dataFormatter.formatCellValue(row.getCell(1));
                        if (ObjectUtils.isEmpty(name)) {
                            return CommonResult.fail("第" + (rowNum + 2) + "条数据的名称不能为空");
                        }

                        //身份是否为空判断
                        String identity = dataFormatter.formatCellValue(row.getCell(2));
                        if (ObjectUtils.isEmpty(identity)) {
                            return CommonResult.fail(name + "的身份不能为空");
                        }

                        String dormitoryNumber = dataFormatter.formatCellValue(row.getCell(7));//宿舍号
                        String grade = dataFormatter.formatCellValue(row.getCell(8));//年级
                        String schoolClass = dataFormatter.formatCellValue(row.getCell(9));//班级
                        //身份为学生的情况下 宿舍号、年级、班级不能为空
                        if (eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Student.getValue()) {
                            if (ObjectUtils.isEmpty(dormitoryNumber)) {
                                return CommonResult.fail(name + "的宿舍号不能为空");
                            }
                            if (ObjectUtils.isEmpty(grade)) {
                                return CommonResult.fail(name + "的年级不能为空");
                            }
                            if (ObjectUtils.isEmpty(schoolClass)) {
                                return CommonResult.fail(name + "的班级不能为空");
                            }
                        }

                        //手机号重复判断
                        String phone = dataFormatter.formatCellValue(row.getCell(10));
                        if (eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Parent.getValue() || eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Teacher.getValue()) {
                            if (ObjectUtils.isEmpty(phone)) {
                                return CommonResult.fail(name + "的手机号不能为空");
                            }
                        }
                        if (!ObjectUtils.isEmpty(phone)) {
                            phones.add(phone);
                        }
                        if (phones.stream().distinct().count() != phones.size()) {
                            return CommonResult.fail("导入的Excel中，手机号：" + phone + "存在重复数据");
                        }

                        String affiliate = dataFormatter.formatCellValue(row.getCell(11));//关联人
                        if (eIdentityStatu.integerOf(identity).intValue() == eIdentityStatu.Parent.getValue()) {
                            if (ObjectUtils.isEmpty(affiliate)) {
                                return CommonResult.fail(name + "的关联人不能为空");
                            }
                        }

                        //性别是否为空判断
                        String sex = dataFormatter.formatCellValue(row.getCell(4));
                        if (ObjectUtils.isEmpty(sex)) {
                            return CommonResult.fail(name + "的性别不能为空");
                        }

                        //家庭住址是否为空判断
                        String address = dataFormatter.formatCellValue(row.getCell(13));
                        if (ObjectUtils.isEmpty(address)) {
                            return CommonResult.fail(name + "的家庭住址不能为空");
                        }

                        //民族是否为空判断
                        String nation = dataFormatter.formatCellValue(row.getCell(14));
                        if (ObjectUtils.isEmpty(nation)) {
                            return CommonResult.fail(name + "的民族不能为空");
                        }

                        //部门是否为空判断
                        String department = dataFormatter.formatCellValue(row.getCell(5));
                        if (ObjectUtils.isEmpty(department)) {
                            return CommonResult.fail(name + "的部门不能为空");
                        }
                        int lastIndex = department.lastIndexOf("/");
                        Integer departmentId = null;
                        if (lastIndex >= 0) {
                            Optional<SmartDepartment> departModel = departments.stream().filter(e -> e.getName().equals(department.substring(lastIndex))).findFirst();
                            if (departModel != null && departModel.isPresent()) {
                                departmentId = departModel.get().getId();
                            }
                        }


                        //学号重复判断
                        String cardNo = dataFormatter.formatCellValue(row.getCell(0));
                        if (!ObjectUtils.isEmpty(cardNo)) {
                            cardNos.add(cardNo);
                        }
                        if (cardNos.stream().distinct().count() != cardNos.size()) {
                            return CommonResult.fail("导入的Excel中，卡号：" + cardNo + "存在重复数据");
                        }

                        //身份证重复判断
                        String idCard = dataFormatter.formatCellValue(row.getCell(3));
                        if (!ObjectUtils.isEmpty(idCard)) {
                            idCards.add(idCard);
                        }
                        //List<String> noEmptyIdCards = idCards.stream().filter(e -> !e.equals("") || e != null).collect(Collectors.toList());
                        if (idCards.stream().distinct().count() != idCards.size()) {
                            return CommonResult.fail("导入的Excel中，身份证号：" + idCard + "存在重复数据");
                        }
                        user.setCardNo(cardNo == null ? "" : cardNo);
                        user.setName(name == null ? "" : name);
                        user.setIdentityId(identity == null ? eIdentityStatu.Student.getValue() : eIdentityStatu.integerOf(identity));
                        user.setIdCard(idCard == null ? "" : idCard);
                        user.setSexId(sex == null ? eSexStatu.Man.getValue() : eSexStatu.integerOf(sex));
                        user.setDepartmentId(departmentId);
                        String cellImage = dataFormatter.formatCellValue(row.getCell(6));
                        user.setHeadImage(cellImage);
                        user.setDormitoryNumber(dormitoryNumber == null ? "" : dormitoryNumber);
                        user.setGrade(grade == null ? "" : grade);
                        Optional<SmartGrade> oGrade = grades.stream().filter(e -> e.getName().equals(grade)).findFirst();

                        if (oGrade != null && oGrade.isPresent()) {
                            Integer gradeId = oGrade.get().getId();

                            Optional<SmartClass> oClass = classs.stream().filter(e -> e.getName().equals(schoolClass) && e.getGradeId().equals(gradeId)).findFirst();

                            if (oClass != null && oClass.isPresent()) {
                                user.setSchoolClass(oClass.get().getId());
                            } else {
                                return CommonResult.fail(name + "的班级数据无效，导入失败");
                            }

                        } else {
                            return CommonResult.fail(name + "的年级数据无效，导入失败");
                        }
                        user.setCollege("");
                        user.setSpeciality("");
                        user.setCampus("");
                        user.setPhone(phone == null ? "" : phone);
                        user.setAffiliate(affiliate == null ? "" : affiliate);
                        String title = dataFormatter.formatCellValue(row.getCell(12));//职称
                        user.setTitle(title == null ? "" : title);
                        user.setAddress(address == null ? "" : address);
                        user.setNation(nation == null ? "" : nation);
                        String ofStudent = dataFormatter.formatCellValue(row.getCell(15));//生源地
                        user.setOfStudent(ofStudent == null ? "" : ofStudent);
                        String graduate = dataFormatter.formatCellValue(row.getCell(16));//毕业学校
                        user.setGraduate(graduate == null ? "" : graduate);
                        String duties = dataFormatter.formatCellValue(row.getCell(17));//职务
                        user.setDuties(duties == null ? null : Integer.valueOf(duties));
                        user.setIsCancel(eLogOff.Unlogout.getValue());

                        result.add(user);
                    }
                }
            }
        } catch (Exception e) {
            return CommonResult.fail("请按模板格式导入数据");
        }

        return CommonResult.ok(result);
    }

    @Override
    public CommonResult timeGroups() {
        List<TimeGroupVo> result = new ArrayList<>();

        for (int i = 1; i <= 3; i++) {
            TimeGroupVo data = new TimeGroupVo();
            data.setId(i);
            data.setName(eTimeGroup.stringOfName(i));
            result.add(data);
        }

        return CommonResult.ok(result);
    }

    /**
     * 新增用户
     *
     * @param isur          用户数据
     * @param bindingResult
     * @return
     */
    @Override
    public CommonResult insertSmartUser(insertSmartUserRequest isur, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //重复性判断
        int existCount = smartUserService.querySmartUserByCardNo(isur.getCardNo());
        if (existCount > 0) {
            return CommonResult.fail("当前学号已存在，请勿重复添加");
        }

        SmartUser su = new SmartUser();
        su.setTimeGroupId(isur.getTimeGroupId());
        su.setCardNo(isur.getCardNo());
        su.setName(isur.getName());
        su.setIdentityId(isur.getIdentityId());
        su.setIdCard(isur.getIdCard());
        su.setSexId(isur.getSexId());
        su.setDepartmentId(isur.getDepartmentId());
        su.setHeadImage(isur.getHeadImage());
        su.setGrade(isur.getGrade());
        su.setCollege(isur.getCollege());
        su.setSpeciality(isur.getSpeciality());
        su.setSchoolClass(isur.getSchoolClass());
        su.setCampus(isur.getCampus());
        su.setDormitoryNumber(isur.getDormitoryNumber());
        su.setPhone(isur.getPhone());
        su.setAffiliate(StringUtils.join(isur.getAffiliate(), ","));
        su.setTitle(isur.getTitle());
        su.setAddress(isur.getAddress());
        su.setNation(isur.getNation());
        su.setOfStudent(isur.getOfStudent());
        su.setGraduate(isur.getGraduate());
        su.setDuties(isur.getDuties());
        su.setIsCancel(eLogOff.Unlogout.getValue());

        //region 人员信息加入到第三方api
        //要将用户数据加入到希沃和百胜中
        //希沃和百胜的老师、学生数据添加是不一样的，所以按身份添加
        if (isur.getIdentityId().intValue() == eIdentityStatu.Parent.getValue()) {//家长

            //region 家长参数必填判断：手机号
            if (isur.getPhone() == null) {
                return CommonResult.fail("家长手机号不能为空");
            }
            //endregion

            //拿到被关联学生的信息去获取对应的卡号
            //有多个学生就循环学生

            if (isur.getAffiliate() == null) {
                return CommonResult.fail("被关联人不能为空");
            }

            if (isur.getAffiliate().size() <= 0) {
                return CommonResult.fail("被关联人不能为空");
            }

            List<SmartUser> studentDatas = smartUserService.getSmartUserIds(isur.getAffiliate());

            //region 希沃新增编辑学生家长信息
            //学生与家长列表，最大100条
            List<ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem> studentParents = new ArrayList<>();
            for (SmartUser student : studentDatas) {
                ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem students = ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem.builder()
                        .studentCode(student.getCardNo())
                        .build();
                studentParents.add(students);

                //家长列表，最多4个
                ParentServiceBatchSaveOrUpdateParentsParam.ParentsItem parents = ParentServiceBatchSaveOrUpdateParentsParam.ParentsItem.builder()
                        .name(isur.getName())
                        .phone(isur.getPhone())
                        .index(0)
                        .build();

                students.setParents(java.util.Collections.singletonList(parents));
            }

            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            ParentServiceBatchSaveOrUpdateParentsParam param = new ParentServiceBatchSaveOrUpdateParentsParam();
            //响应体，MimeType为 application/json
            ParentServiceBatchSaveOrUpdateParentsParam.RequestBody requestBody = ParentServiceBatchSaveOrUpdateParentsParam.RequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //query
            ParentServiceBatchSaveOrUpdateParentsParam.Query query = ParentServiceBatchSaveOrUpdateParentsParam.Query.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .build();
            requestBody.setQuery(query);
            query.setStudentParents(studentParents);
            param.setRequestBody(requestBody);
            ParentServiceBatchSaveOrUpdateParentsRequest request = new ParentServiceBatchSaveOrUpdateParentsRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            ParentServiceBatchSaveOrUpdateParentsResult result = seewoClient.invoke(request);
            System.out.println("出参：" + result);
            //endregion

            if (result == null) {
                return CommonResult.fail("希沃学生家长数据添加失败！");
            }

            if (!result.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(result.getResponseBody().getMessage());
            }

        } else if (isur.getIdentityId().intValue() == eIdentityStatu.Student.getValue()) {//学生

            //region 学生参数必填判断：年级、班级
            if (isur.getGrade() == null) {
                return CommonResult.fail("学生年级不能为空");
            }

            if (isur.getSchoolClass() == null) {
                return CommonResult.fail("学生班级不能为空");
            }
            //endregion

            //获取班级Uid
            SmartClass classData = smartClassService.getSmartClassById(isur.getSchoolClass());
            if (classData == null) {
                return CommonResult.fail("班级数据无效，新增失败");
            }

            //region 希沃新增学生信息
            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            StudentServiceBatchSaveClassStudentsParam param = new StudentServiceBatchSaveClassStudentsParam();
            //请求体，MimeType为 application/json
            StudentServiceBatchSaveClassStudentsParam.JSONRequestBody requestBody = StudentServiceBatchSaveClassStudentsParam.JSONRequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //查询条件
            StudentServiceBatchSaveClassStudentsParam.StudentSaveQuery query = StudentServiceBatchSaveClassStudentsParam.StudentSaveQuery.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .classUid(classData.getClassUid())
                    .build();
            requestBody.setQuery(query);
            // 学生列表
            StudentServiceBatchSaveClassStudentsParam.StudentInfo students = StudentServiceBatchSaveClassStudentsParam.StudentInfo.builder()
                    .studentName(isur.getName())
                    .studentCode(isur.getCardNo())
                    .gender(isur.getSexId())
                    .phone(isur.getPhone() == null ? "" : isur.getPhone())
                    .build();
            query.setStudents(java.util.Collections.singletonList(students));
            query.setInPlaceOld(true);// 是否删除旧学生再保存
            param.setRequestBody(requestBody);
            StudentServiceBatchSaveClassStudentsRequest request = new StudentServiceBatchSaveClassStudentsRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            StudentServiceBatchSaveClassStudentsResult result = seewoClient.invoke(request);
            System.out.println("出参：" + result);

            if (result == null) {
                return CommonResult.fail("希沃学生数据新增失败！");
            }

            if (!result.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(result.getResponseBody().getMessage());
            }

            su.setXwStudentUid(result.getResponseBody().getData().get(0).getUserUid());
            //endregion

            //region 百胜新增学生信息
            String appId = controlConfig.getAppId();
            String schoolno = controlConfig.getSchoolCode();
            String timestamp = TimeExchange.DateNowTimeStamo();
            String appSecret = controlConfig.getAppSecret();
            String url = controlConfig.getUrl() + "student/create";

            JSONObject jsonobject = new JSONObject();
            jsonobject.put("appid", appId);
            String str = "{\"student_name\":\"" + isur.getName() + "\",\"classtab_no\":\"" + classData.getBsClassNo() + "\",\"student_number\":\"" + isur.getCardNo() + "\",\"student_sex\":\"" + isur.getSexId() + "\",\"student_photo\":\"" + imageUtils.getBase64Url(isur.getHeadImage()) + "\",\"student_tgno\":\"" + eTimeGroup.stringOf(isur.getTimeGroupId()) + "\"}";
            String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
            jsonobject.put("data", aesStr);
            jsonobject.put("schoolno", schoolno);
            jsonobject.put("timestamp", timestamp);

            String md5Str = "appid=" + appId + "&data={\"student_name\":\"" + isur.getName() + "\",\"classtab_no\":\"" + classData.getBsClassNo() + "\",\"student_number\":\"" + isur.getCardNo() + "\",\"student_sex\":\"" + isur.getSexId() + "\",\"student_photo\":\"" + imageUtils.getBase64Url(isur.getHeadImage()) + "\",\"student_tgno\":\"" + eTimeGroup.stringOf(isur.getTimeGroupId()) + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
            String sign = CommonUtil.MD5(md5Str);
            //sign签名
            jsonobject.put("sign", sign);

            //返回的结果中 code为1表示成功
            String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

            if (bsResult.contains("添加成功")) {
                ObjectMapper objectMapper = new ObjectMapper();
                BsStudentVo grade = objectMapper.readValue(bsResult, BsStudentVo.class);

                // URL解码
                String decodedUrl = URLDecoder.decode(grade.getData(), "UTF-8");

                BsStudentNoVo studentNo = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsStudentNoVo.class);
                su.setBsStudentNo(studentNo.getStudent_no());
            }
            //endregion

        } else if (isur.getIdentityId().intValue() == eIdentityStatu.Teacher.getValue()) {//老师

            //region 老师参数必填判断：职称、手机号
            if (isur.getTitle() == null) {
                return CommonResult.fail("老师职称不能为空");
            }

            if (isur.getPhone() == null) {
                return CommonResult.fail("老师手机号不能为空");
            }
            //endregion

            //region 希沃添加教师数据
            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            TeacherServiceBatchSaveOrUpdateTeacherParam param = new TeacherServiceBatchSaveOrUpdateTeacherParam();
            //请求体，MimeType为 application/json
            TeacherServiceBatchSaveOrUpdateTeacherParam.JSONRequestBody requestBody = TeacherServiceBatchSaveOrUpdateTeacherParam.JSONRequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //老师信息
            TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherBatchQuery query = TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherBatchQuery.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .build();
            requestBody.setQuery(query);
            // 老师列表
            TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherQuery teachers = TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherQuery.builder()
                    .account(isur.getPhone())//用户账号
                    .name(isur.getName())//用户名字
                    .accountType("phone")//账号类型 phone：手机号  email：邮箱
                    .teacherCode(isur.getPhone())//教师工号
                    .photoUrl(isur.getHeadImage())//图片链接
                    .build();
            query.setTeachers(java.util.Collections.singletonList(teachers));
            param.setRequestBody(requestBody);
            TeacherServiceBatchSaveOrUpdateTeacherRequest request = new TeacherServiceBatchSaveOrUpdateTeacherRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            TeacherServiceBatchSaveOrUpdateTeacherResult result = seewoClient.invoke(request);
            System.out.println("出参：" + result);

            if (result == null) {
                return CommonResult.fail("希沃教师数据新增失败！");
            }

            if (!result.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(result.getResponseBody().getMessage());
            }

            su.setXwTeacherCode(result.getResponseBody().getData().get(0).getTeacherCode());
            //endregion

            if (isur.getDuties().intValue() == eDuties.ClassTeacher.getValue()) {
                //获取班级Uid
                SmartClass classData = smartClassService.getSmartClassById(isur.getSchoolClass());
                if (classData == null) {
                    return CommonResult.fail("班级数据无效，新增失败");
                }

                //region 将班主任推送到希沃
                //初始化客户端
                //SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
                TeacherServiceBatchSetClassMastersParam teacherClassParam = new TeacherServiceBatchSetClassMastersParam();
                //响应体，MimeType为 application/json
                TeacherServiceBatchSetClassMastersParam.RequestBody teacherClassRequestBody = TeacherServiceBatchSetClassMastersParam.RequestBody.builder()
                        .build();
                teacherClassParam.setRequestBody(teacherClassRequestBody);
                //query
                List<String> teacherPhones = new ArrayList<>();
                teacherPhones.add(isur.getPhone());
                TeacherServiceBatchSetClassMastersParam.Query teacherClassQuery = TeacherServiceBatchSetClassMastersParam.Query.builder()
                        .appId(seewoConfig.getAppId())
                        .schoolUid(seewoConfig.getSchoolId())
                        .classUid(classData.getClassUid())
                        .userPhones(teacherPhones)
                        .build();
                teacherClassRequestBody.setQuery(teacherClassQuery);
                teacherClassParam.setRequestBody(teacherClassRequestBody);
                TeacherServiceBatchSetClassMastersRequest teacherClassRequest = new TeacherServiceBatchSetClassMastersRequest(teacherClassParam);
                System.out.println("入参：" + teacherClassRequest);
                //如果想要调用沙箱环境，请通过设置 teacherClassRequest 对象的 serverUrl 属性，如：
                //request.setServerUrl("https://openapi.test.seewo.com")
                //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
                TeacherServiceBatchSetClassMastersResult teacherClassResult = seewoClient.invoke(teacherClassRequest);
                System.out.println("出参：" + teacherClassResult);

                if (teacherClassResult == null) {
                    return CommonResult.fail("希沃教师数据新增失败！");
                }

                if (!teacherClassResult.getResponseBody().getCode().equals("000000")) {
                    return CommonResult.fail(result.getResponseBody().getMessage());
                }

                //endregion
            }

            //region 百胜添加教师数据
            SmartDepartment departmentData = smartDepartmentService.getSmartById(isur.getDepartmentId());
            if (departmentData == null) {
                return CommonResult.fail("部门数据无效，新增教师失败");
            }

            String departmentNo = departmentData.getBsDepartmentNo();//"DT1701845086538710";
            String appId = controlConfig.getAppId();
            String schoolno = controlConfig.getSchoolCode();
            String timestamp = TimeExchange.DateNowTimeStamo();
            String appSecret = controlConfig.getAppSecret();
            String url = controlConfig.getUrl() + "staff/create";

            JSONObject jsonobject = new JSONObject();
            jsonobject.put("appid", appId);
            String str = "{\"staff_name\":\"" + isur.getName() + "\",\"department_no\":\"" + departmentNo + "\",\"stafft_number\":\"" + isur.getCardNo() + "\",\"staff_phone\":\"" + isur.getPhone() + "\",\"staff_sex\":\"" + isur.getSexId() + "\",\"staff_photo\":\"" + imageUtils.getBase64Url(isur.getHeadImage()) + "\",\"staff_tgno\":\"" + eTimeGroup.stringOf(isur.getTimeGroupId()) + "\"}";
            String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
            jsonobject.put("data", aesStr);
            jsonobject.put("schoolno", schoolno);
            jsonobject.put("timestamp", timestamp);

            String md5Str = "appid=" + appId + "&data={\"staff_name\":\"" + isur.getName() + "\",\"department_no\":\"" + departmentNo + "\",\"stafft_number\":\"" + isur.getCardNo() + "\",\"staff_phone\":\"" + isur.getPhone() + "\",\"staff_sex\":\"" + isur.getSexId() + "\",\"staff_photo\":\"" + imageUtils.getBase64Url(isur.getHeadImage()) + "\",\"staff_tgno\":\"" + eTimeGroup.stringOf(isur.getTimeGroupId()) + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
            String sign = CommonUtil.MD5(md5Str);
            //sign签名
            jsonobject.put("sign", sign);

            //返回的结果中 code为1表示成功
            String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

            if (bsResult.contains("添加成功")) {
                ObjectMapper objectMapper = new ObjectMapper();
                BsStaffVo staff = objectMapper.readValue(bsResult, BsStaffVo.class);

                // URL解码
                String decodedUrl = URLDecoder.decode(staff.getData(), "UTF-8");

                BsStaffNoVo staffNo = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsStaffNoVo.class);
                su.setBsStaffCode(staffNo.getStaff_no());
            }
            //endregion

        }
        //endregion

        //最后都要把数据加入到数据库中
        int result = smartUserService.insertSmartUser(su);

        //新增用户得将用户信息通过接口推送到希沃、百胜

        return result > 0 ? CommonResult.ok("添加成功") : CommonResult.fail("添加失败");
    }

    /**
     * 更新用户
     *
     * @param usur          更新用户数据
     * @param bindingResult
     * @return
     */
    @Override
    public CommonResult updateSmartUserById(updateSmartUserRequest usur, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //更新的同时将百胜用户信息同步过去或者同步过来？
        SmartUser su = smartUserService.getSmartById(usur.getId());
        if (su == null) {
            CommonResult.fail("用户数据已失效，修改失败！");
        }

        su.setTimeGroupId(usur.getTimeGroupId());
        su.setCardNo(usur.getCardNo());
        su.setName(usur.getName());
        su.setIdentityId(usur.getIdentityId());
        su.setIdCard(usur.getIdCard());
        su.setSexId(usur.getSexId());
        su.setDepartmentId(usur.getDepartmentId());
        su.setHeadImage(usur.getHeadImage());
        su.setGrade(usur.getGrade());
        su.setCollege(usur.getCollege());
        su.setSpeciality(usur.getSpeciality());
        su.setSchoolClass(usur.getSchoolClass());
        su.setCampus(usur.getCampus());
        su.setDormitoryNumber(usur.getDormitoryNumber());
        su.setPhone(usur.getPhone());
        su.setAffiliate(StringUtils.join(usur.getAffiliate(), ","));
        su.setTitle(usur.getTitle());
        su.setAddress(usur.getAddress());
        su.setNation(usur.getNation());
        su.setOfStudent(usur.getOfStudent());
        su.setGraduate(usur.getGraduate());
        su.setDuties(usur.getDuties());
        su.setIsCancel(eLogOff.Unlogout.getValue());

        if (usur.getIdentityId().intValue() == eIdentityStatu.Parent.getValue()) {//家长
            //拿到被关联学生的信息去获取对应的卡号
            //有多个学生就循环学生
            if (usur.getAffiliate() == null) {
                return CommonResult.fail("被关联人不能为空");
            }

            if (usur.getAffiliate().size() <= 0) {
                return CommonResult.fail("被关联人不能为空");
            }

            List<SmartUser> studentDatas = smartUserService.getSmartUserIds(usur.getAffiliate());

            //region 希沃新增编辑学生家长信息
            //学生与家长列表，最大100条
            List<ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem> studentParents = new ArrayList<>();
            for (SmartUser student : studentDatas) {
                ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem students = ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem.builder()
                        .studentCode(student.getCardNo())
                        .build();
                studentParents.add(students);

                //家长列表，最多4个
                ParentServiceBatchSaveOrUpdateParentsParam.ParentsItem parents = ParentServiceBatchSaveOrUpdateParentsParam.ParentsItem.builder()
                        .name(usur.getName())
                        .phone(usur.getPhone())
                        .index(0)
                        .build();

                students.setParents(java.util.Collections.singletonList(parents));
            }

            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            ParentServiceBatchSaveOrUpdateParentsParam param = new ParentServiceBatchSaveOrUpdateParentsParam();
            //响应体，MimeType为 application/json
            ParentServiceBatchSaveOrUpdateParentsParam.RequestBody requestBody = ParentServiceBatchSaveOrUpdateParentsParam.RequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //query
            ParentServiceBatchSaveOrUpdateParentsParam.Query query = ParentServiceBatchSaveOrUpdateParentsParam.Query.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .build();
            requestBody.setQuery(query);
            query.setStudentParents(studentParents);
            param.setRequestBody(requestBody);
            ParentServiceBatchSaveOrUpdateParentsRequest request = new ParentServiceBatchSaveOrUpdateParentsRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            ParentServiceBatchSaveOrUpdateParentsResult result = seewoClient.invoke(request);
            System.out.println("出参：" + result);

            if (result == null) {
                return CommonResult.fail("希沃学生家长数据更新失败！");
            }

            if (!result.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(result.getResponseBody().getMessage());
            }
            //endregion

        } else if (usur.getIdentityId().intValue() == eIdentityStatu.Student.getValue()) {//学生

            //region 年级和班级不能为空
            if (usur.getGrade() == null) {
                return CommonResult.fail("学生年级不能为空");
            }
            if (usur.getSchoolClass() == null) {
                return CommonResult.fail("学生班级不能为空");
            }
            //endregion

            //region 更新希沃学生信息
            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            StudentServiceUpdateStudentInfoParam param = new StudentServiceUpdateStudentInfoParam();
            //响应体，MimeType为 application/json
            StudentServiceUpdateStudentInfoParam.RequestBody requestBody = StudentServiceUpdateStudentInfoParam.RequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //query
            StudentServiceUpdateStudentInfoParam.Query query = StudentServiceUpdateStudentInfoParam.Query.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .studentUid(su.getXwStudentUid())
                    .studentCode(su.getCardNo())
                    .studentName(su.getName())
                    .build();
            requestBody.setQuery(query);
            param.setRequestBody(requestBody);
            StudentServiceUpdateStudentInfoRequest request = new StudentServiceUpdateStudentInfoRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            StudentServiceUpdateStudentInfoResult result = seewoClient.invoke(request);
            System.out.println("出参：" + result);

            if (result == null) {
                return CommonResult.fail("希沃学生数据更新失败！");
            }

            if (!result.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(result.getResponseBody().getMessage());
            }
            //endregion

            //region 更新百胜学生信息
            String appId = controlConfig.getAppId();
            String schoolno = controlConfig.getSchoolCode();
            String timestamp = TimeExchange.DateNowTimeStamo();
            String appSecret = controlConfig.getAppSecret();
            String url = controlConfig.getUrl() + "student/update";

            JSONObject jsonobject = new JSONObject();
            jsonobject.put("appid", appId);
            String str = "{\"student_no\":\"" + su.getBsStudentNo() + "\",\"student_name\":\"" + su.getName() + "\",\"student_number\":\"" + su.getCardNo() + "\",\"student_sex\":\"" + su.getSexId() + "\",\"student_idcard\":\"" + su.getIdCard() + "\",\"student_photo\":\"" + imageUtils.getBase64Url(su.getHeadImage()) + "\",\"student_tgno\":\"" + eTimeGroup.stringOf(su.getTimeGroupId()) + "\"}";
            String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
            jsonobject.put("data", aesStr);
            jsonobject.put("schoolno", schoolno);
            jsonobject.put("timestamp", timestamp);

            String md5Str = "appid=" + appId + "&data={\"student_no\":\"" + su.getBsStudentNo() + "\",\"student_name\":\"" + su.getName() + "\",\"student_number\":\"" + su.getCardNo() + "\",\"student_sex\":\"" + su.getSexId() + "\",\"student_idcard\":\"" + su.getIdCard() + "\",\"student_photo\":\"" + imageUtils.getBase64Url(su.getHeadImage()) + "\",\"student_tgno\":\"" + eTimeGroup.stringOf(su.getTimeGroupId()) + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
            String sign = CommonUtil.MD5(md5Str);
            //sign签名
            jsonobject.put("sign", sign);

            //返回的结果中 code为1表示成功
            String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

            if(bsResult.contains("人员不存在或已删除")){
                //获取班级Uid
                SmartClass classData = smartClassService.getSmartClassById(usur.getSchoolClass());
                if (classData == null) {
                    return CommonResult.fail("班级数据无效，新增失败");
                }

                //region 百胜新增学生信息
                String insertUrl = controlConfig.getUrl() + "student/create";

                JSONObject insertJsonobject = new JSONObject();
                jsonobject.put("appid", appId);
                String insertStr = "{\"student_name\":\"" + usur.getName() + "\",\"classtab_no\":\"" + classData.getBsClassNo() + "\",\"student_number\":\"" + usur.getCardNo() + "\",\"student_sex\":\"" + usur.getSexId() + "\",\"student_photo\":\"" + imageUtils.getBase64Url(usur.getHeadImage()) + "\",\"student_tgno\":\"" + eTimeGroup.stringOf(usur.getTimeGroupId()) + "\"}";
                String insertAesStr = URLEncoder.encode(AesTestOne.encrypt(insertStr, controlConfig.getAppSecret()), "UTF-8");
                jsonobject.put("data", insertAesStr);
                jsonobject.put("schoolno", schoolno);
                jsonobject.put("timestamp", timestamp);

                String insertMd5Str = "appid=" + appId + "&data={\"student_name\":\"" + usur.getName() + "\",\"classtab_no\":\"" + classData.getBsClassNo() + "\",\"student_number\":\"" + usur.getCardNo() + "\",\"student_sex\":\"" + usur.getSexId() + "\",\"student_photo\":\"" + imageUtils.getBase64Url(usur.getHeadImage()) + "\",\"student_tgno\":\"" + eTimeGroup.stringOf(usur.getTimeGroupId()) + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
                String insertSign = CommonUtil.MD5(insertMd5Str);
                //sign签名
                jsonobject.put("sign", insertSign);

                //返回的结果中 code为1表示成功
                String insertBsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

                if (insertBsResult.contains("添加成功")) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    BsStudentVo grade = objectMapper.readValue(insertBsResult, BsStudentVo.class);

                    // URL解码
                    String decodedUrl = URLDecoder.decode(grade.getData(), "UTF-8");

                    BsStudentNoVo studentNo = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsStudentNoVo.class);
                    su.setBsStudentNo(studentNo.getStudent_no());
                }
                //endregion
                if (!insertBsResult.contains("更新成功")) {
                    return CommonResult.fail("百胜学生信息更新失败");
                }
            }

            //endregion

        } else if (usur.getIdentityId().intValue() == eIdentityStatu.Teacher.getValue()) {//教师
            //region 希沃更新教师数据
            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            TeacherServiceBatchSaveOrUpdateTeacherParam param = new TeacherServiceBatchSaveOrUpdateTeacherParam();
            //请求体，MimeType为 application/json
            TeacherServiceBatchSaveOrUpdateTeacherParam.JSONRequestBody requestBody = TeacherServiceBatchSaveOrUpdateTeacherParam.JSONRequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //老师信息
            TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherBatchQuery query = TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherBatchQuery.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .build();
            requestBody.setQuery(query);
            // 老师列表
            TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherQuery teachers = TeacherServiceBatchSaveOrUpdateTeacherParam.SaveOrUpdateTeacherQuery.builder()
                    .account(su.getPhone())//用户账号
                    .name(su.getName())//用户名字
                    .accountType("phone")//账号类型 phone：手机号  email：邮箱
                    .teacherCode("")//教师工号
                    .photoUrl(su.getHeadImage())//图片链接
                    .build();
            query.setTeachers(java.util.Collections.singletonList(teachers));
            param.setRequestBody(requestBody);
            TeacherServiceBatchSaveOrUpdateTeacherRequest request = new TeacherServiceBatchSaveOrUpdateTeacherRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            TeacherServiceBatchSaveOrUpdateTeacherResult result = seewoClient.invoke(request);
            System.out.println("出参：" + result);

            if (result == null) {
                return CommonResult.fail("希沃教师数据更新失败！");
            }

            if (!result.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(result.getResponseBody().getMessage());
            }

            su.setXwTeacherCode(result.getResponseBody().getData().get(0).getTeacherCode());
            //endregion

            //region 百胜更新教师数据
            SmartDepartment departmentData = smartDepartmentService.getSmartById(su.getDepartmentId());
            if (departmentData == null) {
                return CommonResult.fail("部门数据无效，更新教师失败");
            }

            String departmentNo = departmentData.getBsDepartmentNo();
            String appId = controlConfig.getAppId();
            String schoolno = controlConfig.getSchoolCode();
            String timestamp = TimeExchange.DateNowTimeStamo();
            String appSecret = controlConfig.getAppSecret();
            String url = controlConfig.getUrl() + "staff/update";

            JSONObject jsonobject = new JSONObject();
            jsonobject.put("appid", appId);
            String str = "{\"staff_no\":\"" + su.getBsStaffCode() + "\"staff_name\":\"" + su.getName() + "\",\"department_no\":\"" + departmentNo + "\",\"stafft_number\":\"" + su.getCardNo() + "\",\"staff_phone\":\"" + su.getPhone() + "\",\"staff_sex\":\"" + su.getSexId() + "\",\"staff_photo\":\"" + imageUtils.getBase64Url(su.getHeadImage()) + "\",\"staff_tgno\":\"" + eTimeGroup.stringOf(su.getTimeGroupId()) + "\"}";
            String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
            jsonobject.put("data", aesStr);
            jsonobject.put("schoolno", schoolno);
            jsonobject.put("timestamp", timestamp);

            String md5Str = "appid=" + appId + "&data={\"staff_no\":\"" + su.getBsStaffCode() + "\"staff_name\":\"" + su.getName() + "\",\"department_no\":\"" + departmentNo + "\",\"stafft_number\":\"" + su.getCardNo() + "\",\"staff_phone\":\"" + su.getPhone() + "\",\"staff_sex\":\"" + su.getSexId() + "\",\"staff_photo\":\"" + imageUtils.getBase64Url(su.getHeadImage()) + "\",\"staff_tgno\":\"" + eTimeGroup.stringOf(su.getTimeGroupId()) + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
            String sign = CommonUtil.MD5(md5Str);
            //sign签名
            jsonobject.put("sign", sign);

            //返回的结果中 code为1表示成功
            String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

            if (bsResult.contains("添加成功")) {
                ObjectMapper objectMapper = new ObjectMapper();
                BsStaffVo staff = objectMapper.readValue(bsResult, BsStaffVo.class);

                // URL解码
                String decodedUrl = URLDecoder.decode(staff.getData(), "UTF-8");

                BsStaffNoVo staffNo = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsStaffNoVo.class);
                su.setBsStaffCode(staffNo.getStaff_no());
            }
            //endregion
        }

        int result = smartUserService.updateSmartUser(su);
        return result > 0 ? CommonResult.ok("修改成功") : CommonResult.fail("修改失败");
    }

    /**
     * 用户分页数据查询
     *
     * @param currentPage  当前页数
     * @param pageCount    一页数据条数
     * @param departmentId 部门ID
     * @return
     */
    @Override
    public CommonResult queryPageSmartUser(int currentPage, int pageCount, Integer departmentId, String name) {
        //获取该部门下的所有子级部门ID
        List<Integer> childDepartmentIds = new ArrayList<>();
        List<SmartDepartment> departments = smartDepartmentService.list(null);
        childDepartmentIds.add(departmentId);
        QueryDepartmentTreeRecords(departmentId, departments, childDepartmentIds);

        if (departmentId == null) {
            childDepartmentIds = null;
        }

        PageUtils<UserVo> result = smartUserService.querySmartUserPages(currentPage, pageCount, childDepartmentIds, name);

        if (result != null && result.getList() != null) {
            List<Integer> studentIds = new ArrayList<>();
            List<String> studentStrs = Arrays.asList(StringUtils.join(result.getList().stream().map(UserVo::getAffiliate).collect(Collectors.toList()), ",").split(","));
            for (String studentStr : studentStrs) {
                if (!ObjectUtils.isEmpty(studentStr)) {
                    studentIds.add(Integer.valueOf(studentStr));
                }
            }
            List<SmartUser> students = smartUserService.getSmartUserByIds(studentIds);
            List<SmartClass> classs = smartClassService.list(null);

            for (UserVo data : result.getList()) {
                data.setIdentity(eIdentityStatu.stringOf(data.getIdentityId()));
                data.setSex(eSexStatu.stringOf(data.getSexId()));
                Optional<SmartDepartment> departmentData = departments == null ? null : departments.stream().filter(e -> e.getId().equals(data.getDepartmentId())).findFirst();
                if (departmentData != null && departmentData.isPresent()) {
                    data.setDepartment(departmentData.get().getName());
                }
                Optional<SmartClass> nowClass = classs == null ? null : classs.stream().filter(e -> e.getId().equals(data.getSchoolClass())).findFirst();
                if (nowClass != null && nowClass.isPresent()) {
                    data.setClassStr(nowClass.get().getName());
                }

                List<AffiliateUserVo> datas = new ArrayList<>();
                if (data.getAffiliate() != null) {
                    List<String> affiliates = Arrays.asList(data.getAffiliate().split(","));
                    for (String a : affiliates) {
                        if (!ObjectUtils.isEmpty(a)) {
                            Optional<SmartUser> student = students.stream().filter(e -> e.getId().equals(Integer.valueOf(a))).findFirst();
                            if (student != null && student.isPresent()) {
                                AffiliateUserVo affiliate = new AffiliateUserVo();
                                affiliate.setId(student.get().getId());
                                affiliate.setName(student.get().getName());
                                affiliate.setCardNo(student.get().getCardNo());
                                affiliate.setDepartmentId(student.get().getDepartmentId());
                                datas.add(affiliate);
                            }
                        }
                    }
                }
                data.setAffiliates(datas);
            }
        }

        return CommonResult.ok(result);
    }

    @Override
    public void smartUserExport(HttpServletResponse response, Integer departmentId, String name) {
        //获取该部门下的所有子级部门ID
        List<Integer> childDepartmentIds = new ArrayList<>();
        List<SmartDepartment> departments = smartDepartmentService.list(null);
        childDepartmentIds.add(departmentId);
        QueryDepartmentTreeRecords(departmentId, departments, childDepartmentIds);

        List<SmartUser> users = smartUserService.querySmartUsers(childDepartmentIds, name);

        //导出
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("用户信息管理");
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("序号");
        headerRow.createCell(1).setCellValue("学号");
        headerRow.createCell(2).setCellValue("姓名");
        headerRow.createCell(3).setCellValue("身份");
        headerRow.createCell(4).setCellValue("身份证号");
        headerRow.createCell(5).setCellValue("性别");
        headerRow.createCell(6).setCellValue("部门");
        headerRow.createCell(7).setCellValue("人脸");
        headerRow.createCell(8).setCellValue("年级");
        headerRow.createCell(9).setCellValue("学院");
        headerRow.createCell(10).setCellValue("专业");
        headerRow.createCell(11).setCellValue("班级");
        headerRow.createCell(12).setCellValue("校区");
        headerRow.createCell(13).setCellValue("宿舍号");
        headerRow.createCell(14).setCellValue("手机号");
        headerRow.createCell(15).setCellValue("关联人");
        headerRow.createCell(16).setCellValue("职称");
        headerRow.createCell(17).setCellValue("家庭住址");
        headerRow.createCell(18).setCellValue("民族");
        headerRow.createCell(19).setCellValue("生源地");
        headerRow.createCell(20).setCellValue("毕业学校");
        headerRow.createCell(21).setCellValue("职务");

        for (int i = 0; i < users.size(); i++) {
            SmartUser user = users.get(i);

            Row dataRow = sheet.createRow(i + 1);
            dataRow.createCell(0).setCellValue(i + 1);
            dataRow.createCell(1).setCellValue(user.getCardNo());
            dataRow.createCell(2).setCellValue(user.getName());
            dataRow.createCell(3).setCellValue(eIdentityStatu.stringOf(user.getIdentityId()));
            dataRow.createCell(4).setCellValue(user.getIdCard());
            dataRow.createCell(5).setCellValue(eSexStatu.stringOf(user.getSexId()));
            //获取父级部门ID
            Optional<SmartDepartment> department = departments.stream().filter(e -> e.getId().equals(user.getDepartmentId())).findFirst();
            if (department != null && department.isPresent()) {
                dataRow.createCell(6).setCellValue(QueryParentDepartments(department.get().getParentId(), departments, null));
            }

            dataRow.createCell(7).setCellValue(user.getHeadImage());
            dataRow.createCell(8).setCellValue(user.getGrade());
            dataRow.createCell(9).setCellValue(user.getCollege());
            dataRow.createCell(10).setCellValue(user.getSpeciality());
            dataRow.createCell(11).setCellValue(user.getSchoolClass());
            dataRow.createCell(12).setCellValue(user.getCampus());
            dataRow.createCell(13).setCellValue(user.getDormitoryNumber());
            dataRow.createCell(14).setCellValue(user.getPhone());
            dataRow.createCell(15).setCellValue(user.getAffiliate());
            dataRow.createCell(16).setCellValue(user.getTitle());
            dataRow.createCell(17).setCellValue(user.getAddress());
            dataRow.createCell(18).setCellValue(user.getNation());
            dataRow.createCell(19).setCellValue(user.getOfStudent());
            dataRow.createCell(20).setCellValue(user.getGraduate());
            dataRow.createCell(21).setCellValue(user.getDuties());
        }

        // 将工作簿写入文件
        ExcelUtils.excelDownload(workbook, "用户信息.xlsx", response);
    }

    /**
     * 根据父级ID获取树形数据
     *
     * @param parentID 父级ID
     * @param lists    数据集合
     * @return
     */
    private List<DepartmentTreeVo> QueryDepartmentTreeRecords(Integer parentID, List<SmartDepartment> lists, List<Integer> departmentIds) {
        List<DepartmentTreeVo> newTrees = new ArrayList<>();

        List<SmartDepartment> datas = lists.stream().filter(e -> e.getParentId().equals(parentID)).collect(Collectors.toList());

        for (SmartDepartment data : datas) {
            departmentIds.add(data.getId());
            QueryDepartmentTreeRecords(data.getId(), lists, departmentIds);
        }

        return newTrees;
    }


    /**
     * 根据父级ID获取父级数据
     *
     * @param parentID 子级ID
     * @param lists    数据集合
     * @return
     */
    private String QueryParentDepartments(Integer parentID, List<SmartDepartment> lists, String departmentStr) {

        Optional<SmartDepartment> data = lists.stream().filter(e -> e.getId().equals(parentID)).findFirst();

        if (data != null && data.isPresent()) {
            departmentStr = departmentStr == null ? data.get().getName() : data.get().getName() + "/" + departmentStr;
            departmentStr = QueryParentDepartments(data.get().getParentId(), lists, departmentStr);
        }

        return departmentStr;
    }

    @Override
    public CommonResult deleteSmartUserById(useridsRequest ur, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        int data = smartUserService.getSmartUserCountByIds(ur.getUserIds());

        if (data != ur.getUserIds().size()) {
            return CommonResult.fail("存在无效用户数据，删除失败！");
        }

        int result = smartUserService.deleteSmartUserByIds(ur.getUserIds());

        return result > 0 ? CommonResult.ok("删除成功") : CommonResult.fail("删除失败");
    }

    @Override
    public CommonResult queryAffiliateUserById(int id) {
        List<AffiliateUserVo> result = smartUserService.queryAffiliateUserById(id);

        if (result != null && result.size() > 0) {
            List<SmartDepartment> departments = smartDepartmentService.list(null);
            for (AffiliateUserVo data : result) {
                //获取父级部门ID
                Optional<SmartDepartment> department = departments.stream().filter(e -> e.getId().equals(data.getDepartmentId())).findFirst();
                if (department != null && department.isPresent()) {
                    String departmentName = QueryParentDepartments(department.get().getParentId(), departments, null);
                    data.setDepartmentName(departmentName);
                }
            }
        }

        return CommonResult.ok(result);
    }

    @Override
    public CommonResult downloadUserExcel() {
        return CommonResult.ok("200", "操作成功", "https://wanzai-1306339220.cos.ap-shanghai.myqcloud.com/excelModel/人员信息表.xlsx");
    }

    @Override
    public CommonResult queryStudents(int userId) {

        List<SmartUser> students = new ArrayList<>();
        SmartUser user = smartUserService.getSmartById(userId);
        if (user == null) {
            return CommonResult.fail("用户信息为空，获取学生列表数据失败");
        }

        if (user.getAffiliate() == null) {
            return CommonResult.ok(students);
        }

        List<Integer> affiliateIds = new ArrayList<>();
        List<String> affiliates = Arrays.asList(user.getAffiliate().split(","));
        for (String affiliate : affiliates) {
            affiliateIds.add(Integer.valueOf(affiliate));
        }

        students = smartUserService.getSmartUserByIds(affiliateIds);

        List<ParentOfStudentsVo> result = new ArrayList<>();
        for (SmartUser student : students) {
            ParentOfStudentsVo data = new ParentOfStudentsVo();
            data.setId(student.getId());
            data.setName(student.getName());
            data.setCardNo(student.getCardNo());
            data.setDepartmentId(student.getDepartmentId());
            result.add(data);
        }

        return CommonResult.ok(result);
    }


    @Override
    public CommonResult queryInfoData(int id) {

        SmartUser su = smartUserService.getSmartById(id);
        if (su == null) {
            return CommonResult.fail("用户信息失效，获取用户信息失败");
        }

        //部门数据集合
        List<SmartDepartment> departments = smartDepartmentService.list(null);

        WechatUserVo userData = new WechatUserVo();
        userData.setId(su.getId());
        userData.setCardNo(su.getCardNo());
        userData.setTimeGroupId(su.getTimeGroupId());
        userData.setName(su.getName());
        userData.setIdentityId(su.getIdentityId());
        userData.setIdCard(su.getIdCard());
        userData.setSexId(su.getSexId());
        userData.setDepartmentId(su.getDepartmentId());

        Optional<SmartDepartment> department = departments.stream().filter(e -> e.getId().equals(su.getDepartmentId())).findFirst();
        if (department != null && department.isPresent()) {
            String departmentName = QueryParentDepartments(department.get().getParentId(), departments, null);
            userData.setDepartmentName(departmentName == null ? "" : departmentName + "/" + department.get().getName());
        }

        userData.setHeadImage(su.getHeadImage());
        userData.setGrade(su.getGrade());
        userData.setCollege(su.getCollege());
        userData.setSpeciality(su.getSpeciality());
        userData.setSchoolClass(su.getSchoolClass());
        userData.setCampus(su.getCampus());
        userData.setDormitoryNumber(su.getDormitoryNumber());
        userData.setPhone(su.getPhone());
        userData.setAffiliate(su.getAffiliate());
        //查找关联人
        if (su.getIdentityId().intValue() == eIdentityStatu.Student.getValue()) {//学生
            List<AffiliateParentVo> parents = smartUserService.queryAffiliateParents(su.getId());
            if (parents != null && parents.size() > 0) {
                String affiliateStr = StringUtils.join(parents.stream().map(AffiliateParentVo::getName).collect(Collectors.toList()), ",");
                userData.setAffiliateName(affiliateStr);
            }
        } else if (su.getIdentityId().intValue() == eIdentityStatu.Parent.getValue()) {//家长
            if (su.getAffiliate() != null) {
                List<String> affiliates = Arrays.asList(su.getAffiliate().split(","));
                List<SmartUser> childs = smartUserService.getSmartUserIds(affiliates);
                String affiliateStr = StringUtils.join(childs.stream().map(SmartUser::getName).collect(Collectors.toList()), ",");
                userData.setAffiliateName(affiliateStr);
            }
        }
        //关联人名称用逗号隔开

        userData.setTitle(su.getTitle());
        userData.setAddress(su.getAddress());
        userData.setNation(su.getNation());
        userData.setOfStudent(su.getOfStudent());
        userData.setGraduate(su.getGraduate());
        userData.setDuties(su.getDuties());
        userData.setIsPush(su.getIsPush());
        userData.setIsCancel(su.getIsCancel());
        userData.setOpenId(su.getOpenId());
        userData.setXOpenId(su.getXOpenId());
        userData.setGzhOpenId(su.getGzhOpenId());
        userData.setXwStudentUid(su.getXwStudentUid());
        userData.setBsStudentNo(su.getBsStudentNo());
        userData.setXwTeacherCode(su.getXwTeacherCode());
        userData.setBsStaffCode(su.getBsStaffCode());

        return CommonResult.ok(userData);
    }

    @Override
    public CommonResult bindStudent(bindStudentRequest bsr, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        SmartUser parentUser = smartUserService.getSmartById(bsr.getUserId());
        if (parentUser == null) {
            return CommonResult.fail("当前用户信息无效，绑定失败！");
        }

        if (parentUser.getIdentityId().intValue() != eIdentityStatu.Parent.getValue()) {
            return CommonResult.fail("当前用户身份无法进行绑定操作");
        }

        //查找是否存在学生数据
        SmartUser studentUser = smartUserService.queryUserInfo(bsr.getName(), bsr.getCardNo(), bsr.getIdCard());
        if (studentUser == null) {
            return CommonResult.fail("当前学生不存在，绑定失败！");
        }

        //判断是否已绑定过
        if (parentUser.getAffiliate() == null) {
            parentUser.setAffiliate(String.valueOf(studentUser.getId()));
        } else {
            List<String> newAffiliates = new ArrayList<>();
            List<String> affiliates = Arrays.asList(parentUser.getAffiliate().split(","));
            long existCount = affiliates.stream().filter(e -> e.equals(String.valueOf(studentUser.getId()))).count();
            if (existCount > 0) {
                return CommonResult.fail("当前学生信息已绑定过，请勿重复操作！");
            }

            parentUser.setAffiliate(parentUser.getAffiliate() + "," +String.valueOf(studentUser.getId()));
        }

        //region 新增希沃学生家长信息
        //初始化客户端
        SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
        ParentServiceBatchSaveOrUpdateParentsParam param = new ParentServiceBatchSaveOrUpdateParentsParam();
        //响应体，MimeType为 application/json
        ParentServiceBatchSaveOrUpdateParentsParam.RequestBody requestBody = ParentServiceBatchSaveOrUpdateParentsParam.RequestBody.builder()
                .build();
        param.setRequestBody(requestBody);
        //query
        ParentServiceBatchSaveOrUpdateParentsParam.Query query = ParentServiceBatchSaveOrUpdateParentsParam.Query.builder()
                .appId(seewoConfig.getAppId())
                .schoolUid(seewoConfig.getSchoolId())
                .build();
        requestBody.setQuery(query);
        //学生与家长列表，最大100条
        ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem studentParents = ParentServiceBatchSaveOrUpdateParentsParam.StudentParentsItem.builder()
                .studentCode(studentUser.getCardNo())
                .build();
        query.setStudentParents(java.util.Collections.singletonList(studentParents));
        //家长列表，最多4个
        ParentServiceBatchSaveOrUpdateParentsParam.ParentsItem parents = ParentServiceBatchSaveOrUpdateParentsParam.ParentsItem.builder()
                .name(parentUser.getName())
                .phone(parentUser.getPhone())
                .index(0)
                .build();
        studentParents.setParents(java.util.Collections.singletonList(parents));
        param.setRequestBody(requestBody);
        ParentServiceBatchSaveOrUpdateParentsRequest request = new ParentServiceBatchSaveOrUpdateParentsRequest(param);
        System.out.println("入参：" + request);
        //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
        //request.setServerUrl("https://openapi.test.seewo.com")
        //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
        ParentServiceBatchSaveOrUpdateParentsResult result = seewoClient.invoke(request);
        System.out.println("出参：" + result);

        if (result == null) {
            return CommonResult.fail("希沃学生家长数据添加失败！");
        }

        if (!result.getResponseBody().getCode().equals("000000")) {
            return CommonResult.fail(result.getResponseBody().getMessage());
        }
        //endregion

        int updateResult = smartUserService.updateSmartUser(parentUser);

        return updateResult > 0 ? CommonResult.ok("绑定成功") : CommonResult.fail("绑定失败");
    }
}

