utils.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package main
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/base64"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "strings"
  10. "time"
  11. )
  12. func strToDateTime(str string) time.Time {
  13. dt, err := time.Parse("2006-01-02 15:04:05", str)
  14. if err == nil {
  15. return dt
  16. } else {
  17. panic(any(err))
  18. }
  19. }
  20. func strToDate(str string) time.Time {
  21. date, err := time.Parse("2006-01-02", str)
  22. if err == nil {
  23. return date
  24. } else {
  25. panic(any(err))
  26. }
  27. }
  28. func strToTime(str string) time.Time {
  29. timeStr := str
  30. if timeStr == "" {
  31. timeStr = "00:00"
  32. }
  33. tm, err := time.Parse("15:04", timeStr)
  34. if err == nil {
  35. return tm
  36. } else {
  37. panic(any(err))
  38. }
  39. }
  40. func dateTimeToStr(time time.Time) string {
  41. return time.Format("2006-01-02 15:04:05")
  42. }
  43. func dateToStr(time time.Time) string {
  44. return time.Format("2006-01-02")
  45. }
  46. func timeToStr(time time.Time) string {
  47. return time.Format("15:04")
  48. }
  49. func dateTimeToTime(datetime time.Time) time.Time {
  50. return strToTime(timeToStr(datetime))
  51. }
  52. func dateTimeToDate(datetime time.Time) time.Time {
  53. return strToDate(dateToStr(datetime))
  54. }
  55. func NewUUId() string {
  56. b := make([]byte, 16)
  57. _, err := rand.Read(b)
  58. if err != nil {
  59. panic(any(err))
  60. }
  61. return fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
  62. }
  63. func readBody(resp *http.Response) []byte {
  64. defer resp.Body.Close()
  65. contentLength := resp.ContentLength
  66. if contentLength == -1 {
  67. bodyData, err := io.ReadAll(resp.Body)
  68. if err == nil {
  69. return bodyData
  70. } else {
  71. panic(any(err))
  72. }
  73. } else {
  74. buffer := new(bytes.Buffer)
  75. for contentLength > 0 {
  76. size, err := buffer.ReadFrom(resp.Body)
  77. if err == nil {
  78. contentLength -= size
  79. } else {
  80. break
  81. }
  82. }
  83. bodyData := buffer.Bytes()
  84. return bodyData
  85. }
  86. }
  87. func calcPerformanceHours(rules AttendanceRules, data AttendanceData) float64 {
  88. if data.State == 出差 {
  89. return 8
  90. }
  91. if data.State == 缺卡 {
  92. return 0
  93. }
  94. if data.State == 休息 {
  95. return 0
  96. }
  97. if data.State == 请假 {
  98. if (data.StartTime.Hour() == 0 && data.StartTime.Minute() == 0) || (data.EndTime.Hour() == 0 && data.EndTime.Minute() == 0) {
  99. return 0
  100. }
  101. }
  102. start := data.StartTime
  103. if data.EndTime.Before(start) {
  104. return 0
  105. }
  106. hours := data.EndTime.Sub(start).Hours()
  107. if hours > 100 {
  108. Logger.log(WarningLevel, "Calc hours error, it larger than 100")
  109. }
  110. if start.Hour() < 12 {
  111. hours -= 1
  112. }
  113. overEndMinutes := data.EndTime.Sub(rules.End).Minutes()
  114. if overEndMinutes > 30 {
  115. hours -= 0.5
  116. }
  117. if hours < 0 {
  118. return 0
  119. }
  120. return hours
  121. }
  122. func calcWorkingHours(day time.Time, rules AttendanceRules, data AttendanceData, isHoliday bool, holidayAdjusted bool, isNationalLegalHoliday bool) float64 {
  123. if day.Weekday() == time.Saturday || day.Weekday() == time.Sunday || isHoliday {
  124. //法定节假日来加班都不算
  125. if isHoliday && !holidayAdjusted && isNationalLegalHoliday {
  126. return 0
  127. }
  128. //节假日/周末/调班休息日计算方式
  129. if data.State == 加班 {
  130. return 0
  131. } else {
  132. //最早 7:30
  133. earliestStart := strToTime("7:30")
  134. start := data.StartTime
  135. if start.Sub(earliestStart).Minutes() < 0 {
  136. start = earliestStart
  137. }
  138. if data.EndTime.Before(start) {
  139. return 0
  140. }
  141. hours := data.EndTime.Sub(start).Hours()
  142. //12点前来的,扣掉中饭时间和晚饭时间
  143. if start.Hour() < 12 {
  144. hours -= 1.5
  145. }
  146. if hours < 7.5 {
  147. return 0
  148. }
  149. return 7.5
  150. }
  151. }
  152. if data.EndResult == "请假" {
  153. return 0
  154. }
  155. start := data.StartTime
  156. if start.Sub(rules.Start).Minutes() < 0 {
  157. start = rules.Start
  158. }
  159. if (start.Hour() > 12 && start.Hour() < 13) || (data.StartResult == "请假") {
  160. start = strToTime("13:00")
  161. }
  162. if data.EndTime.Before(start) {
  163. return 0
  164. }
  165. hours := data.EndTime.Sub(start).Hours()
  166. if hours > 100 {
  167. Logger.log(WarningLevel, "Calc hours error, it larger than 100")
  168. }
  169. //12点前来的,扣掉中饭时间
  170. if start.Hour() < 12 {
  171. hours -= 1
  172. }
  173. overEndMinutes := data.EndTime.Sub(rules.End).Minutes()
  174. if overEndMinutes > 30 {
  175. hours -= 0.5
  176. }
  177. if hours < 0 {
  178. return 0
  179. }
  180. return hours
  181. }
  182. func calcRequiredWorkingHours(day time.Time, rules AttendanceRules, data AttendanceData, isHoliday bool) float64 {
  183. if day.Weekday() == time.Saturday || day.Weekday() == time.Sunday || isHoliday {
  184. return 0
  185. }
  186. start := rules.Start
  187. if data.StartResult == "正常" {
  188. if (data.StartTime.Hour() > 12 && data.StartTime.Hour() < 13) || (data.StartTime.Hour() > 13) {
  189. start = strToTime("13:00")
  190. }
  191. }
  192. if data.StartResult == "请假" {
  193. start = strToTime("13:00")
  194. }
  195. requiredHours := rules.End.Sub(start).Hours()
  196. //12点前来的,扣掉中饭时间
  197. if start.Hour() < 12 {
  198. requiredHours -= 1
  199. }
  200. return requiredHours
  201. }
  202. func b64(str string) string {
  203. return "=?UTF-8?B?" + base64.StdEncoding.EncodeToString([]byte(str)) + "?="
  204. }
  205. func sendEmail(host string, port string, sender string, password string, receiver string, cc string, title string, content string) {
  206. receivers := make([]string, 0)
  207. temp := strings.Split(receiver, ";")
  208. for i := 0; i < len(temp); i++ {
  209. if temp[i] != "" {
  210. receivers = append(receivers, temp[i])
  211. }
  212. }
  213. toStr := strings.Join(receivers, ",")
  214. ccs := make([]string, 0)
  215. temp = strings.Split(cc, ";")
  216. for i := 0; i < len(temp); i++ {
  217. if temp[i] != "" {
  218. ccs = append(ccs, temp[i])
  219. }
  220. }
  221. var message []byte
  222. if len(ccs) == 0 {
  223. message = []byte("From: " + sender + "\r\n" +
  224. "To: " + toStr + "\r\n" +
  225. "Subject: " + b64(title) + "\r\n\r\n" +
  226. content + "\r\n")
  227. } else {
  228. ccStr := strings.Join(ccs, ",")
  229. message = []byte("From: " + sender + "\r\n" +
  230. "To: " + toStr + "\r\n" +
  231. "cc: " + ccStr + "\r\n" +
  232. "Subject: " + b64(title) + "\r\n\r\n" +
  233. content + "\r\n")
  234. }
  235. // Authentication.
  236. auth := NewLoginAuth(sender, password, host)
  237. for i := 0; i < len(ccs); i++ {
  238. receivers = append(receivers, ccs[i])
  239. }
  240. err := SendMail(host+":"+port, auth, sender, receivers, message)
  241. if err != nil {
  242. Logger.log(WarningLevel, err.Error())
  243. }
  244. }