package BaseTeacherDao import ( "dsBaseRpc/Const" "dsBaseRpc/RpcService/BaseOrganization/BaseOrganizationDao" "dsBaseRpc/RpcService/BaseTeacher/BaseTeacherProto" "dsBaseRpc/RpcService/SysDict/SysDictKit" "dsBaseRpc/RpcService/SysLoginperson/SysLoginpersonDao" "dsBaseRpc/RpcService/SysLoginperson/SysLoginpersonService" "dsBaseRpc/Utils/CommonUtil" "dsBaseRpc/Utils/DateUtil" "dsBaseRpc/Utils/DbUtil" "dsBaseRpc/Utils/ExcelUtil" "dsBaseRpc/Utils/FileUtil" "dsBaseRpc/Utils/IdCardUtil" "dsBaseRpc/Utils/LogUtil" "dsBaseRpc/Utils/PinYinUtil" "dsBaseRpc/Utils/RedisUtil" "dsBaseRpc/Utils/SqlKit" "dsBaseRpc/models" "fmt" "github.com/pkg/errors" "github.com/xormplus/builder" "github.com/xormplus/xorm" "github.com/xuri/excelize/v2" "strconv" ) var db = DbUtil.Engine //记录操作日志 func ActionLog(ms []models.TBaseTeacher, actionCode string, actionPersonId string, actionIp string) { msLog := make([]models.TBaseTeacherLog, len(ms)) for i := range ms { _ = CommonUtil.CopyFields(ms[i], &msLog[i]) msLog[i].LogId = CommonUtil.GetUUID() msLog[i].ActionCode = actionCode msLog[i].ActionIpAddress = actionIp msLog[i].ActionPersonId = actionPersonId } //批量保存 _, _ = db.Insert(msLog) } //通过主键集合,查找对应的实体bean集合 func GetByIds(ids []string) ([]models.TBaseTeacher, error) { ms := make([]models.TBaseTeacher, 0) err := db.In("person_id", ids).Find(&ms) if err != nil { return nil, err } return ms, nil } /** 功能:获取指定部门下的排序号最大值 作者:黄海 时间:2020-06-03 */ func GetMaxSortId(OrgId string) int64 { //取最大值 sql := "select ifnull(max(sort_id),0) as maxSortId from t_base_teacher_org where org_id=? and b_use=1" listSort, _ := db.SQL(sql, OrgId).Query().List() SortId := listSort[0]["maxSortId"].(int64) return SortId } //增加 func AddBaseTeacher(session *xorm.Session, model models.TBaseTeacher) (int64, error) { //插入基本表 count, err := session.Insert(model) return count, err } //修改 func UpdateBaseTeacher(model models.TBaseTeacher, ForceUpdateFields []string) (int64, error) { //1、清除Redis缓存 var ids = []string{model.PersonId} var selector = SqlKit.GetBean("t_base_teacher") SqlKit.DeleteCacheByIds(ids, selector) //更改登录表中的教师姓名 _, _ = SysLoginpersonDao.UpdatePersonName(model.PersonId, model.Xm) //2、计算本次操作,有哪些字段需要更新 NeedUpdateFields := CommonUtil.GetNeedUpdateFields(model) //3、合并强制更新的字段 ForceUpdateFields = append(ForceUpdateFields, NeedUpdateFields...) //4、去重 ForceUpdateFields = CommonUtil.RemoveDuplicatesAndEmpty(ForceUpdateFields) //5、更新操作,强制更新这些列 affected, err := db.ID(model.PersonId).Cols(ForceUpdateFields...).Update(model) return affected, err } //分页查询 func PageBaseTeacher(in *BaseTeacherProto.QueryArg) ([]map[string]interface{}, int32, error) { //所在单位ID list := SqlKit.QueryByIds([]string{in.OrgId}, "t_base_organization") if list == nil { return nil, 0, errors.New("没有找到此单位代码!") } bureauId := list[0]["bureau_id"].(string) //接收传入参数 var limit = int(in.Limit) var offset = int((in.Page - 1) * in.Limit) // 注意使用limit时要使用方言 // 注意两个表关联时的on用法: var myBuilder = builder.Dialect(builder.MYSQL).Select(`t1.person_id,t1.identity_id,group_concat(t3.org_name) as org_name,t1.id_int,t1.xm,t1.xmpy,t1.cym,t1.xbm,t1.csrq,t1.mzm,t1.zzmmm,t1.sfzjlxm,t1.sfzjh,t1.xlm,t1.xwm,t1.zcm,t1.bzlbm,t1.cjny,t1.stage_id,t1.subject_id,t1.gwzym,t1.lxdh,t1.dzxx,t1.b_use,t1.state_id,t1.last_updated_time,t1.create_time,t2.bureau_id,t2.org_id`). From("t_base_teacher as t1"). LeftJoin("t_base_teacher_org as t2", "t1.person_id=t2.person_id and t2.b_use=1 and t2.bureau_id='"+bureauId+"'"). InnerJoin("t_base_organization as t3", "t2.org_id=t3.org_id"). OrderBy("t2.sort_id") if in.OrgId == bureauId { //如果是单位ID myBuilder.And(builder.Eq{"t2.bureau_id": in.OrgId}) } else { //如果是部门ID myBuilder.And(builder.Eq{"t2.org_id": in.OrgId}) } //姓名模糊搜索 myBuilder.And(builder.Like{"t1.xm", in.Xm}) //只要b_use=1 myBuilder.And(builder.Eq{"t1.b_use": 1}) //只要identity_id=2 myBuilder.And(builder.Eq{"t1.identity_id": 2}) //分组 myBuilder.GroupBy("t1.person_id") //分页 myBuilder.Limit(limit, offset) //获取拼接完成的SQL语句 sql, err := myBuilder.ToBoundSQL() if err != nil { return nil, 0, err } list, count, err := SqlKit.Query(sql) //扩展登录信息 _ = FillLoginInfo(&list) //对于教师是不是修改过账号进行判断 SysLoginpersonService.FillPwdIsChange(&list) //扩展是不是在多个单位+部门下 FillIsMultiOrg(&list) //填充主单位,主部门信息 FillMainBureauOrgInfo(&list) //返回结果 return list, count, err } /** 功能:填充一个人员在几个部门下 作者:黄海 时间:2020-08-05 */ func FillIsMultiOrg(list2 *[]map[string]interface{}) { list := *list2 var personIds = make([]string, 0) for i := range list { personIds = append(personIds, (list[i])["person_id"].(string)) } var myBuilder = builder.Dialect(builder.MYSQL).Select("person_id,count(*) as c"). From("t_base_teacher_org").Where(builder.In("person_id", personIds)).And(builder.Eq{"b_use": 1}). GroupBy("person_id") sql, _ := myBuilder.ToBoundSQL() _list, _ := db.SQL(sql).Query().List() //生成map var _map = make(map[string]int64, 0) for i := range _list { _map[_list[i]["person_id"].(string)] = _list[i]["c"].(int64) } for i := range list { list[i]["org_count"] = _map[list[i]["person_id"].(string)] } } /** 功能:填充一个人员的主单位,主部门 作者:黄海 时间:2020-08-05 */ func FillMainBureauOrgInfo(list2 *[]map[string]interface{}) { list := *list2 var personIds = make([]string, 0) for i := range list { personIds = append(personIds, (list[i])["person_id"].(string)) } var myBuilder = builder.Dialect(builder.MYSQL).Select("person_id,bureau_id,org_id,province_code,city_code,district_code,main_school_id"). From("t_base_teacher_org"). Where(builder.In("person_id", personIds)).And(builder.Eq{"b_use": 1}). And(builder.Eq{"is_main": 1}) sql, _ := myBuilder.ToBoundSQL() _listExtendInfo, _ := db.SQL(sql).Query().List() for i := range list { for j := range _listExtendInfo { if _listExtendInfo[j]["person_id"] == list[i]["person_id"] { list[i]["x_bureau_id"] = _listExtendInfo[j]["bureau_id"] list[i]["x_org_id"] = _listExtendInfo[j]["org_id"] list[i]["x_province_code"] = _listExtendInfo[j]["province_code"] list[i]["x_city_code"] = _listExtendInfo[j]["city_code"] list[i]["x_district_code"] = _listExtendInfo[j]["district_code"] list[i]["x_main_school_id"] = _listExtendInfo[j]["main_school_id"] break } } } } /** 功能:扩展登录信息 作者:黄海 时间:2020-6-15 */ func FillLoginInfo(list *[]map[string]interface{}) error { list2 := *list //哪些person_ids ids := CommonUtil.ConvertSqlListToArray(list2, "person_id") //在登录表中查找 var myBuilder = builder.Dialect(builder.MYSQL).Select("person_id,login_name,pwd,original_pwd,b_use"). From("t_sys_loginperson").Where(builder.Eq{"identity_id": 2}).And(builder.In("person_id", ids)) sql, err := myBuilder.ToBoundSQL() if err != nil { return err } list3, err := db.SQL(sql).Query().List() if err != nil { return err } //准备字典数据 _map := make(map[string]map[string]interface{}) for i := range list3 { _map[list3[i]["person_id"].(string)] = list3[i] } //对原始数据进行扩展 for i := range list2 { record := list2[i] _, ok := _map[record["person_id"].(string)]["login_name"] if ok { record["login_name"] = _map[record["person_id"].(string)]["login_name"].(string) record["pwd"] = _map[record["person_id"].(string)]["pwd"].(string) record["original_pwd"] = _map[record["person_id"].(string)]["original_pwd"].(string) record["login_b_use"] = _map[record["person_id"].(string)]["b_use"].(int64) } else { record["login_name"] = "未找到" record["pwd"] = "未找到" record["original_pwd"] = "未找到" var i int64 = 0 record["login_b_use"] = i } } return nil } /** 功能:获取指定部门的人员最大排序号 */ func getOrgMaxSortId(OrgId string) int32 { //1、目前这个部门,最大的SortId sql := "select ifnull(max(sort_id),0) as maxSortId from t_base_teacher_org where b_use=1 and org_id=?" listSortId, _ := db.SQL(sql, OrgId).Query().List() maxSortId := int32(listSortId[0]["maxSortId"].(int64)) return maxSortId } //批量教师修改部门 func ReviseTeacherOrg(Ids []string, OrgId string) error { //获取指定部门的人员最大排序号 maxSortId := getOrgMaxSortId(OrgId) //2、删除旧的部门关系 _ = DeleteTeacherOrgInfo(Ids, OrgId) //3、插入人员部门关系 _, _, _, _ = AddTeacherOrgInfo(Ids, OrgId, 1, maxSortId) return nil } //导出本单位教职工账号信息到EXCEL func ExportTeacherAccountInfoExcel(in *BaseTeacherProto.ModelArg) ([]map[string]interface{}, int32, error) { var myBuilder = builder.Dialect(builder.MYSQL).Select("t1.*,t3.org_name"). From("t_sys_loginperson as t1"). InnerJoin("t_base_teacher as t2", "t1.person_id=t2.person_id"). InnerJoin("t_base_teacher_org as t4", "t2.person_id=t4.person_id"). InnerJoin("t_base_organization as t3", "t4.org_id=t3.org_id") myBuilder.Where(builder.Eq{"t1.b_use": 1}). And(builder.Eq{"t2.b_use": 1}). And(builder.Eq{"t3.b_use": 1}). And(builder.Eq{"t4.b_use": 1}). And(builder.Eq{"t4.is_main": 1}). And(builder.Eq{"t3.bureau_id": in.BureauId}).And(builder.Eq{"t1.identity_id": 2}) myBuilder.OrderBy("t2.sort_id").OrderBy("t2.id_int") sql, err := myBuilder.ToBoundSQL() if err != nil { return nil, 0, err } list, count, err := SqlKit.Query(sql) return list, count, err } /** 功能:生成导入教师的EXCEL模板 作者:黄海 时间:2020-06-05 */ func ExportTeacherInfoExcel(targetPath string, bureauId string, ExportExcelStatus int32) { //1、配置文件 jsonTemplate := "teacher.json" f, s1, dictCols, SheetName := ExcelUtil.TemplateAddDict("teacher.xlsx", jsonTemplate) //添加注释 _ = f.AddComment(SheetName, "D201", `{"author":"示例: ","text":"1980-01-01"}`) //数据准备 list, _ := db.SQL(s1.Level2Sql[0][0]).Query().List() //初始列 var startDictCName string //终止列 var stopDictCName string for i := range list { dictCName, _ := excelize.ColumnNumberToName(dictCols) if i == 0 { startDictCName = dictCName } if i == len(list)-1 { stopDictCName = dictCName } dictCols++ stageName := list[i]["dict_value"].(string) _ = f.SetCellValue(SheetName, dictCName+CommonUtil.ConvertIntToString(1), stageName) //在学段下面第二行开始写入各个学段对应的学科 list2, _ := db.SQL(s1.Level2Sql[0][1], stageName).Query().List() for k := range list2 { subjectName := list2[k]["dict_value"].(string) _ = f.SetCellValue(SheetName, dictCName+CommonUtil.ConvertIntToString(k+2), subjectName) } //批量建立名称管理器 _ = f.SetDefinedName(&excelize.DefinedName{ Name: stageName, RefersTo: SheetName + "!$" + dictCName + "$2:$" + dictCName + "$" + CommonUtil.ConvertIntToString(len(list2)+1), Comment: stageName, Scope: SheetName, }) //隐藏字典列 _ = f.SetColVisible(SheetName, dictCName, false) } //学段限定 dvRange := excelize.NewDataValidation(true) dvRange.Sqref = "M" + CommonUtil.ConvertIntToString(ExcelUtil.HiddenRows+2) + ":M" + CommonUtil.ConvertIntToString(ExcelUtil.RowsCount+ExcelUtil.HiddenRows) dvRange.SetSqrefDropList("$" + startDictCName + "$1:$" + stopDictCName + "$1") _ = f.AddDataValidation(SheetName, dvRange) //学科级联绑定 dvRange = excelize.NewDataValidation(true) dvRange.Sqref = "N" + CommonUtil.ConvertIntToString(2+ExcelUtil.HiddenRows) + ":N" + CommonUtil.ConvertIntToString(ExcelUtil.RowsCount+ExcelUtil.HiddenRows) dvRange.SetSqrefDropList("INDIRECT($M" + CommonUtil.ConvertIntToString(ExcelUtil.HiddenRows+2) + ")") _ = f.AddDataValidation(SheetName, dvRange) //部门 sql := "select org_name as dict_value from t_base_organization where bureau_id=? and b_use=1 order by org_type,sort_id" list, _ = db.SQL(sql, bureauId).Query().List() if len(list) > 0 { //字典列从cols+1开始 dictCName, _ := excelize.ColumnNumberToName(dictCols) for j := range list { _ = f.SetCellValue(SheetName, dictCName+CommonUtil.ConvertIntToString(j+1), list[j]["dict_value"]) //隐藏字典列 _ = f.SetColVisible(SheetName, dictCName, false) //要设置下拉框的列 dvRange := excelize.NewDataValidation(true) dvRange.Sqref = "A" + CommonUtil.ConvertIntToString(2+ExcelUtil.HiddenRows) + ":A" + CommonUtil.ConvertIntToString(ExcelUtil.RowsCount+ExcelUtil.HiddenRows) c := "$" + dictCName + "$1:" + dictCName + "$" + CommonUtil.ConvertIntToString(ExcelUtil.RowsCount) dvRange.SetSqrefDropList(c) _ = f.AddDataValidation(SheetName, dvRange) } } if ExportExcelStatus > 0 { //将现有数据填充到下载的模板中 sql := `select t1.person_id,t2.org_name,t1.xm,t1.xbm,t1.csrq, t1.mzm,t1.zzmmm,t1.sfzjlxm, (case t1.sfzjh when '-1' then '' else t1.sfzjh end ) as sfzjh, t1.xlm,t1.xwm,t1.zcm,t1.bzlbm,t1.stage_id,t1.subject_id,t1.gwzym,t1.lxdh,t1.dzxx from t_base_teacher as t1 inner join t_base_teacher_org as t3 on t1.person_id=t3.person_id inner join t_base_organization as t2 on t3.org_id=t2.org_id where t3.bureau_id=? and t1.identity_id=2 and t1.b_use=1 and t3.b_use=1 and t3.is_main=1 order by t3.sort_id,t1.id_int` list, _ := db.SQL(sql, bureauId).Query().List() for i := range list { record := list[i] //扩展性别 if record["xbm"].(string) == "1" { record["xbm"] = "男" } else { record["xbm"] = "女" } //扩展民族 record["mzm"] = SysDictKit.MapDictKindCodeToChinese["mzm"+"_"+record["mzm"].(string)] //扩展政治面貌 record["zzmmm"] = SysDictKit.MapDictKindCodeToChinese["zzmmm"+"_"+record["zzmmm"].(string)] //扩展身份证件类型 record["sfzjlxm"] = SysDictKit.MapDictKindCodeToChinese["sfzjlxm"+"_"+record["sfzjlxm"].(string)] //扩展学历 record["xlm"] = SysDictKit.MapDictKindCodeToChinese["xlm"+"_"+record["xlm"].(string)] //扩展学位 record["xwm"] = SysDictKit.MapDictKindCodeToChinese["xwm"+"_"+record["xwm"].(string)] //扩展职称 record["zcm"] = SysDictKit.MapDictKindCodeToChinese["zcm"+"_"+record["zcm"].(string)] //扩展编制类别 record["bzlbm"] = SysDictKit.MapDictKindCodeToChinese["bzlbm"+"_"+record["bzlbm"].(string)] //扩展学段 record["stage_name"] = SysDictKit.MapStageIdToName[record["stage_id"].(string)] //扩展学科 record["subject_name"] = SysDictKit.MapSubjectIdToName[record["subject_id"].(string)] //岗位 record["gwzym"] = SysDictKit.MapDictKindCodeToChinese["gwzym"+"_"+record["gwzym"].(string)] //联系电话 record["lxdh"] = record["lxdh"].(string) //邮箱 record["dzxx"] = record["dzxx"].(string) } //填充 var colNames = []string{"org_name", "xm", "xbm", "csrq", "mzm", "zzmmm", "sfzjlxm", "sfzjh", "xlm", "xwm", "zcm", "bzlbm", "stage_name", "subject_name", "lxdh"} for i := range list { for j := range colNames { cName, _ := excelize.ColumnNumberToName(j + 1) cName = cName + strconv.Itoa(i+2+ExcelUtil.HiddenRows) _ = f.SetCellValue(SheetName, cName, list[i][colNames[j]]) } //单独填充上person_id,为了能在没有身份号的唯一标识的情况下,确定是新增还是修改 cName := "P" cName = cName + strconv.Itoa(i+2+ExcelUtil.HiddenRows) _ = f.SetCellValue(SheetName, cName, list[i]["person_id"]) } } // 根据指定路径保存文件 if err := f.SaveAs(targetPath); err != nil { println(err.Error()) } } //导入本校教师信息 func ImportTeacherInfoExcel(excelPath string, bureauId string, actionPersonId string, actionIp string) (bool, string, error) { //判断文件是不是存在 if !FileUtil.PathExists(excelPath) { return false, "03", nil //03:文件没有找到 } //模板是不是系统提供的 var templateSuccess = true //excel级别检查 var excelSuccess = true //临时表级别检查 var mysqlSuccess = true //新增记录个数 var insertCount = 0 //修改记录个数 var updateCount = 0 //批次号 var batchId = CommonUtil.GetUUID() //配置文件,用于校验读入的表格是不是系统规定好的格式 jsonTemplate := "teacher.json" var s1 = ExcelUtil.ReadJson(jsonTemplate, ExcelUtil.ImportFlag) //此单位下的哪些部门名称 MapOrgName, _ := getOrgNameMap(bureauId) //1、对模板的合法性进行检查 templateSuccess = ExcelUtil.IsValidTemplate(excelPath, s1) if !templateSuccess { return false, "01", nil //01:不是系统提供的模板,无法完成导入! } //2、对excel的合法性进行检查 excelSuccess = checkExcel(excelPath, s1, MapOrgName) //将excel文件读取到mysql的临时数据表中 _ = readToTable(excelPath, s1, MapOrgName, bureauId, batchId) //3、对数据库中的人员身份证号进行检查 mysqlSuccess = checkTempTable(excelPath, s1, batchId, bureauId) //两个有一个不成功,则提示 if !excelSuccess || !mysqlSuccess { return false, "02", nil //02:在excel检测中,发现问题,请检查后重新上传! } //4、获取所有单位的一些属性,用于一会维护人员信息时使用 var bureauModel models.TBaseOrganization _, _ = db.Where("org_id=?", bureauId).Get(&bureauModel) //5、新增 insertCount, _, _ = insertTeacher(batchId, actionPersonId, actionIp) //6、修改 updateCount, _, _ = updateTeacherImport(batchId, actionPersonId, actionIp) return true, "插入" + CommonUtil.ConvertIntToString(insertCount) + "条记录,更新" + CommonUtil.ConvertIntToString(updateCount) + "条记录!", nil } /**********************************以下为辅助函数*************************************************************************/ /** 功能:将excel的内容读入到数据库的临时表中 作者:黄海 时间:2020-06-18 */ func readToTable(excelPath string, s1 ExcelUtil.TemplateStruct, MapOrgName map[string]string, bureauId string, batchId string) error { var ms = make([]models.TBaseTeacherImportExcel, 0) f, _ := excelize.OpenFile(excelPath) rows, _ := f.GetRows(s1.Title) for i, row := range rows { //放过第一行 if i < ExcelUtil.HiddenRows+1 { continue } //如果连续三个格为空,则不记入预导入行 if len(row) == 0 { break } if row[0] == "" && row[1] == "" && row[2] == "" { break } //导入到临时表中 var m models.TBaseTeacherImportExcel //主键 m.Id = CommonUtil.GetUUID() //部门 m.OrgName = row[0] //姓名 m.Xm = row[1] //性别 if row[2] == "男" { m.Xbm = "1" } else { m.Xbm = "2" } //出生日期 m.Csrq = DateUtil.ConvertDate(row[3]) //民族 m.Mzm = SysDictKit.MapDictKindChineseToCode["mzm_"+row[4]] //政治面貌 m.Zzmmm = SysDictKit.MapDictKindChineseToCode["zzmmm_"+row[5]] //身份证件类型 m.Sfzjlxm = SysDictKit.MapDictKindChineseToCode["sfzjlxm_"+row[6]] //身份证件号 m.Sfzjh = CommonUtil.CompressStr(row[7]) //学历 m.Xlm = SysDictKit.MapDictKindChineseToCode["xlm_"+row[8]] //学位 m.Xwm = SysDictKit.MapDictKindChineseToCode["xwm_"+row[9]] //职称 m.Zcm = SysDictKit.MapDictKindChineseToCode["zcm_"+row[10]] //编制 m.Bzlbm = SysDictKit.MapDictKindChineseToCode["bzlbm_"+row[11]] //学段 m.StageId = SysDictKit.MapStageNameToId[row[12]] //学科 m.SubjectId = SysDictKit.MapSubjectNameToId[row[13]] //部门名称 m.OrgName = row[0] //部门ID if len(m.OrgName) == 0 { m.OrgId = bureauId //默认是放到单位根目录下的 } else { m.OrgId = MapOrgName[m.OrgName] } //联系电话 m.Lxdh = row[14] //人员ID if len(row) == 16 { m.PersonId = row[15] } else { m.PersonId = "" } //批次号 m.BatchId = batchId //第几行的数据 m.RowNumber = int32(i + 1) //添加到数组中 ms = append(ms, m) } _, err := db.Insert(ms) return err } /** 功能:在临时表中检查身份证号的合法性,本次上传的身份证号,不能存在于系统中的其它单位 作者:黄海 时间:2020-06-18 */ func checkTempTable(excelPath string, s1 ExcelUtil.TemplateStruct, batchId string, bureauId string) bool { //打开excel文件 f, _ := excelize.OpenFile(excelPath) var success = true /****************************************************************************/ //是否存在本次导入的身份证号与其它单位的已有身份证号相同,这样的不让导入,用蓝色标识出来 sql := `select t1.sfzjh,t2.row_number from t_base_teacher as t1 inner join t_base_teacher_import_excel as t2 on t1.sfzjh=t2.sfzjh inner join t_base_teacher_org as t3 on t1.person_id=t3.person_id and t3.b_use=1 and t3.is_main=1 where t2.batch_id=? and t3.bureau_id<>? and t1.sfzjh<>''` listIdCardTeacher, err := db.SQL(sql, batchId, bureauId).Query().List() if err != nil { LogUtil.Error(Const.DataBaseActionError, "在查询教师的身份证号重复时发生严重错误!") return false } //存在教师身份证号检查重复 for i := range listIdCardTeacher { rowNumber := listIdCardTeacher[i]["row_number"].(int64) cell := "H" + CommonUtil.ConvertInt64ToString(rowNumber) style, _ := f.GetCellStyle(s1.Title, Const.YellowCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) //设计二级检查失败 success = false } /****************************************************************************/ //检查学生的身份证号重复 sql = `select t1.sfzjh,t2.row_number from t_base_student as t1 inner join t_base_teacher_import_excel as t2 on t1.sfzjh=t2.sfzjh where t2.batch_id=? and t1.bureau_id<>? and t1.sfzjh<>''` listIdCardStudent, err := db.SQL(sql, batchId, bureauId).Query().List() if err != nil { LogUtil.Error(Const.DataBaseActionError, "在查询学生的身份证号重复时发生严重错误!") return false } //存在学生身份证号检查重复 for i := range listIdCardStudent { rowNumber := listIdCardStudent[i]["row_number"].(int64) cell := "H" + CommonUtil.ConvertInt64ToString(rowNumber) style, _ := f.GetCellStyle(s1.Title, Const.YellowCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) //设计二级检查失败 success = false } /****************************************************************************/ //查出与数据库中重复的非空手机号 sql = `select t1.sfzjh,t1.lxdh from t_base_teacher as t1 inner join t_base_teacher_import_excel as t2 on t1.lxdh=t2.lxdh where t2.batch_id=? and t2.lxdh<>''` listJoinMobileNumber, _ := db.SQL(sql, batchId).Query().List() //转成map,方便快速查询 var _map = make(map[string]string) for i := range listJoinMobileNumber { _map[listJoinMobileNumber[i]["lxdh"].(string)] = listJoinMobileNumber[i]["sfzjh"].(string) } //读取本次导入的所有手机号不为空的数据 sql = `select sfzjh,lxdh,row_number from t_base_teacher_import_excel where batch_id=? and lxdh<>''` listThisBatchNotEmptyMobileNumber, _ := db.SQL(sql, batchId).Query().List() //遍历每一行数据,看看与系统现有数据的是不是存在冲突 for i := range listThisBatchNotEmptyMobileNumber { if _, ok := _map[listThisBatchNotEmptyMobileNumber[i]["lxdh"].(string)]; ok { //身份证号一致 if listThisBatchNotEmptyMobileNumber[i]["sfzjh"].(string) != _map[listThisBatchNotEmptyMobileNumber[i]["lxdh"].(string)] { //不一致 rowNumber := listThisBatchNotEmptyMobileNumber[i]["row_number"].(int64) cell := "O" + CommonUtil.ConvertInt64ToString(rowNumber) style, _ := f.GetCellStyle(s1.Title, Const.YellowCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) //设计二级检查失败 success = false } } } // 根据指定路径保存文件(不管是不是通过,都保存一次) if err := f.SaveAs(excelPath); err != nil { println(err.Error()) } return success } /** 功能:检查excel,1是检查是不是系统提供的模板,2是检查是不是存在EXCEL级别的错误 作者:黄海 时间:2020-06-18 */ func checkExcel(excelPath string, s1 ExcelUtil.TemplateStruct, MapOrgName map[string]string) bool { //打开指定的文件 f, err := excelize.OpenFile(excelPath) if err != nil { LogUtil.Error(Const.IoActionError, "文件丢失:"+excelPath) return false } // excel级别检查的结果 var firstSuccess = true //身份证的map var _idCardMap = make(map[string][]int) //手机号的map var _mobileMap = make(map[string][]int) //遍历所有数据 rows, _ := f.GetRows(s1.Title) for i, row := range rows { //放过表头 if i < ExcelUtil.HiddenRows+1 { continue } //如果连续三个格为空,则不记入预导入行 if len(row) == 0 { break } if row[0] == "" && row[1] == "" && row[2] == "" { break } //真实显示的字段,不要把名称管理器的内容遍历出来 for j := 0; j < len(s1.Cols); j++ { //(1)必填写项目+值域检查 var pass = true //(0)部门 if j == 0 { //是不是在单位已存在的部门列表中,不允许手动输入 if _, ok := MapOrgName[row[j]]; !ok { //如果未输入,也是可以的,理解为放到根目录下 if row[j] != "" { pass = false } } } //(1)姓名 if j == 1 { if row[j] == "" { pass = false } } //(2)性别 if j == 2 { if row[j] != "男" && row[j] != "女" { pass = false } } //(3)出生日期 if j == 3 { //是不是合法出生日期 if !DateUtil.CheckDateStr(row[j]) { pass = false } } //(4)民族 if j == 4 { if _, ok := SysDictKit.MapDictKindChineseToCode["mzm_"+row[j]]; !ok { pass = false } } //(5)政治面貌 if j == 5 { if _, ok := SysDictKit.MapDictKindChineseToCode["zzmmm_"+row[j]]; !ok { pass = false } } //(6)身份证件类型 if j == 6 { if _, ok := SysDictKit.MapDictKindChineseToCode["sfzjlxm_"+row[j]]; !ok { pass = false } if row[j] == "" { pass = true } } //(7)身份证号 if j == 7 { if row[j-1] == "居民身份证" && row[j] != "" && !CommonUtil.IsIdCard(CommonUtil.CompressStr(row[j])) { pass = false } if len(row[j]) > 0 { _idCardMap[CommonUtil.CompressStr(row[j])] = append(_idCardMap[CommonUtil.CompressStr(row[j])], i+1) } } //(8)学历 if j == 8 { if _, ok := SysDictKit.MapDictKindChineseToCode["xlm_"+row[j]]; !ok { pass = false } } //(9)学位 if j == 9 { if _, ok := SysDictKit.MapDictKindChineseToCode["xwm_"+row[j]]; !ok { pass = false } } //(10)职称 if j == 10 { if _, ok := SysDictKit.MapDictKindChineseToCode["zcm_"+row[j]]; !ok { pass = false } } //(11)编制 if j == 11 { if _, ok := SysDictKit.MapDictKindChineseToCode["bzlbm_"+row[j]]; !ok { pass = false } } //(12)任课学段 if j == 12 { if _, ok := SysDictKit.MapStageNameToId[row[j]]; !ok { pass = false } } //(13)任课学科 if j == 13 { if _, ok := SysDictKit.MapStageSubjectNameExist[row[j-1]+"_"+row[j]]; !ok { pass = false } } //(14)联系电话 if j == 14 { if row[j] != "" { _mobileMap[row[j]] = append(_mobileMap[row[j]], i+1) } } //标红 cName, _ := excelize.ColumnNumberToName(j + 1) cell := cName + CommonUtil.ConvertIntToString(i+1) if !pass { //红色 style, _ := f.GetCellStyle(s1.Title, Const.RedCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) firstSuccess = false } else { style, _ := f.GetCellStyle(s1.Title, Const.WhiteCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) } } } //判断身份证号是不是在本EXCEL中存在重复,如果存在,需要进行标识 for _, rowArray := range _idCardMap { //重复 if len(rowArray) > 1 { for i := range rowArray { cell := "H" + CommonUtil.ConvertIntToString(rowArray[i]) //重复 style, _ := f.GetCellStyle(s1.Title, Const.BlueCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) } firstSuccess = false } } //判断联系电话是不是在本EXCEL中存在重复,如果存在,需要进行标识 for _, rowArray := range _mobileMap { //重复 if len(rowArray) > 1 { for i := range rowArray { cell := "O" + CommonUtil.ConvertIntToString(rowArray[i]) //重复 style, _ := f.GetCellStyle(s1.Title, Const.BlueCell) _ = f.SetCellStyle(s1.Title, cell, cell, style) } firstSuccess = false } } // 根据指定路径保存文件(不管是不是通过,都保存一次) if err := f.SaveAs(excelPath); err != nil { println(err.Error()) } return firstSuccess } /** 功能:插入教师 */ func insertTeacher(batchId string, actionPersonId string, actionIp string) (int, string, error) { //2、新增人员 teacherImportExcelArray := make([]models.TBaseTeacherImportExcel, 0) teacherArray := make([]models.TBaseTeacher, 0) _ = db.Where("batch_id=? and length(person_id)=0", batchId).Find(&teacherImportExcelArray) for i := range teacherImportExcelArray { r1 := teacherImportExcelArray[i] var model models.TBaseTeacher //身份 model.IdentityId = 2 //人员编号 model.PersonId = CommonUtil.GetUUID() //导入即可用 model.BUse = 1 //身份证号 model.Sfzjh = r1.Sfzjh //身份证件类型 model.Sfzjlxm = r1.Sfzjlxm //编制 model.Bzlbm = r1.Bzlbm //从教年月 model.Cjny = DateUtil.ConvertDate("1900-01-01") //根据身份证号,提取男女,出生日期 isValid, birthday, xbm := IdCardUtil.GetIdCardNoInfo(r1.Sfzjh) if isValid { model.Csrq = DateUtil.ConvertDate(birthday) model.Xbm = xbm } else { model.Csrq = r1.Csrq model.Xbm = r1.Xbm } //学段 model.StageId = r1.StageId //学科 model.SubjectId = r1.SubjectId //民族 model.Mzm = r1.Mzm //学历 model.Xlm = r1.Xlm //姓名 model.Xm = r1.Xm //曾用名 model.Cym = model.Xm //姓名拼音 model.Xmpy = PinYinUtil.PinYin(model.Xm) //学位码 model.Xwm = r1.Xwm //职称 model.Zcm = r1.Zcm //政治面貌 model.Zzmmm = r1.Zzmmm //岗位 model.Gwzym = r1.Gwzym //联系电话 model.Lxdh = r1.Lxdh //邮箱 model.Dzxx = r1.Dzxx //状态 model.StateId = 1 //添加到数组中 teacherArray = append(teacherArray, model) //保存人员所在的部门信息 _, _, _, _ = AddTeacherOrgInfo([]string{model.PersonId}, r1.OrgId, 1, 1) } //批量插入 if len(teacherArray) > 0 { _, err := db.Insert(&teacherArray) if err != nil { return 0, Const.DataBaseActionError, err } //记录日志 ActionLog(teacherArray, Const.ActionInsert, actionPersonId, actionIp) //产生登录名 accountArray := SysLoginpersonService.GenerateLoginAccount(2, int64(len(teacherImportExcelArray))) var loginpersonModels = make([]models.TSysLoginperson, 0) for i := range teacherArray { //调用dao model := new(models.TSysLoginperson) model.Id = CommonUtil.GetUUID() model.LoginName = accountArray[i].LoginName model.Pwd = accountArray[i].Pwd model.OriginalPwd = accountArray[i].OriginalPwd model.IdentityId = 2 model.PersonId = teacherArray[i].PersonId model.PersonName = teacherArray[i].Xm model.BUse = 1 loginpersonModels = append(loginpersonModels, *model) } //批量插入 if len(loginpersonModels) > 0 { _, err = db.Insert(&loginpersonModels) if err != nil { return 0, Const.DataBaseActionError, err } } return len(teacherArray), "保存成功", nil } return 0, "没有记录需要进行保存", nil } /** 功能:更新导入的教师 */ func updateTeacherImport(batchId string, actionPersonId string, actionIp string) (int, string, error) { //开始 teacherImportExcelArray := make([]models.TBaseTeacherImportExcel, 0) teacherArray := make([]models.TBaseTeacher, 0) _ = db.Where("batch_id=? and length(person_id)=36", batchId).Find(&teacherImportExcelArray) //准备更新的数据 for i := range teacherImportExcelArray { r1 := teacherImportExcelArray[i] var model models.TBaseTeacher //身份 model.IdentityId = 2 //人员编号 model.PersonId = r1.PersonId //导入即可用 model.BUse = 1 //身份证号 model.Sfzjh = r1.Sfzjh //身份证件类型 model.Sfzjlxm = r1.Sfzjlxm //编制 model.Bzlbm = r1.Bzlbm //从教年月 model.Cjny = DateUtil.ConvertDate("1999-09-01") //出生日期与性别 if model.Sfzjlxm == "1" { //根据身份证号,提取男女,出生日期 isValid, birthday, xbm := IdCardUtil.GetIdCardNoInfo(r1.Sfzjh) if isValid { model.Csrq = DateUtil.ConvertDate(birthday) model.Xbm = xbm } else { model.Csrq = r1.Csrq model.Xbm = r1.Xbm } } else { model.Csrq = r1.Csrq model.Xbm = r1.Xbm } //排序号 //model.SortId = 1 //排序号就不修改了,防止人为修改对了,这样导入再修改回去 //学段 model.StageId = r1.StageId //学科 model.SubjectId = r1.SubjectId //学历 model.Xlm = r1.Xlm //姓名 model.Xm = r1.Xm //曾用名 model.Cym = model.Xm //姓名拼音 model.Xmpy = PinYinUtil.PinYin(model.Xm) //学位码 model.Xwm = r1.Xwm //职称 model.Zcm = r1.Zcm //民族 model.Mzm = r1.Mzm //政治面貌 model.Zzmmm = r1.Zzmmm //岗位 model.Gwzym = r1.Gwzym //联系电话 model.Lxdh = r1.Lxdh //邮箱 model.Dzxx = r1.Dzxx //状态 model.StateId = 1 //添加到数组中 teacherArray = append(teacherArray, model) //保存人员所在的部门信息 _, _, _, _ = AddTeacherOrgInfo([]string{model.PersonId}, r1.OrgId, 1, 1) } //批量更新 if len(teacherArray) > 0 { //声明事务 session := db.NewSession() defer func() { err := session.Close() if err != nil { fmt.Println(err.Error()) } }() _ = session.Begin() for k := range teacherArray { _, err := session.Where("person_id=?", teacherArray[k].PersonId). Cols("b_use", "sfzjh", "sfzjlxm", "bzlbm", "cjny", "xbm", "csrq", "stage_id", "subject_id", "xlm", "xm", "cym", "xmpy", "xwm", "zcm", "mzm", "zzmmm", "gwzym", "lxdh", "dzxx", "state_id").Update(teacherArray[k]) if err != nil { _ = session.Rollback() return 0, Const.DataBaseActionError, err } } //事务提交 err := session.Commit() if err != nil { return 0, Const.DataBaseActionError, err } //删除缓存 var teacherIds = make([]string, 0) for i := range teacherArray { key := SqlKit.GetBean("t_base_teacher").RedisPrefix + teacherArray[i].PersonId RedisUtil.DEL(key) teacherIds = append(teacherIds, teacherArray[i].PersonId) } //记录日志 ms, _ := GetByIds(teacherIds) ActionLog(ms, Const.ActionUpdate, actionPersonId, actionIp) return len(teacherArray), "保存成功", nil } return 0, "没有记录需要保存", nil } /** 功能:获取指定单位下部门的名称集合MAP 作者:黄海 时间:2020-06-18 */ func getOrgNameMap(bureauId string) (map[string]string, error) { //1、此单位下的哪些部门名称 sql := `select org_name,org_id from t_base_organization where bureau_id=? and b_use=1` listOrgName, err := db.SQL(sql, bureauId).Query().List() if err != nil { return nil, err } //转为map,一会方便用于填充部门号 var MapOrgName = make(map[string]string) for i := range listOrgName { MapOrgName[listOrgName[i]["org_name"].(string)] = listOrgName[i]["org_id"].(string) } return MapOrgName, nil } /** 功能:将人员追加到某个部门下,支持批量操作 作者:黄海 时间:2020-08-05 */ func AddTeacherOrgInfo(personIds []string, orgId string, isMain int32, fromSortId int32) (bool, string, string, error) { //(1)获取单位ID list := SqlKit.QueryByIds([]string{orgId}, "t_base_organization") if len(list) == 0 { return false, "", "没有找到指定的部门编号!", nil } bureauId := list[0]["bureau_id"].(string) //(2)获取单位对应的省码,市码,县区码,主校ID _, ProvinceCode, CityCode, DistrictCode, mainSchoolId, err := BaseOrganizationDao.GetBureauAdministrativeDivision(bureauId) if err != nil { return false, "", "在查找单位的行政区划关系时出错!", nil } //(3)删除旧的 _ = DeleteTeacherOrgInfo(personIds, orgId) //(4)如果isMain==1,还需要清除原来这些人员的主部门,准备插入新的 if isMain == 1 { disableMainOrg(personIds) } //(5)插入新的 for i := range personIds { var model models.TBaseTeacherOrg model.Id = CommonUtil.GetUUID() model.PersonId = personIds[i] model.BureauId = bureauId model.OrgId = orgId model.BUse = 1 model.ProvinceCode = ProvinceCode model.CityCode = CityCode model.DistrictCode = DistrictCode model.MainSchoolId = mainSchoolId model.SortId = fromSortId model.IsMain = isMain _, err := db.Insert(model) if err != nil { return false, "", "插入人员部门关系表时失败!", err } fromSortId++ } return true, bureauId, "保存成功!", nil } /** 功能:将人员从某个部门下删除,支持批量操作 作者:黄海 时间:2020-08-05 */ func DeleteTeacherOrgInfo(personIds []string, orgId string) error { //主部门是不能删除的,主部门只能随着人员删除而删除 //批量删除教师在此部门的信息 var myBuilder = builder.Dialect(builder.MYSQL).Update(builder.Eq{"b_use": -2}). From("t_base_teacher_org").Where(builder.Eq{"b_use": 1, "org_id": orgId}.And(builder.In("person_id", personIds))) sql, _ := myBuilder.ToBoundSQL() _, err := db.SQL(sql).Execute() return err } /** 功能:将人员从全部部门下删除,支持批量操作 作者:黄海 时间:2020-08-05 */ func DeleteTeacherOrgInfoAll(personIds []string) error { //主部门是不能删除的,主部门只能随着人员删除而删除 //批量删除教师在此部门的信息 var myBuilder = builder.Dialect(builder.MYSQL).Update(builder.Eq{"b_use": -2}). From("t_base_teacher_org").Where(builder.Eq{"b_use": 1}.And(builder.In("person_id", personIds))) sql, _ := myBuilder.ToBoundSQL() _, err := db.SQL(sql).Execute() return err } /** 功能:修改指定人员在指定部门下的排序号 作者:黄海 时间:2020-08-05 */ func UpdateSortId(personId string, sortId int32) { sql := `update t_base_teacher_org set sort_id=? where person_id=?` _, _ = db.SQL(sql, sortId, personId).Execute() } /** 功能:将指定人员的主部门信息禁用 作者:黄海 时间:2020-08-05 */ func disableMainOrg(personIds []string) { for i := range personIds { sql := `update t_base_teacher_org set b_use=-2 where person_id=? and is_main=1` _, _ = db.SQL(sql, personIds[i]).Execute() } } /** 功能:获取指定人员的部门名称 作者:黄海 时间:2020-08-12 */ func GetPersonOrgName(personId string) (string, error) { sql := `select group_concat(org_name) as org_name from t_base_organization where org_id in ( select org_id from t_base_teacher_org where person_id=? and b_use=1 order by is_main desc);` list, err := db.SQL(sql, personId).Query().List() if err != nil { return "操作异常", err } if len(list) == 0 { return "没有找到此人员", nil } if list[0]["org_name"] == nil { return "未找到部门信息", nil } else { return list[0]["org_name"].(string), nil } } /** 功能:将指定的人员,保存到指定的单位下,存储多个职务 作者:黄海 时间:2020-08-20 */ func AddTeacherPosition(personIds []string, bureauId string, PositionIds []string) (bool, string, error) { //两重循环进行保存 for i := range personIds { for j := range PositionIds { model := new(models.TBaseTeacherPosition) model.Id = CommonUtil.GetUUID() model.PersonId = personIds[i] model.BureauId = bureauId model.PositionId = PositionIds[j] model.BUse = 1 //插入基本表 _, err := db.Insert(model) if err != nil { return false, "保存人员职务信息出错!", err } } } return true, "保存成功!", nil } /** 功能:删除人员在指定单位下的职务 作者:黄海 时间:2020-08-20 */ func DeleteTeacherPosition(personIds []string, bureauId string) (bool, error) { for i := range personIds { sql := `update t_base_teacher_position set b_use=-2 where person_id=? and bureau_id=?` _, err := db.SQL(sql, personIds[i], bureauId).Execute() if err != nil { return false, err } } return true, nil } /** 功能:删除人员在指定单位下的职务(所有的职务) 作者:黄海 时间:2020-08-20 */ func DeleteTeacherAllPosition(personIds []string) (bool, error) { for i := range personIds { sql := `update t_base_teacher_position set b_use=-2 where person_id=?` _, err := db.SQL(sql, personIds[i]).Execute() if err != nil { return false, err } } return true, nil } /** 功能:获取指定人员在指定单位下有哪些职务 作者:黄海 时间:2020-08-20 */ func GetPositionInfoByPersonIdAndBureauId(personId string, bureauId string) ([]string, error) { sql := `select position_id from t_base_teacher_position where person_id=? and bureau_id=? and b_use=1` list, err := db.SQL(sql, personId, bureauId).Query().List() if err != nil { return nil, err } res := make([]string, len(list)) for i := range list { res[i] = list[i]["position_id"].(string) } return res, nil } //设置教师多单位 func SettingTeacherMultipleBureau(in *BaseTeacherProto.SettingMultipleBureauArg) (bool, string, error) { var fromSortId = int32(GetMaxSortId(in.OrgId)) + 1 _, _, message, err := AddTeacherOrgInfo([]string{in.PersonId}, in.OrgId, 0, fromSortId) if err != nil { return false, message, err } return true, "调置成功!", nil } //根据教职工ID获取该教职工所在多单位列表 func PageTeacherMultipleBureau(in *BaseTeacherProto.PageMultipleBureauArg) ([]map[string]interface{}, int32, error) { var myBuilder = builder.Dialect(builder.MYSQL).Select("t1.id,t1.person_id,t4.xm,t1.org_id,t2.org_name,t1.bureau_id,t3.org_name as bureau_name,t1.is_main"). From("t_base_teacher_org as t1"). InnerJoin("t_base_organization as t2", "t1.org_id=t2.org_id"). InnerJoin("t_base_organization as t3", "t1.bureau_id=t3.org_id"). InnerJoin("t_base_teacher as t4", "t1.person_id=t4.person_id"). Where(builder.Eq{"t1.person_id": in.PersonId}).And(builder.Eq{"t1.b_use": 1}) sql, err := myBuilder.ToBoundSQL() if err != nil { return nil, 0, err } list, err := db.SQL(sql).Query().List() if err != nil { return nil, 0, err } return list, int32(len(list)), nil } //获取指定人员所在单位的行政区划列表 func GetPersonAllBureauXZQH(personId string) ([]map[string]interface{}, int32, error) { sql := `select bureau_id,province_code,city_code,district_code from t_base_teacher_org where person_id=?` list, err := db.SQL(sql, personId).Query().List() return list, int32(len(list)), err } //设置主单位 func SettingMainOrg(in *BaseTeacherProto.SettingMainOrgArg) (bool, string, error) { //将旧的设置为删除状态 sql := `update t_base_teacher_org set is_main=0 where person_id=? and b_use=1` _, _ = db.SQL(sql, in.PersonId).Execute() //将新的ID设置为主单位状态 sql = `update t_base_teacher_org set is_main=1,b_use=1 where id=?` _, _ = db.SQL(sql, in.Id).Execute() return true, "设置成功!", nil } //教师的调转 func TeacherTransfer(personId string, orgId string) (bool, string, error) { //1、因为只有唯一个单位+部门的人员才能进行调转,所以直接找到此关系,禁用即可 sql := `update t_base_teacher_org set b_use=-2 where person_id=? and b_use=1` _, _ = db.SQL(sql, personId).Execute() //2、插入新的关系 fromSortId := getOrgMaxSortId(orgId) _, _, _, _ = AddTeacherOrgInfo([]string{personId}, orgId, 1, fromSortId) return true, "保存成功", nil }