package customerApp import ( "appPlatform/middleware/grocerystore" "appPlatform/models/customerForm" "appPlatform/models/modelshr" "appPlatform/models/teamlog" "appPlatform/overall" "appPlatform/overall/publicmethod" "encoding/csv" "encoding/json" "fmt" "mime/multipart" "path" "strconv" "strings" "time" "github.com/360EntSecGroup-Skylar/excelize" "github.com/gin-gonic/gin" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" ) var RongXinArrOrg []modelshr.AdministrativeOrganization /* * @ 作者: 秦东 @ 时间: 2025-08-18 14:16:25 @ 功能: 下载排班模板 */ func (a *ApiMethod) DownLoadDutyPage(c *gin.Context) { orgId := c.Query("orgid") //哪个行政组织 types := c.Query("types") //什么类型 timeVal := c.Query("timeval") //时间 if orgId == "undefined" || orgId == "" || orgId == "" { fmt.Printf("%v--%v--%v", orgId, types, timeVal) return } // var orgInfo modelshr.AdministrativeOrganization // err := orgInfo.GetCont(map[string]interface{}{"`id`": orgId}) } /* * @ 作者: 秦东 @ 时间: 2025-08-19 08:09:34 @ 功能: 上传文档并解析(Redis) */ func (a *ApiMethod) UploadFilesRedis(c *gin.Context) { orgId := c.Request.FormValue("orgId") types := c.Request.FormValue("types") dateTime := c.Request.FormValue("dateTime") //附加参数 fileInfo, fileHeader, fileErr := c.Request.FormFile("file") //上传的文件 if fileErr != nil { publicmethod.Result(200, fileErr, c) return } defer fileInfo.Close() // fmt.Printf("argVal-dateTime-->%T--->%v\n\n\n", orgId, orgId) // fmt.Printf("argVal-types-->%T--->%v\n\n\n", types, types) // fmt.Printf("argVal-dateTime-->%T--->%v\n\n\n", dateTime, dateTime) if orgId == "" { publicmethod.Result(200, fileErr, c, "未知行政组织!数据不可导入!") return } typesInt := 1 if types != "" { typesVal, _ := strconv.Atoi(types) if typesVal > 0 { typesInt = typesVal } } currTime := time.Now().Unix() if dateTime != "" { currTimes, _ := strconv.ParseInt(dateTime, 10, 64) if currTimes > 0 { if publicmethod.GetIntLength(currTimes) >= 13 { currTime = currTimes / 1000 } else { currTime = currTimes } } } encoding := c.Request.FormValue("encoding") if encoding == "" { encoding = "utf-8" // 默认使用UTF-8 } // fmt.Printf("argVal-currTime-->%T--->%v\n\n\n", currTime, currTime) // fmt.Printf("argVal-encoding-->%T--->%v\n\n\n", encoding, encoding) tageExt := path.Ext(fileHeader.Filename) //获取文件后缀 fileType := publicmethod.JudgeUpFileType(tageExt) if fileType != 5 && fileType != 6 { publicmethod.Result(200, fileType, c, "您上传的不是电子表格!请上传正确的文件!") return } orgIdInt, _ := strconv.ParseInt(orgId, 10, 64) var orgCont []string overall.CONSTANT_DB_HR.Model(&modelshr.AdministrativeOrganization{}).Select("`name`").Where("`superior` = ?", orgId).Find(&orgCont) if len(orgCont) < 1 { publicmethod.Result(200, orgCont, c, "未知行政组织!数据不可导入") return } redisListKey := fmt.Sprintf("ExcelCsvImport:List:u_%v_%v", orgId, publicmethod.GetUUid(1)) //获取当前列表的Key sendData := publicmethod.MapOut[string]() sendData["redisKey"] = redisListKey isTrue := true callBackMsg := "" switch fileType { case 5: xlsx, err := excelize.OpenReader(fileInfo) //读取文件内容 if err != nil { publicmethod.Result(2, xlsx, c, tageExt) return } rows := xlsx.GetRows(xlsx.GetSheetName(xlsx.GetActiveSheetIndex())) fmt.Printf("row--->%T\n\n\n", rows) if len(rows) < 1 { publicmethod.Result(200, err, c, "你没有写入数据!") return } sendData["total"], callBackMsg, isTrue = ParseExcelCsvData(rows, orgCont, typesInt, orgIdInt, currTime, redisListKey) case 6: // xlsx := csv.NewReader() records, err := ReadCSVFromMultipartFileWithEncoding(fileInfo, "gbk") if err != nil || len(records) < 1 { publicmethod.Result(200, err, c, "你没有写入数据!") return } sendData["total"], callBackMsg, isTrue = ParseExcelCsvData(records, orgCont, typesInt, orgIdInt, currTime, redisListKey) default: } if !isTrue { publicmethod.Result(200, sendData, c, callBackMsg) return } publicmethod.Result(0, sendData, c) } // File读取CSV数据 func ReadCSVFromMultipartFileWithEncoding(file multipart.File, encoding string) ([][]string, error) { var reader *csv.Reader // 根据指定的编码创建相应的reader switch encoding { case "gbk", "gb2312": // 创建GBK解码器 gbkReader := transform.NewReader(file, simplifiedchinese.GBK.NewDecoder()) reader = csv.NewReader(gbkReader) case "utf-8", "utf8": fallthrough default: // 默认使用UTF-8 reader = csv.NewReader(file) } // 设置CSV选项 reader.Comma = ',' // 设置分隔符 reader.LazyQuotes = true // 允许非标准的引号 // 读取所有记录 records, err := reader.ReadAll() if err != nil { return nil, fmt.Errorf("读取CSV失败: %w", err) } return records, nil } /* * @ 作者: 秦东 @ 时间: 2025-08-19 11:44:51 @ 功能: 解析数据 #row 多数的表格数据 #orgList 行政组织列表 #types 1:按月;非1:按天 #orgIdInt 公司 #redisKey redis唯一识别符 */ func ParseExcelCsvData(row [][]string, orgList []string, types int, orgIdInt, currTime int64, redisKey string) (totalNum int, msg string, isOk bool) { redisClient := grocerystore.RunRedis(overall.CONSTANT_REDIS4) redisClient.SetRedisTime(86400) year, _ := strconv.Atoi(publicmethod.UnixTimeToDay(currTime, 16)) month, _ := strconv.Atoi(publicmethod.UnixTimeToDay(currTime, 17)) day, _ := strconv.Atoi(publicmethod.UnixTimeToDay(currTime, 18)) for i, v := range row { // for vi, vv := range v { // fmt.Printf("%v-%v:%v\n\n", i, vi, vv) // if i == 1 && vi == 0 { // if types == 1 { // var timeVal publicmethod.DateTimeTotimes // timeVal.BaisStrToTime(vv) // if timeVal.AllTime <= 0 { // msg = "书写的导入日期不正确;请按照规定书写日期。" // return // } // } else { // var timeVal publicmethod.DateTimeTotimes // timeVal.BaisStrToTime(vv) // if timeVal.AllTime <= 0 { // msg = "书写的导入日期不正确;请按照规定书写日期。" // return // } // } // } // if orgIdInt == 309 { // if i == 2 && vi == 0 { // if vv != "公司带班" { // msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" // return // } // } // if i == 3 && vi == 0 { // if vv != "公司值班" { // msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" // return // } // } // } else { // if i == 2 && vi == 0 { // if vv != "公司带班" { // msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" // return // } // } // } // } if i == 1 { if v[0] == "" { msg = "书写的导入日期不正确;请按照规定书写日期。" return } else { if types == 1 { var timeVal publicmethod.DateTimeTotimes timeVal.BaisStrToTimeExcel(v[0]) if timeVal.AllTime <= 0 { msg = "书写的导入日期不正确;请按照规定书写日期。" return } timeYear, _ := strconv.Atoi(timeVal.Years) timeMonth, _ := strconv.Atoi(timeVal.Months) if year != timeYear || month != timeMonth { // msg = "导入日期,与模版设定日期不符!请检查!。" msg = fmt.Sprintf("%v-%v-%v导入日期,与模版设定日期不符!请检查!%v-%v", year, month, day, timeYear, timeMonth) return } } else { var timeVal publicmethod.DateTimeTotimes timeVal.BaisStrToTimeExcel(v[0]) if timeVal.AllTime <= 0 { msg = "书写的导入日期不正确;请按照规定书写日期。" return } timeYear, _ := strconv.Atoi(timeVal.Years) timeMonth, _ := strconv.Atoi(timeVal.Months) timeDay, _ := strconv.Atoi(timeVal.Days) if year != timeYear || month != timeMonth || day != timeDay { msg = fmt.Sprintf("%v-%v-%v导入日期,与模版设定日期不符!请检查!%v-%v-%v", year, month, day, timeYear, timeMonth, timeDay) return } } } // fmt.Printf("v---0---->%v\n\n", v[0]) } if orgIdInt == 309 { if i == 2 { if v[0] == "" { msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" return } else { if v[0] != "公司带班" { msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" return } } } if i == 3 { if v[0] == "" { msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" return } else { if v[0] != "公司值班" { msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" return } } } } else { if i == 2 { if v[0] == "" { msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" return } else { if v[0] != "公司带班" { msg = "您的导入的数据所使用得模版不符合当前公司导入模版格式。请先下载相应的模版后,重新编辑数据,再上传!" return } } } } if i > 1 { jsonStr, _ := json.Marshal(v) redisClient.Lpush(redisKey, jsonStr) totalNum++ } } if totalNum > 0 { isOk = true } return } /* * @ 作者: 秦东 @ 时间: 2025-08-19 15:34:42 @ 功能: 将排班信息解写入数据库 */ func (a *ApiMethod) AnalysisDutyData(c *gin.Context) { var requestData AlaDutyInfo err := c.ShouldBindJSON(&requestData) if err != nil { publicmethod.Result(100, err, c) return } if requestData.OrgId == 0 { publicmethod.Result(200, err, c, "未知行政组织!非法数据据") return } if requestData.Types == 0 { requestData.Types = 1 } currTime := time.Now().Unix() if requestData.DateTime != 0 { if publicmethod.GetIntLength(requestData.DateTime) >= 13 { currTime = requestData.DateTime / 1000 } else { currTime = requestData.DateTime } } if requestData.RedisKey == "" { publicmethod.Result(200, err, c, "数据获取识别!没有找到数据! ") return } redisClient := grocerystore.RunRedis(overall.CONSTANT_REDIS4) orgDutyList, err := redisClient.Llen(requestData.RedisKey) //获取列表总长度 if err != nil { publicmethod.Result(200, err, c, "数据获取识别!没有找到数据! ") return } redisVal, err := redisClient.Lindex(requestData.RedisKey, requestData.Number) if err != nil { publicmethod.Result(200, err, c, "数据获取识别!没有找到数据! ") return } var redisDataMap []string err = json.Unmarshal([]byte(redisVal), &redisDataMap) if err != nil { publicmethod.Result(200, err, c, "数据格式不正取!") return } var msgStr string var orgCompunt modelshr.AdministrativeOrganization orgCompunt.GetCont(map[string]interface{}{"`id`": requestData.OrgId}, "`name`") year, _ := strconv.Atoi(publicmethod.UnixTimeToDay(currTime, 16)) month, _ := strconv.Atoi(publicmethod.UnixTimeToDay(currTime, 17)) day, _ := strconv.Atoi(publicmethod.UnixTimeToDay(currTime, 18)) if requestData.Types == 1 { if len(redisDataMap) >= 1 { if redisDataMap[0] != "" { orgKey, orgTitle, orgErr := CallBackOrgIdName(requestData.OrgId, redisDataMap[0]) if orgErr != nil { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", orgCompunt.Name, "未知行政组织", time.Now().Unix()) } else { for i, v := range redisDataMap { fmt.Printf("读取的回写数据:\ni:%v------------------>%v\n", i, v) if i > 0 { if v != "" { msgStr = SaveDutyData(orgCompunt.Name, orgTitle, orgKey, year, month, i, v) } else { msgStr = fmt.Sprintf("%v[%v]数据处理完成!--->%v", orgCompunt.Name, orgTitle, time.Now().Unix()) } } } } } else { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", orgCompunt.Name, "未知行政组织", time.Now().Unix()) } } } else { if len(redisDataMap) >= 2 { if redisDataMap[0] != "" { orgKey, orgTitle, orgErr := CallBackOrgIdName(requestData.OrgId, redisDataMap[0]) if orgErr != nil { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", orgCompunt.Name, "未知行政组织", time.Now().Unix()) } else { if redisDataMap[1] != "" { msgStr = SaveDutyData(orgCompunt.Name, orgTitle, orgKey, year, month, day, redisDataMap[1]) } else { msgStr = fmt.Sprintf("%v[%v]数据处理完成!--->%v", orgCompunt.Name, orgTitle, time.Now().Unix()) } } } else { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", orgCompunt.Name, "未知行政组织", time.Now().Unix()) } } else { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", orgCompunt.Name, redisDataMap[0], time.Now().Unix()) } } sendData := publicmethod.MapOut[string]() sendData["currTime"] = currTime sendData["orgDutyList"] = orgDutyList sendData["msg"] = msgStr publicmethod.Result(0, sendData, c) } /* * @ 作者: 秦东 @ 时间: 2025-08-19 16:28:20 @ 功能: 编辑排班数据 */ func SaveDutyData(compurtNam, orgNam string, orgid int64, year, month, day int, userStr string) (msgStr string) { var comDutyLog teamlog.Companylog err := comDutyLog.GetCont(map[string]interface{}{"`orgid`": orgid, "`years`": year, "`months`": month, "`days`": day}) fmt.Printf("编辑排班数据:\n%v---->%v---->%v---->%v---->%v\n\n\n", orgid, year, month, day, userStr) var userKeyAllDayAry []string var userKeyBaiTianAry []string var userKeyNightAry []string var userKeyMorningAry []string var userKeyAfternoonAry []string holiday := 2 userAry := strings.Split(userStr, ",") if len(userStr) > 0 { //获取排班人员 // fmt.Printf("编辑排班数据:\n%v---->%v---->%v---->%v---->%v\n\n\n", orgid, year, month, day, userAry) for _, v := range userAry { userInfoStr := publicmethod.MatchBracket(v, "(", ")") fmt.Printf("编辑排班数据110:\n%v\n\n\n", userInfoStr) if userInfoStr != "" { userAttr := strings.Split(userInfoStr, "*") if len(userAttr) > 0 { var usInfo modelshr.PersonArchives usInfo.GetCont(map[string]interface{}{"`number`": userAttr[0]}) if len(userAttr) >= 2 { //(B:白天;Y:夜间;S:上午;X:下午;Z:值班)不填默认为值班(Z) if usInfo.Key != 0 { switch userAttr[1] { case "B": holiday = 1 userKeyBaiTianAry = append(userKeyBaiTianAry, strconv.FormatInt(usInfo.Key, 10)) case "Y": holiday = 1 userKeyNightAry = append(userKeyNightAry, strconv.FormatInt(usInfo.Key, 10)) case "S": userKeyMorningAry = append(userKeyMorningAry, strconv.FormatInt(usInfo.Key, 10)) case "X": userKeyAfternoonAry = append(userKeyAfternoonAry, strconv.FormatInt(usInfo.Key, 10)) default: userKeyAllDayAry = append(userKeyAllDayAry, strconv.FormatInt(usInfo.Key, 10)) } } } else { if usInfo.Key != 0 { userKeyAllDayAry = append(userKeyAllDayAry, strconv.FormatInt(usInfo.Key, 10)) } } } } // fmt.Printf("编辑排班数据val:\n%v---->%v---->%v---->%v---->%v\n\n\n", orgid, year, month, day, v) } } if err == nil && comDutyLog.ID != 0 { //存在,进行修改 saveEitd := publicmethod.MapOut[string]() saveEitd["`holiday`"] = holiday saveEitd["allDay"] = strings.Join(userKeyAllDayAry, ",") saveEitd["baiTian"] = strings.Join(userKeyBaiTianAry, ",") saveEitd["night"] = strings.Join(userKeyNightAry, ",") saveEitd["morning"] = strings.Join(userKeyMorningAry, ",") saveEitd["afternoon"] = strings.Join(userKeyAfternoonAry, ",") saveEitd["saveTime"] = time.Now().Unix() var newDutyCont teamlog.Companylog err = newDutyCont.EiteCont(map[string]interface{}{"`id`": comDutyLog.ID}, saveEitd) if err == nil { msgStr = fmt.Sprintf("%v[%v]数据处理完成!--->%v", compurtNam, orgNam, time.Now().Unix()) } else { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", compurtNam, orgNam, time.Now().Unix()) } } else { //不存在!进行新增 var saveConter teamlog.Companylog saveConter.Orgid = orgid // 行政组织ID saveConter.RunTime = time.Now().Unix() // 执行时间 saveConter.Years = year // 年 saveConter.Months = month // 月 saveConter.Days = day // 日 saveConter.Holiday = holiday // 假日(1:是;2:否) saveConter.AllDay = strings.Join(userKeyAllDayAry, ",") // 全天值班人员 saveConter.BaiTian = strings.Join(userKeyBaiTianAry, ",") // 白天值班人员 saveConter.Night = strings.Join(userKeyNightAry, ",") // 夜晚值班人员 saveConter.Morning = strings.Join(userKeyMorningAry, ",") // 夜晚值班人员 saveConter.Afternoon = strings.Join(userKeyAfternoonAry, ",") // 夜晚值班人员 saveConter.SaveTime = time.Now().Unix() // 编辑时间 err = overall.CONSTANT_DB_TeamsLog.Create(&saveConter).Error if err == nil { msgStr = fmt.Sprintf("%v[%v]数据处理完成!--->%v", compurtNam, orgNam, time.Now().Unix()) } else { msgStr = fmt.Sprintf("%v[%v]数据处理失败!--->%v", compurtNam, orgNam, time.Now().Unix()) } } return } /* * @ 作者: 秦东 @ 时间: 2025-08-19 16:17:31 @ 功能: 返回当前行政组织的id与名称 */ func CallBackOrgIdName(superiorId int64, orgName string) (orgId int64, orgTitle string, err error) { switch orgName { case "公司带班": orgId = superiorId * 10000 orgTitle = orgName case "公司值班": orgId = superiorId*10000 + 1 orgTitle = orgName default: var orgBan modelshr.AdministrativeOrganization err = orgBan.GetCont(map[string]interface{}{"`superior`": superiorId, "`name`": orgName}, "`id`") if err != nil { return } orgId = orgBan.Id orgTitle = orgName } return } // 判断有无换班申请 func ShiftChange(userCode string, userKey int64, year, month, day int) (userInfo modelshr.ManCont, isTrue bool) { monthStr := "01" if month > 0 && month <= 12 { if month < 10 { monthStr = fmt.Sprintf("0%v", month) } else { monthStr = strconv.Itoa(month) } } dayStr := "01" if day > 0 && day <= 12 { if day < 10 { dayStr = fmt.Sprintf("0%v", day) } else { dayStr = strconv.Itoa(day) } } fullDayStr := fmt.Sprintf("%v-%v-%v", year, monthStr, dayStr) startTime, endTime := publicmethod.OenDayStartOrEndTime(fullDayStr, 1) kaishi, _ := publicmethod.StringToInt64(startTime) beginTime := kaishi * 1000 jieshu, _ := publicmethod.StringToInt64(endTime) lastTime := jieshu * 1000 //被调换人到当前日期 var diaoban []customerForm.SCApplication overall.CONSTANT_DB_CustomerForm.Model(&customerForm.SCApplication{}).Where("FIND_IN_SET(?,`diao4huan4ren2`) AND `dang1zhi2ri4qi141995810` BETWEEN ? AND ?", userCode, beginTime, lastTime).Find(&diaoban) if len(diaoban) > 0 { for _, v := range diaoban { var taskInfo customerForm.RunFlowTask taskInfo.GetCont(map[string]interface{}{"`masters_key`": v.MastersKey}, "status") if taskInfo.Status == 4 { isTrue = true userInfo.GetCont(map[string]interface{}{"`number`": userCode}) break } } } //申请人到调换日期 var shenQing []customerForm.SCApplication overall.CONSTANT_DB_CustomerForm.Model(&customerForm.SCApplication{}).Where("`creater` = ? AND `diao4huan4ri4qi1` BETWEEN ? AND ?", userKey, beginTime, lastTime).Find(&shenQing) if len(shenQing) > 0 { for _, v := range shenQing { var taskInfo customerForm.RunFlowTask taskInfo.GetCont(map[string]interface{}{"`masters_key`": v.MastersKey}, "status") if taskInfo.Status == 4 { isTrue = true userInfo.GetCont(map[string]interface{}{"`key`": userKey}) break } } } return }