12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133 |
- package main
- import (
- "bytes"
- "encoding/base64"
- "errors"
- "fmt"
- "strconv"
- "strings"
- "sync"
- "time"
- "github.com/xuri/excelize/v2"
- )
- var dingTalk = new(DingTalk)
- type DingTalkService struct {
- isSyncing bool
- syncLocker *sync.Mutex
- }
- func (service *DingTalkService) initialize() {
- service.isSyncing = false
- service.syncLocker = new(sync.Mutex)
- dingTalk.refreshToken()
- go func() {
- for {
- time.Sleep(time.Minute * 5)
- dingTalk.refreshToken()
- }
- }()
- }
- func getSubDepartments(dingTalk *DingTalk, parentId int, departments []Department) []Department {
- subDepartments := dingTalk.getDepartments(parentId)
- for i := 0; i < len(subDepartments); i++ {
- departments = append(departments, subDepartments[i])
- departments = getSubDepartments(dingTalk, subDepartments[i].Id, departments)
- }
- return departments
- }
- func getDepartmentEmployees(dingTalk *DingTalk, departmentId int, employees []Employee) []Employee {
- departmentEmployees := dingTalk.getEmployees(departmentId)
- for i := 0; i < len(departmentEmployees); i++ {
- employees = append(employees, departmentEmployees[i])
- }
- subDepartments := dingTalk.getDepartments(departmentId)
- for i := 0; i < len(subDepartments); i++ {
- subDepartment := subDepartments[i]
- employees = getDepartmentEmployees(dingTalk, subDepartment.Id, employees)
- }
- return employees
- }
- func (service *DingTalkService) GeteEmployeeIsLeader(authCode string) bool {
- var employeeId = dingTalk.getEmployeeIdByAuthCode(authCode)
- return dingTalk.getIsLeaderById(employeeId)
- }
- func (service *DingTalkService) GeteEmployeeNameByAuthCode(authCode string) string {
- return dingTalk.getEmployeeNameByAuthCode(authCode)
- }
- func (service *DingTalkService) GetDepartmentEmployees(departmentId int) []Employee {
- employees := make([]Employee, 0)
- return getDepartmentEmployees(dingTalk, departmentId, employees)
- }
- func (service *DingTalkService) GetDepartments(departmentId int) []Department {
- departments := make([]Department, 0)
- return getSubDepartments(dingTalk, departmentId, departments)
- }
- func (service *DingTalkService) SyncDepartmentEmployees(parentId int, syncedCount *int, employeeCount int, progressId string) {
- defer func() {
- var p = any(recover())
- if p != nil {
- errStr := fmt.Sprintln("error_") + fmt.Sprintf("%v", p)
- progressService.AddOrUpdateProgress(progressId, errStr)
- }
- }()
- employees := dingTalk.getEmployees(parentId)
- for i := 0; i < len(employees); i++ {
- employee := employees[i]
- exist := databaseManager.GetEmployeeById(employee.Id)
- if exist == nil {
- databaseManager.AddEmployee(&employee)
- } else {
- databaseManager.UpdateEmployee(&employee)
- }
- *syncedCount++
- progressValue := *syncedCount * 100 / employeeCount
- progressService.AddOrUpdateProgress(progressId, strconv.Itoa(progressValue))
- }
- departments := dingTalk.getDepartments(parentId)
- for i := 0; i < len(departments); i++ {
- department := departments[i]
- exist := databaseManager.GetDepartmentById(department.Id)
- if exist == nil {
- databaseManager.AddDepartment(&department)
- } else {
- databaseManager.UpdateDepartment(&department)
- }
- service.SyncDepartmentEmployees(department.Id, syncedCount, employeeCount, progressId)
- }
- }
- func (service *DingTalkService) SyncEmployeess2(progressId string) {
- defer func() {
- var p = any(recover())
- if p != nil {
- errStr := fmt.Sprintln("error_") + fmt.Sprintf("%v", p)
- progressService.AddOrUpdateProgress(progressId, errStr)
- if service.isSyncing {
- service.isSyncing = false
- service.syncLocker.Unlock()
- }
- }
- }()
- if service.isSyncing {
- progressService.AddOrUpdateProgress(progressId, "error_一个同步操作已经在进行中。")
- return
- }
- service.syncLocker.Lock()
- service.isSyncing = true
- dingTalk.refreshToken()
- //Create or update default department
- rootDepartment := Department{1, "VINNO", 0}
- exist := databaseManager.GetDepartmentById(rootDepartment.Id)
- if exist == nil {
- databaseManager.AddDepartment(&rootDepartment)
- } else {
- databaseManager.UpdateDepartment(&rootDepartment)
- }
- employeeCount := dingTalk.getEmployeeCount()
- syncCount := 0
- dingTalkService.SyncDepartmentEmployees(rootDepartment.Id, &syncCount, employeeCount, progressId)
- service.isSyncing = false
- service.syncLocker.Unlock()
- }
- func (service *DingTalkService) SyncEmployees(departmentId int) {
- service.syncLocker.Lock()
- if service.isSyncing {
- service.syncLocker.Unlock()
- return
- } else {
- service.isSyncing = true
- service.syncLocker.Unlock()
- }
- dingTalk.refreshToken()
- employees := service.GetDepartmentEmployees(departmentId)
- for i := 0; i < len(employees); i++ {
- employee := employees[i]
- exist := databaseManager.GetEmployeeById(employee.Id)
- if exist == nil {
- databaseManager.AddEmployee(&employee)
- } else {
- databaseManager.UpdateEmployee(&employee)
- }
- }
- service.syncLocker.Lock()
- service.isSyncing = false
- service.syncLocker.Unlock()
- }
- func (service *DingTalkService) SendTextMessage(userId string, text string) {
- dingTalk.sendTextMessage([]string{userId}, text)
- }
- func (service *DingTalkService) SendUrlMessage(userId string, title string, text string, imageUrl string, url string) {
- dingTalk.sendUrlMessage([]string{userId}, title, text, imageUrl, url)
- }
- func (service *DingTalkService) SendActionCard(userId string, title string, markdown string, singleTitle string, singleUrl string) {
- dingTalk.sendActionCard([]string{userId}, title, markdown, singleTitle, singleUrl)
- }
- type LoginService struct {
- }
- func createSession(accountId string) *Session {
- session := new(Session)
- session.sessionId = NewUUId()
- session.accountId = accountId
- session.updateTime = time.Now()
- sessionManager.RemoveSessionByAccountId(session.accountId)
- sessionManager.AddSession(session)
- return session
- }
- func (service *LoginService) Login(name string, password string) string {
- result := databaseManager.GetAdminByName(name)
- if result == nil {
- var err any = errors.New("用户名不存在。")
- panic(err)
- } else {
- if result.Password != password {
- var err any = errors.New("密码错误。")
- panic(err)
- } else {
- //强制替换session
- session := createSession(result.Id)
- return session.sessionId
- }
- }
- }
- func (service *LoginService) Logoff(sessionId string) {
- sessionManager.RemoveSessionBySessionId(sessionId)
- }
- func CheckSession(sessionId string) {
- if strings.Index(sessionId, "ViewCode") != 0 {
- session := sessionManager.GetSessionBySessionId(sessionId)
- if session == nil {
- var err any = errors.New("无效的登录信息。")
- panic(err)
- }
- }
- }
- type AdminService struct {
- }
- func (service *AdminService) Add(sessionId string, admin Admin) {
- CheckSession(sessionId)
- exist := databaseManager.GetAdminByName(admin.Name)
- if exist != nil {
- var err any = "管理员已经存在."
- panic(err)
- }
- databaseManager.AddAdmin(&admin)
- }
- func (service *AdminService) GetAdminIds(sessionId string) []string {
- CheckSession(sessionId)
- return []string{
- "14033025461181119", //邓
- "0117116430501258458", //高
- "1403411622464238794", //邢
- }
- }
- func (service *AdminService) Update(sessionId string, adminName string, adminPassword string) {
- CheckSession(sessionId)
- exist := databaseManager.GetAdminByName(adminName)
- if exist == nil {
- var err any = "管理员不存在."
- panic(err)
- }
- exist.Password = adminPassword
- databaseManager.UpdateAdminPassword(exist)
- }
- func (service *AdminService) Get(sessionId string, id string) Admin {
- CheckSession(sessionId)
- return *databaseManager.GetAdminById(id)
- }
- type DepartmentService struct {
- }
- func (service *DepartmentService) GetDepartment(sessionId string, departmentId int) Department {
- CheckSession(sessionId)
- result := databaseManager.GetDepartmentById(departmentId)
- return *result
- }
- func (service *DepartmentService) GetChildDepartments(sessionId string, departmentId int) []Department {
- CheckSession(sessionId)
- departments := make([]Department, 0)
- result := databaseManager.GetDepartmentsByParentId(departmentId)
- for i := 0; i < len(result); i++ {
- departments = append(departments, *result[i])
- }
- return departments
- }
- type EmployeeService struct {
- }
- func getEmployeesByDepartmentId(departmentId int, employees []Employee) []Employee {
- result := databaseManager.GetEmployeeManyByDepartmentId(departmentId)
- for i := 0; i < len(result); i++ {
- employees = append(employees, *result[i])
- }
- departments := databaseManager.GetDepartmentsByParentId(departmentId)
- for i := 0; i < len(departments); i++ {
- employees = getEmployeesByDepartmentId(departments[i].Id, employees)
- }
- return employees
- }
- func (service *EmployeeService) GetReviewers(sessionId string) []Employee {
- CheckSession(sessionId)
- employees := make([]Employee, 0)
- result := databaseManager.GetReviewers()
- for i := 0; i < len(result); i++ {
- employees = append(employees, *result[i])
- }
- return employees
- }
- func (service *EmployeeService) GetManyByDepartmentId(sessionId string, departmentId int) []Employee {
- CheckSession(sessionId)
- employees := make([]Employee, 0)
- employees = getEmployeesByDepartmentId(departmentId, employees)
- return employees
- }
- func (service *EmployeeService) GetLeaveQuotas(email string, leaveType int) []LeaveQuota {
- employee := databaseManager.GetEmployeeByEmail(email)
- if employee != nil {
- return dingTalk.getLeaveQuotas(employee.Id, leaveType)
- } else {
- var err any = "账号不存在。"
- panic(err)
- }
- }
- func (service *EmployeeService) UpdateEmployee(sessionId string, employee Employee) {
- CheckSession(sessionId)
- databaseManager.UpdateEmployee(&employee)
- }
- func (service *EmployeeService) GetEmployeeCount(sessionId string) int {
- CheckSession(sessionId)
- return int(databaseManager.GetEmployeeCount())
- }
- func (service *EmployeeService) GetStruggleEmployeeCount(sessionId string) int {
- CheckSession(sessionId)
- return int(databaseManager.GetStruggleEmployeeCount())
- }
- func (service *EmployeeService) UpdateEmployeeDepartment(sessionId string, employee Employee) {
- CheckSession(sessionId)
- databaseManager.UpdateEmployeeDepartment(&employee)
- }
- func (service *EmployeeService) UpdateEmployeeIsStruggle(sessionId string, employee Employee) {
- CheckSession(sessionId)
- databaseManager.UpdateEmployeeIsStruggle(&employee)
- }
- func (service *EmployeeService) UpdateEmployeeIsReviewer(sessionId string, employee Employee) {
- CheckSession(sessionId)
- databaseManager.UpdateEmployeeIsReviewer(&employee)
- }
- func (service *EmployeeService) GetByName(sessionId string, employeeName string) Employee {
- CheckSession(sessionId)
- result := databaseManager.GetEmployeeByName(employeeName)
- if result == nil {
- var err any = "账号不存在。"
- panic(err)
- }
- return *result
- }
- func (service *EmployeeService) Get(sessionId string, employeeId string) Employee {
- CheckSession(sessionId)
- result := databaseManager.GetEmployeeById(employeeId)
- if result == nil {
- var err any = "账号不存在。"
- panic(err)
- }
- return *result
- }
- func (service *EmployeeService) Delete(sessionId string, employeeId string) {
- CheckSession(sessionId)
- result := databaseManager.GetEmployeeById(employeeId)
- if result == nil {
- var err any = "账号不存在。"
- panic(err)
- }
- databaseManager.DeleteEmployee(employeeId)
- }
- type WorkingDayService struct {
- }
- func (service *WorkingDayService) Update(sessionId string, workingDayInfo WorkingDayInfo) {
- CheckSession(sessionId)
- exist := databaseManager.GetWorkingDayInfoById(workingDayInfo.Id)
- if exist == nil {
- var err any = "工作日不存在。"
- panic(err)
- }
- databaseManager.UpdateWorkingDayInfo(&workingDayInfo)
- }
- func (service *WorkingDayService) GetMany(sessionId string, employeeId string, statisticsId string) []WorkingDayInfo {
- CheckSession(sessionId)
- workingDayInfos := make([]WorkingDayInfo, 0)
- result := databaseManager.GetWorkingDayInfoMany(employeeId, statisticsId)
- for i := 0; i < len(result); i++ {
- workingDayInfos = append(workingDayInfos, *result[i])
- }
- return workingDayInfos
- }
- type WorkingDayStatisticsService struct {
- checkHistory map[string]*CheckHistory
- }
- func (service *WorkingDayStatisticsService) CheckEmployeeStatistics(email string, startStr string, endStr string) int {
- if service.checkHistory == nil {
- service.checkHistory = make(map[string]*CheckHistory)
- }
- if service.checkHistory[strings.ToLower(email)] != nil {
- now := time.Now()
- history := service.checkHistory[strings.ToLower(email)]
- if history.CheckDay.Year() == now.Year() && history.CheckDay.Month() == now.Month() && history.CheckDay.Day() == now.Day() {
- return history.TotalUnits
- }
- }
- totalUnits := 0
- employee := databaseManager.GetEmployeeByEmail(email)
- if employee == nil {
- var err any = "查询的员工不存在。"
- panic(err)
- }
- start := strToDateTime(startStr)
- end := strToDateTime(endStr)
- holidayInfos := databaseManager.GetHolidayDayInfos(time.Now().AddDate(-1, 0, 0), time.Now().AddDate(1, 0, 0))
- holidays := make(map[int64]*HolidayInfo)
- adjustDays := make(map[int64]*HolidayInfo)
- for i := 0; i < len(holidayInfos); i++ {
- holidays[holidayInfos[i].Holiday.Unix()] = holidayInfos[i]
- if holidayInfos[i].IsAdjusted {
- adjustDays[holidayInfos[i].AdjustedDay.Unix()] = holidayInfos[i]
- }
- }
- attendanceList := dingTalk.getEmployeeAttendanceDataList(employee.Id, start, end)
- statisticsId := NewUUId()
- for j := 0; j < len(attendanceList); j++ {
- attendanceData := attendanceList[j]
- day := attendanceData.Day
- workingDayInfo := new(WorkingDayInfo)
- workingDayInfo.Id = NewUUId()
- workingDayInfo.StatisticsId = statisticsId
- workingDayInfo.EmployeeId = employee.Id
- workingDayInfo.Day = day
- workingDayInfo.Start = attendanceData.StartTime
- if attendanceData.StartResult != "正常" {
- workingDayInfo.StartResult = attendanceData.StartResult
- }
- workingDayInfo.End = attendanceData.EndTime
- if attendanceData.EndResult != "正常" {
- workingDayInfo.EndResult = attendanceData.EndResult
- }
- workingDayInfo.State = attendanceData.State
- isHoliday := holidays[attendanceData.Day.Unix()] != nil
- workingDayInfo.IsHoliday = isHoliday
- if isHoliday {
- holidayInfo := holidays[attendanceData.Day.Unix()]
- if holidayInfo.IsAdjusted {
- workingDayInfo.HolidayAdjusted = true
- workingDayInfo.AdjustedDay = holidayInfo.AdjustedDay
- }
- }
- isAdjustedDay := adjustDays[attendanceData.Day.Unix()] != nil
- if isAdjustedDay {
- holidayInfo := adjustDays[attendanceData.Day.Unix()]
- day = holidayInfo.Holiday
- workingDayInfo.HolidayAdjusted = true
- workingDayInfo.AdjustedDay = holidayInfo.Holiday
- if workingDayInfo.State == 休息 {
- workingDayInfo.State = 调班
- }
- //此天是调班日,按休假的那天算
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(day, employee.AttendanceRules, attendanceData, false)
- workingDayInfo.WorkingHours = calcWorkingHours(day, employee.AttendanceRules, attendanceData, false, true, false)
- } else {
- if workingDayInfo.HolidayAdjusted {
- //此天是休息日,但是如果来按休假的那天来计算
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(workingDayInfo.AdjustedDay, employee.AttendanceRules, attendanceData, true)
- workingDayInfo.WorkingHours = calcWorkingHours(workingDayInfo.AdjustedDay, employee.AttendanceRules, attendanceData, true, true, false)
- } else {
- //此天可能休息也可能不休息,但是没有调班
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(day, employee.AttendanceRules, attendanceData, isHoliday)
- if isHoliday {
- holiday := holidays[day.Unix()]
- isNationalLegal := false
- if holiday != nil {
- isNationalLegal = holiday.IsNationalLegal
- }
- workingDayInfo.WorkingHours = calcWorkingHours(day, employee.AttendanceRules, attendanceData, true, false, isNationalLegal)
- } else {
- workingDayInfo.WorkingHours = calcWorkingHours(day, employee.AttendanceRules, attendanceData, false, false, false)
- }
- }
- }
- workingDayInfo.IsWeekend = day.Weekday() == time.Saturday || day.Weekday() == time.Sunday
- overHours := workingDayInfo.WorkingHours - workingDayInfo.RequiredWorkingHours
- if overHours < 0 {
- overHours = 0
- }
- units := int(overHours / 2.5)
- if units > 1 {
- //工作日最多1次
- if !workingDayInfo.IsWeekend && !workingDayInfo.IsHoliday {
- units = 1
- } else {
- //周末必须达标3次
- if units >= 3 {
- units = 3
- } else {
- units = 0
- }
- }
- }
- workingDayInfo.ObtainedUnits = units
- workingDayInfo.AdjustedObtainedUnits = workingDayInfo.ObtainedUnits
- databaseManager.AddWorkingDayInfo(workingDayInfo)
- totalUnits += workingDayInfo.ObtainedUnits
- }
- history := new(CheckHistory)
- history.CheckDay = time.Now()
- history.TotalUnits = totalUnits
- service.checkHistory[strings.ToLower(email)] = history
- return totalUnits
- }
- func (service *WorkingDayStatisticsService) CheckEmployeePerformanceHours(email string, startStr string, endStr string) int {
- totalHours := 0.0
- employee := databaseManager.GetEmployeeByEmail(email)
- if employee == nil {
- var err any = "查询的员工不存在。"
- panic(err)
- }
- start := strToDateTime(startStr)
- end := strToDateTime(endStr)
- attendanceList := dingTalk.getEmployeeAttendanceDataList(employee.Id, start, end)
- for j := 0; j < len(attendanceList); j++ {
- attendanceData := attendanceList[j]
- hours := calcPerformanceHours(employee.AttendanceRules, attendanceData)
- totalHours += hours
- }
- return int(totalHours / 8)
- }
- func (service *WorkingDayStatisticsService) Update(sessionId string, workingDayStatistics WorkingDayStatistics) {
- CheckSession(sessionId)
- exist := databaseManager.GetWorkingDayStatisticsById(workingDayStatistics.Id)
- if exist == nil {
- var err any = "工作统计不存在。"
- panic(err)
- }
- databaseManager.UpdateWorkingDayStatistics(&workingDayStatistics)
- }
- func (service *WorkingDayStatisticsService) UpdateComment(sessionId string, workingDayStatisticsId string, comment string) {
- CheckSession(sessionId)
- exist := databaseManager.GetWorkingDayStatisticsById(workingDayStatisticsId)
- if exist == nil {
- var err any = "工作统计不存在。"
- panic(err)
- }
- databaseManager.UpdateWorkingDayStatisticsComment(workingDayStatisticsId, comment)
- }
- func (service *WorkingDayStatisticsService) Get(sessionId string, workingDayStatisticsId string) WorkingDayStatistics {
- CheckSession(sessionId)
- result := databaseManager.GetWorkingDayStatisticsById(workingDayStatisticsId)
- return *result
- }
- func (service *WorkingDayStatisticsService) GetMany(sessionId string, workingDayStatisticsIds []string) []WorkingDayStatistics {
- CheckSession(sessionId)
- workingDayStatisticsList := make([]WorkingDayStatistics, 0)
- result := databaseManager.GetWorkingDayStatisticsByIds(workingDayStatisticsIds)
- for i := 0; i < len(result); i++ {
- workingDayStatisticsList = append(workingDayStatisticsList, *result[i])
- }
- return workingDayStatisticsList
- }
- type StatisticsTableService struct {
- }
- func createDepartmentName(departmentId int) string {
- if departmentId != 1 {
- department := databaseManager.GetDepartmentById(departmentId)
- if department != nil {
- departmentName := department.Name
- if department.ParentId != 1 {
- return createDepartmentName(department.ParentId) + "/" + departmentName
- } else {
- return departmentName
- }
- }
- }
- return ""
- }
- func (service *StatisticsTableService) Add(sessionId string, title string, startStr string, endStr string, requiredReachedCount int) {
- CheckSession(sessionId)
- exist := databaseManager.GetStatisticsTableByTitle(title)
- if exist != nil {
- var err any = "同名工作统计集合已经存在。"
- panic(err)
- }
- start := strToDateTime(startStr)
- end := strToDateTime(endStr)
- holidayInfos := databaseManager.GetHolidayDayInfos(time.Now().AddDate(-1, 0, 0), time.Now().AddDate(1, 0, 0))
- holidays := make(map[int64]*HolidayInfo)
- adjustDays := make(map[int64]*HolidayInfo)
- for i := 0; i < len(holidayInfos); i++ {
- holidays[holidayInfos[i].Holiday.Unix()] = holidayInfos[i]
- if holidayInfos[i].IsAdjusted {
- adjustDays[holidayInfos[i].AdjustedDay.Unix()] = holidayInfos[i]
- }
- }
- workingDayStatisticsIds := make([]string, 0)
- employees := databaseManager.GetStruggleEmployeeMany()
- for i := 0; i < len(employees); i++ {
- totalUnits := 0
- attendanceList := dingTalk.getEmployeeAttendanceDataList(employees[i].Id, start, end)
- statisticsId := NewUUId()
- for j := 0; j < len(attendanceList); j++ {
- attendanceData := attendanceList[j]
- day := attendanceData.Day
- workingDayInfo := new(WorkingDayInfo)
- workingDayInfo.Id = NewUUId()
- workingDayInfo.StatisticsId = statisticsId
- workingDayInfo.EmployeeId = employees[i].Id
- workingDayInfo.Day = day
- workingDayInfo.Start = attendanceData.StartTime
- if attendanceData.StartResult != "正常" {
- workingDayInfo.StartResult = attendanceData.StartResult
- }
- workingDayInfo.End = attendanceData.EndTime
- if attendanceData.EndResult != "正常" {
- workingDayInfo.EndResult = attendanceData.EndResult
- }
- workingDayInfo.State = attendanceData.State
- isHoliday := holidays[attendanceData.Day.Unix()] != nil
- workingDayInfo.IsHoliday = isHoliday
- if isHoliday {
- holidayInfo := holidays[attendanceData.Day.Unix()]
- if holidayInfo.IsAdjusted {
- workingDayInfo.HolidayAdjusted = true
- workingDayInfo.AdjustedDay = holidayInfo.AdjustedDay
- }
- }
- isAdjustedDay := adjustDays[attendanceData.Day.Unix()] != nil
- if isAdjustedDay {
- holidayInfo := adjustDays[attendanceData.Day.Unix()]
- day = holidayInfo.Holiday
- workingDayInfo.HolidayAdjusted = true
- workingDayInfo.AdjustedDay = holidayInfo.Holiday
- if workingDayInfo.State == 休息 {
- workingDayInfo.State = 调班
- }
- //此天是调班日,按休假的那天算
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(day, employees[i].AttendanceRules, attendanceData, false)
- workingDayInfo.WorkingHours = calcWorkingHours(day, employees[i].AttendanceRules, attendanceData, false, true, false)
- } else {
- if workingDayInfo.HolidayAdjusted {
- //此天是休息日,但是如果来按休假的那天来计算
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(workingDayInfo.AdjustedDay, employees[i].AttendanceRules, attendanceData, true)
- workingDayInfo.WorkingHours = calcWorkingHours(workingDayInfo.AdjustedDay, employees[i].AttendanceRules, attendanceData, true, true, false)
- } else {
- //此天可能休息也可能不休息,但是没有调班
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(day, employees[i].AttendanceRules, attendanceData, isHoliday)
- if isHoliday {
- holiday := holidays[day.Unix()]
- isNationalLegal := false
- if holiday != nil {
- isNationalLegal = holiday.IsNationalLegal
- }
- workingDayInfo.WorkingHours = calcWorkingHours(day, employees[i].AttendanceRules, attendanceData, true, false, isNationalLegal)
- } else {
- workingDayInfo.WorkingHours = calcWorkingHours(day, employees[i].AttendanceRules, attendanceData, false, false, false)
- }
- }
- }
- workingDayInfo.IsWeekend = day.Weekday() == time.Saturday || day.Weekday() == time.Sunday
- overHours := workingDayInfo.WorkingHours - workingDayInfo.RequiredWorkingHours
- if overHours < 0 {
- overHours = 0
- }
- units := int(overHours / 2.5)
- if units > 1 {
- //工作日最多1次
- if !workingDayInfo.IsWeekend && !workingDayInfo.IsHoliday {
- units = 1
- } else {
- //周末必须达标3次
- if units >= 3 {
- units = 3
- } else {
- units = 0
- }
- }
- }
- workingDayInfo.ObtainedUnits = units
- workingDayInfo.AdjustedObtainedUnits = workingDayInfo.ObtainedUnits
- databaseManager.AddWorkingDayInfo(workingDayInfo)
- totalUnits += workingDayInfo.ObtainedUnits
- }
- workingDayStatistics := new(WorkingDayStatistics)
- workingDayStatistics.Id = statisticsId
- workingDayStatistics.Employee = *employees[i]
- workingDayStatistics.DepartmentId = employees[i].DepartmentId
- workingDayStatistics.DepartmentName = createDepartmentName(employees[i].DepartmentId)
- workingDayStatistics.Start = start
- workingDayStatistics.End = end
- workingDayStatistics.RequiredReachedCount = requiredReachedCount
- workingDayStatistics.ReachedCount = totalUnits
- workingDayStatistics.AdjustedReachedCount = totalUnits
- workingDayStatistics.Adjusted = false
- workingDayStatistics.AdjustDescription = ""
- workingDayStatistics.AdjustedBy = ""
- workingDayStatistics.Comment = ""
- workingDayStatistics.Reviewer = ""
- databaseManager.AddWorkingDayStatistics(workingDayStatistics)
- workingDayStatisticsIds = append(workingDayStatisticsIds, workingDayStatistics.Id)
- }
- table := new(StatisticsTable)
- table.Id = NewUUId()
- table.Title = title
- table.RequiredReachedCount = requiredReachedCount
- table.WorkingDayStatisticsIds = workingDayStatisticsIds
- table.CreateTime = time.Now()
- databaseManager.AddStatisticsTable(table)
- }
- func (service *StatisticsTableService) Add2(sessionId string, title string, startStr string, endStr string, requiredReachedCount int, progressId string) {
- defer func() {
- var p = any(recover())
- if p != nil {
- errStr := fmt.Sprintln("error_") + fmt.Sprintf("%v", p)
- progressService.AddOrUpdateProgress(progressId, errStr)
- }
- }()
- CheckSession(sessionId)
- exist := databaseManager.GetStatisticsTableByTitle(title)
- if exist != nil {
- var err any = "同名工作统计集合已经存在。"
- panic(err)
- }
- start := strToDateTime(startStr)
- end := strToDateTime(endStr)
- holidayInfos := databaseManager.GetHolidayDayInfos(time.Now().AddDate(-1, 0, 0), time.Now().AddDate(1, 0, 0))
- holidays := make(map[int64]*HolidayInfo)
- adjustDays := make(map[int64]*HolidayInfo)
- for i := 0; i < len(holidayInfos); i++ {
- holidays[holidayInfos[i].Holiday.Unix()] = holidayInfos[i]
- if holidayInfos[i].IsAdjusted {
- adjustDays[holidayInfos[i].AdjustedDay.Unix()] = holidayInfos[i]
- }
- }
- workingDayStatisticsIds := make([]string, 0)
- employees := databaseManager.GetStruggleEmployeeMany()
- for i := 0; i < len(employees); i++ {
- totalUnits := 0
- attendanceList := dingTalk.getEmployeeAttendanceDataList(employees[i].Id, start, end)
- statisticsId := NewUUId()
- for j := 0; j < len(attendanceList); j++ {
- attendanceData := attendanceList[j]
- day := attendanceData.Day
- workingDayInfo := new(WorkingDayInfo)
- workingDayInfo.Id = NewUUId()
- workingDayInfo.StatisticsId = statisticsId
- workingDayInfo.EmployeeId = employees[i].Id
- workingDayInfo.Day = day
- workingDayInfo.Start = attendanceData.StartTime
- if attendanceData.StartResult != "正常" {
- workingDayInfo.StartResult = attendanceData.StartResult
- }
- workingDayInfo.End = attendanceData.EndTime
- if attendanceData.EndResult != "正常" {
- workingDayInfo.EndResult = attendanceData.EndResult
- }
- workingDayInfo.State = attendanceData.State
- isHoliday := holidays[attendanceData.Day.Unix()] != nil
- workingDayInfo.IsHoliday = isHoliday
- if isHoliday {
- holidayInfo := holidays[attendanceData.Day.Unix()]
- if holidayInfo.IsAdjusted {
- workingDayInfo.HolidayAdjusted = true
- workingDayInfo.AdjustedDay = holidayInfo.AdjustedDay
- }
- }
- isAdjustedDay := adjustDays[attendanceData.Day.Unix()] != nil
- if isAdjustedDay {
- holidayInfo := adjustDays[attendanceData.Day.Unix()]
- day = holidayInfo.Holiday
- workingDayInfo.HolidayAdjusted = true
- workingDayInfo.AdjustedDay = holidayInfo.Holiday
- if workingDayInfo.State == 休息 {
- workingDayInfo.State = 调班
- }
- //此天是调班日,按休假的那天算
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(day, employees[i].AttendanceRules, attendanceData, false)
- workingDayInfo.WorkingHours = calcWorkingHours(day, employees[i].AttendanceRules, attendanceData, false, true, false)
- } else {
- if workingDayInfo.HolidayAdjusted {
- //此天是休息日,但是如果来按休假的那天来计算
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(workingDayInfo.AdjustedDay, employees[i].AttendanceRules, attendanceData, true)
- workingDayInfo.WorkingHours = calcWorkingHours(workingDayInfo.AdjustedDay, employees[i].AttendanceRules, attendanceData, true, true, false)
- } else {
- //此天可能休息也可能不休息,但是没有调班
- workingDayInfo.RequiredWorkingHours = calcRequiredWorkingHours(day, employees[i].AttendanceRules, attendanceData, isHoliday)
- if isHoliday {
- holiday := holidays[day.Unix()]
- isNationalLegal := false
- if holiday != nil {
- isNationalLegal = holiday.IsNationalLegal
- }
- workingDayInfo.WorkingHours = calcWorkingHours(day, employees[i].AttendanceRules, attendanceData, true, false, isNationalLegal)
- } else {
- workingDayInfo.WorkingHours = calcWorkingHours(day, employees[i].AttendanceRules, attendanceData, false, false, false)
- }
- }
- }
- workingDayInfo.IsWeekend = day.Weekday() == time.Saturday || day.Weekday() == time.Sunday
- overHours := workingDayInfo.WorkingHours - workingDayInfo.RequiredWorkingHours
- if overHours < 0 {
- overHours = 0
- }
- units := int(overHours / 2.5)
- if units > 1 {
- //工作日最多1次
- if !workingDayInfo.IsWeekend && !workingDayInfo.IsHoliday {
- units = 1
- } else {
- //周末必须达标3次
- if units >= 3 {
- units = 3
- } else {
- units = 0
- }
- }
- }
- workingDayInfo.ObtainedUnits = units
- workingDayInfo.AdjustedObtainedUnits = workingDayInfo.ObtainedUnits
- databaseManager.AddWorkingDayInfo(workingDayInfo)
- totalUnits += workingDayInfo.ObtainedUnits
- }
- workingDayStatistics := new(WorkingDayStatistics)
- workingDayStatistics.Id = statisticsId
- workingDayStatistics.Employee = *employees[i]
- workingDayStatistics.DepartmentId = employees[i].DepartmentId
- workingDayStatistics.DepartmentName = createDepartmentName(employees[i].DepartmentId)
- workingDayStatistics.Start = start
- workingDayStatistics.End = end
- workingDayStatistics.RequiredReachedCount = requiredReachedCount
- workingDayStatistics.ReachedCount = totalUnits
- workingDayStatistics.AdjustedReachedCount = totalUnits
- workingDayStatistics.Adjusted = false
- workingDayStatistics.AdjustDescription = ""
- workingDayStatistics.AdjustedBy = ""
- workingDayStatistics.Comment = ""
- workingDayStatistics.Reviewer = ""
- databaseManager.AddWorkingDayStatistics(workingDayStatistics)
- workingDayStatisticsIds = append(workingDayStatisticsIds, workingDayStatistics.Id)
- employeeCount := len(employees)
- progressValue := (i + 1) * 100 / employeeCount
- progressService.AddOrUpdateProgress(progressId, strconv.Itoa(progressValue))
- }
- table := new(StatisticsTable)
- table.Id = NewUUId()
- table.Title = title
- table.RequiredReachedCount = requiredReachedCount
- table.WorkingDayStatisticsIds = workingDayStatisticsIds
- table.CreateTime = time.Now()
- databaseManager.AddStatisticsTable(table)
- }
- func (service *StatisticsTableService) Delete(sessionId string, statisticsTableId string) {
- CheckSession(sessionId)
- databaseManager.DeleteStatisticsTable(statisticsTableId)
- }
- func (service *StatisticsTableService) CreateAndDownloadReport(sessionId string, reportTitle string, workingDayStatisticsList []string) string {
- CheckSession(sessionId)
- f := excelize.NewFile()
- oldName := f.GetSheetName(0)
- f.SetSheetName(oldName, reportTitle)
- //写表头
- header := map[string]string{"A": "员工姓名", "B": "部门", "C": "达标次数", "D": "已调整", "E": "调整说明", "F": "备注", "G": "审核人"}
- row := 1
- style, err := f.NewStyle(`{"font":{"bold":true,"color":"#000000"}}`)
- if err == nil {
- f.SetCellStyle(reportTitle, "A1", "G1", style)
- }
- f.SetColWidth(reportTitle, "A", "A", 25)
- f.SetColWidth(reportTitle, "B", "B", 35)
- f.SetColWidth(reportTitle, "C", "D", 10)
- f.SetColWidth(reportTitle, "E", "F", 35)
- f.SetColWidth(reportTitle, "G", "G", 25)
- for k, v := range header {
- f.SetCellValue(reportTitle, k+strconv.Itoa(row), v)
- }
- row++
- for i := 0; i < len(workingDayStatisticsList); i++ {
- statistics := databaseManager.GetWorkingDayStatisticsById(workingDayStatisticsList[i])
- if statistics != nil {
- adjustedStr := "否"
- if statistics.Adjusted {
- adjustedStr = "是"
- }
- f.SetCellValue(reportTitle, "A"+strconv.Itoa(row), statistics.Employee.Name)
- f.SetCellValue(reportTitle, "B"+strconv.Itoa(row), statistics.DepartmentName)
- f.SetCellValue(reportTitle, "C"+strconv.Itoa(row), statistics.AdjustedReachedCount)
- f.SetCellValue(reportTitle, "D"+strconv.Itoa(row), adjustedStr)
- f.SetCellValue(reportTitle, "E"+strconv.Itoa(row), statistics.AdjustDescription)
- f.SetCellValue(reportTitle, "F"+strconv.Itoa(row), statistics.Comment)
- f.SetCellValue(reportTitle, "G"+strconv.Itoa(row), statistics.Reviewer)
- row++
- }
- }
- buffer := new(bytes.Buffer)
- f.Write(buffer)
- f.Close()
- encodeString := base64.StdEncoding.EncodeToString(buffer.Bytes())
- return encodeString
- }
- func (service *StatisticsTableService) GetMany(sessionId string) []StatisticsTable {
- CheckSession(sessionId)
- statisticsTables := make([]StatisticsTable, 0)
- result := databaseManager.GetStatisticsTableMany()
- for i := 0; i < len(result); i++ {
- statisticsTables = append(statisticsTables, *result[i])
- }
- return statisticsTables
- }
- type ViewCodeService struct {
- }
- func (service *ViewCodeService) SendViewCode(sessionId string, title string, receiver string, cc string, contentTemplate string, viewCode ViewCode) {
- CheckSession(sessionId)
- emailSetting := databaseManager.GetEmailSetting()
- if emailSetting == nil {
- var err any = "服务器邮件参数未配置。"
- panic(err)
- }
- //Create url
- url := "http://localhost:8088/viewstatistcs?viewCode=" + viewCode.Code
- domainSetting := databaseManager.GetDomainSetting()
- if domainSetting != nil {
- url = domainSetting.Domain + "/viewstatistcs?viewCode=" + viewCode.Code
- }
- content := contentTemplate
- content = strings.Replace(content, "{URL}", url, -1)
- content = strings.Replace(content, "{ExpiredTime}", viewCode.ExpiredTime.Format("2006-01-02"), -1)
- sendEmail(emailSetting.Host, emailSetting.Port, emailSetting.Sender, emailSetting.SenderPassword, receiver, cc, title, content)
- }
- func (service *ViewCodeService) Get(code string) ViewCode {
- result := databaseManager.GetViewCode(code)
- if result == nil {
- var err any = "统计码不存在。"
- panic(err)
- }
- return *result
- }
- func (service *ViewCodeService) Add(sessionId string, viewCode ViewCode) {
- CheckSession(sessionId)
- exist := databaseManager.GetViewCode(viewCode.Code)
- if exist != nil {
- var err any = "统计码已存在。"
- panic(err)
- }
- databaseManager.AddViewCode(&viewCode)
- }
- type EmailService struct {
- }
- func (service *EmailService) GetEmailSetting(sessionId string) EmailSetting {
- CheckSession(sessionId)
- emailSetting := databaseManager.GetEmailSetting()
- if emailSetting == nil {
- return EmailSetting{"", "", "", "", ""}
- }
- return *emailSetting
- }
- func (service *EmailService) AddOrUpdateEmailSetting(sessionId string, setting EmailSetting) {
- CheckSession(sessionId)
- emailSetting := databaseManager.GetEmailSetting()
- if emailSetting == nil {
- databaseManager.AddEmailSetting(&setting)
- } else {
- emailSetting.Host = setting.Host
- emailSetting.Port = setting.Port
- emailSetting.Sender = setting.Sender
- emailSetting.SenderPassword = setting.SenderPassword
- databaseManager.UpdateEmailSetting(emailSetting)
- }
- }
- type DomainService struct {
- }
- func (service *DomainService) GetDomainSetting(sessionId string) DomainSetting {
- CheckSession(sessionId)
- domainSetting := databaseManager.GetDomainSetting()
- if domainSetting == nil {
- return DomainSetting{"", ""}
- }
- return *domainSetting
- }
- func (service *DomainService) AddOrUpdateDomainSetting(sessionId string, setting DomainSetting) {
- CheckSession(sessionId)
- domainSetting := databaseManager.GetDomainSetting()
- if domainSetting == nil {
- databaseManager.AddDomainSetting(&setting)
- } else {
- domainSetting.Domain = setting.Domain
- databaseManager.UpdateDomainSetting(domainSetting)
- }
- }
- type MessageTemplateService struct {
- }
- func (service *MessageTemplateService) GetMessageTemplate(sessionId string, name string) MessageTemplate {
- CheckSession(sessionId)
- template := databaseManager.GetMessageTemplate(name)
- if template == nil {
- return MessageTemplate{"", "", ""}
- }
- return *template
- }
- func (service *MessageTemplateService) DeleteMessageTemplate(sessionId string, name string) {
- CheckSession(sessionId)
- template := databaseManager.GetMessageTemplate(name)
- if template == nil {
- var err any = "模板不存在。"
- panic(err)
- }
- databaseManager.DeleteMessageTemplate(template)
- }
- func (service *MessageTemplateService) AddOrUpdateGetMessageTemplate(sessionId string, template MessageTemplate) {
- CheckSession(sessionId)
- exist := databaseManager.GetMessageTemplate(template.Name)
- if exist == nil {
- databaseManager.AddMessageTemplate(&template)
- } else {
- exist.Content = template.Content
- databaseManager.UpdateMessageTemplate(exist)
- }
- }
- type HolidayService struct {
- }
- func (service *HolidayService) GetMany(sessionId string) []HolidayInfo {
- CheckSession(sessionId)
- holidays := make([]HolidayInfo, 0)
- result := databaseManager.GetHolidayDayInfos(time.Now().AddDate(-1, 0, 0), time.Now().AddDate(1, 0, 0))
- for i := 0; i < len(result); i++ {
- holidays = append(holidays, *result[i])
- }
- return holidays
- }
- func (service *HolidayService) Add(sessionId string, holiday HolidayInfo) {
- CheckSession(sessionId)
- exist := databaseManager.GetHolidayInfo(holiday.Holiday)
- if exist != nil {
- var err any = "节假日已存在。"
- panic(err)
- }
- databaseManager.AddHolidayInfo(&holiday)
- }
- func (service *HolidayService) Delete(sessionId string, holiday HolidayInfo) {
- CheckSession(sessionId)
- exist := databaseManager.GetHolidayInfo(holiday.Holiday)
- if exist == nil {
- var err any = "节假日不存在。"
- panic(err)
- }
- databaseManager.DeleteHolidayInfo(holiday.Id)
- }
- type ProgressService struct {
- progressMap map[string]string
- syncLocker *sync.Mutex
- }
- func (service *ProgressService) initialize() {
- service.syncLocker = new(sync.Mutex)
- service.progressMap = make(map[string]string)
- }
- func (service *ProgressService) AddOrUpdateProgress(progressId string, progressValue string) {
- service.syncLocker.Lock()
- service.progressMap[progressId] = progressValue
- service.syncLocker.Unlock()
- }
- func (service *ProgressService) GetProgress(progressId string) string {
- service.syncLocker.Lock()
- if value, ok := service.progressMap[progressId]; ok {
- service.syncLocker.Unlock()
- return value
- } else {
- service.syncLocker.Unlock()
- return "0"
- }
- }
- func (service *ProgressService) DeleteProgress(progressId string) {
- service.syncLocker.Lock()
- delete(service.progressMap, progressId)
- service.syncLocker.Unlock()
- }
|