|
@@ -0,0 +1,149 @@
|
|
|
+package commonApi
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "qfw/util"
|
|
|
+ "sync"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type (
|
|
|
+ holidaysManager struct {
|
|
|
+ holidayCache map[int]map[time.Time]bool
|
|
|
+ sync.Mutex
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+func (hm *holidaysManager) GetEndTime(currentDate time.Time, workDays int) (string, error) {
|
|
|
+ for workDays > 0 {
|
|
|
+ currentDate = currentDate.AddDate(0, 0, 1)
|
|
|
+ yMap := hm.getHolidaysByYear(currentDate.Year())
|
|
|
+ if yMap != nil && !yMap[currentDate] {
|
|
|
+ fmt.Println(currentDate.Format(util.Date_Short_Layout), "工作日")
|
|
|
+ workDays--
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return currentDate.Format(util.Date_Short_Layout), nil
|
|
|
+}
|
|
|
+
|
|
|
+func (hm *holidaysManager) getHolidaysByYear(year int) map[time.Time]bool {
|
|
|
+ hm.Lock()
|
|
|
+ rData := hm.holidayCache[year]
|
|
|
+ hm.Unlock()
|
|
|
+ if len(rData) > 0 {
|
|
|
+ return rData
|
|
|
+ }
|
|
|
+ newData := requestHolidayApi(year)
|
|
|
+ if len(newData) > 0 {
|
|
|
+ //hm.Lock()
|
|
|
+ //defer hm.Unlock()
|
|
|
+ hm.holidayCache[year] = newData
|
|
|
+ }
|
|
|
+ return newData
|
|
|
+}
|
|
|
+
|
|
|
+func requestHolidayApi(year int) map[time.Time]bool {
|
|
|
+ client := http.Client{}
|
|
|
+ req, _ := http.NewRequest("GET", fmt.Sprintf("https://timor.tech/api/holiday/year/%d?type=Y&week=Y", year), nil)
|
|
|
+ req.Header.Add("Accept", "application/json")
|
|
|
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36")
|
|
|
+ for i := 0; i < 5; i++ {
|
|
|
+ holidayTime := func() map[time.Time]bool {
|
|
|
+ res, err := client.Do(req)
|
|
|
+ defer res.Body.Close()
|
|
|
+ if err != nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ bytes, err := io.ReadAll(res.Body)
|
|
|
+ if err != nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ type holidayApiRes struct {
|
|
|
+ Code int `json:"code"`
|
|
|
+ Holiday map[string]struct {
|
|
|
+ Holiday bool `json:"holiday"`
|
|
|
+ Name string `json:"name"`
|
|
|
+ Wage int `json:"wage"`
|
|
|
+ Date string `json:"date"`
|
|
|
+ Rest int `json:"rest"`
|
|
|
+ } `json:"holiday"`
|
|
|
+ }
|
|
|
+ hRes := &holidayApiRes{}
|
|
|
+ err = json.Unmarshal(bytes, hRes)
|
|
|
+ if err != nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ rData := map[time.Time]bool{}
|
|
|
+ for _, s := range hRes.Holiday {
|
|
|
+ if s.Holiday {
|
|
|
+ t, err := time.Parse(util.Date_Short_Layout, s.Date)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ rData[t] = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return rData
|
|
|
+ }()
|
|
|
+ if len(holidayTime) > 0 {
|
|
|
+ return holidayTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+var hManager *holidaysManager
|
|
|
+
|
|
|
+func init() {
|
|
|
+ hManager = &holidaysManager{
|
|
|
+ holidayCache: map[int]map[time.Time]bool{},
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func RegisterCalculateWorkDayApi() {
|
|
|
+ http.HandleFunc("/api/getWorkDay", func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ mData, err := func() (interface{}, error) {
|
|
|
+ reqBytes, _ := io.ReadAll(r.Body)
|
|
|
+ if len(reqBytes) == 0 {
|
|
|
+ return nil, fmt.Errorf("参数异常")
|
|
|
+ }
|
|
|
+
|
|
|
+ type calculateWorkDay struct {
|
|
|
+ InputTime string `json:"startDay" doc:"开始时间"`
|
|
|
+ WorkDayNum int `json:"workDayNum" doc:"工作日"`
|
|
|
+ start, end time.Time
|
|
|
+ }
|
|
|
+
|
|
|
+ cwd := &calculateWorkDay{}
|
|
|
+ if err := json.Unmarshal(reqBytes, cwd); err != nil {
|
|
|
+ log.Println("反序列化异常", err)
|
|
|
+ return nil, fmt.Errorf("参数格式异常")
|
|
|
+ }
|
|
|
+
|
|
|
+ if cwd.WorkDayNum <= 0 {
|
|
|
+ return nil, fmt.Errorf("请输入正确工作日数量")
|
|
|
+ }
|
|
|
+ t, err := time.Parse(util.Date_Short_Layout, cwd.InputTime)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("开始时间格式异常")
|
|
|
+ }
|
|
|
+ return hManager.GetEndTime(t, cwd.WorkDayNum)
|
|
|
+ }()
|
|
|
+ resData := map[string]interface{}{}
|
|
|
+ if err != nil {
|
|
|
+ resData["error_msg"] = err.Error()
|
|
|
+ resData["error_code"] = -1
|
|
|
+ } else {
|
|
|
+ resData["error_code"] = 0
|
|
|
+ resData["data"] = mData
|
|
|
+ }
|
|
|
+ resBytes, _ := json.Marshal(resData)
|
|
|
+ w.Write(resBytes)
|
|
|
+ })
|
|
|
+}
|