diff --git a/cmd/enterprise.go b/cmd/enterprise.go index 526df9a..6f54c35 100644 --- a/cmd/enterprise.go +++ b/cmd/enterprise.go @@ -3,12 +3,13 @@ package main import ( "enterprise/common/config" "enterprise/common/global" + "enterprise/common/model" "enterprise/server" "enterprise/worker" "time" ) -func main1() { +func main() { config.LoadServerConfig() global.InitGlobal() @@ -21,12 +22,12 @@ func main1() { } } -func main() { +func main22() { config.LoadServerConfig() global.InitGlobal() //cfg := config.GetConfig() for i := 0; i < 10; i++ { - new(worker.Approval).SyncCheckinMonth(time.Now().AddDate(0, 0-i, 0).Format("200601")) + new(worker.Approval).Sync(time.Now().AddDate(0, 0-i, 0).Format("200601"), model.ApprovalTypeVacation) } } diff --git a/common/dao/approval_vacation.go b/common/dao/approval_vacation.go new file mode 100644 index 0000000..c6c5f15 --- /dev/null +++ b/common/dao/approval_vacation.go @@ -0,0 +1,66 @@ +package dao + +import ( + "enterprise/common/model" + "gorm.io/gorm" + "time" +) + +type ApprovalVacationDao struct { +} + +func NewApprovalVacationDao() *ApprovalVacationDao { + return &ApprovalVacationDao{} +} + +func (d *ApprovalVacationDao) TableName() string { + return "approval_vacation" +} + +func (d *ApprovalVacationDao) Create(o *model.ApprovalVacation) (int64, error) { + o.CreateTime = time.Now().Unix() + res := GetDB().Table(d.TableName()).Create(o) + return o.Id, res.Error +} + +func (d *ApprovalVacationDao) Update(o *model.ApprovalVacation) error { + o.UpdateTime = time.Now().Unix() + tx := GetDB().Table(d.TableName()) + res := tx.Save(o) + return res.Error +} + +func (d *ApprovalVacationDao) Delete(id int64) error { + res := GetDB().Table(d.TableName()).Delete(&model.ApprovalVacation{}, id) + return res.Error +} + +func (d *ApprovalVacationDao) Get(id int64) (*model.ApprovalVacation, error) { + var u model.ApprovalVacation + tx := GetDB().Table(d.TableName()) + tx = tx.Where("id = ?", id) + res := tx.First(&u) + if res.Error == gorm.ErrRecordNotFound { + return nil, nil + } + + if res.Error != nil { + return nil, res.Error + } + return &u, nil +} + +func (d *ApprovalVacationDao) GetBySpNo(spNo string) (*model.ApprovalVacation, error) { + var u model.ApprovalVacation + tx := GetDB().Table(d.TableName()) + tx = tx.Where("sp_no = ?", spNo) + res := tx.First(&u) + if res.Error == gorm.ErrRecordNotFound { + return nil, nil + } + + if res.Error != nil { + return nil, res.Error + } + return &u, nil +} diff --git a/common/model/approval_checkin.go b/common/model/approval_checkin.go index 5c2d866..8322043 100644 --- a/common/model/approval_checkin.go +++ b/common/model/approval_checkin.go @@ -1,10 +1,9 @@ package model -var () - type ApprovalCheckin struct { Id int64 Username string + Month string SpNo string CheckinType string CheckinDate string diff --git a/common/model/approval_refund.go b/common/model/approval_refund.go index d255c01..a0a668e 100644 --- a/common/model/approval_refund.go +++ b/common/model/approval_refund.go @@ -3,11 +3,15 @@ package model var ( ApprovalRefundStatusCreated = 1 ApprovalRefundStatusPayed = 2 + ApprovalTypeRefund = "refund" + ApprovalTypeCheckin = "checkin" + ApprovalTypeVacation = "vacation" ) type ApprovalRefund struct { Id int64 Username string + Month string SpNo string RefundType string RefundDate string diff --git a/common/model/approval_vacation.go b/common/model/approval_vacation.go new file mode 100644 index 0000000..7c139ff --- /dev/null +++ b/common/model/approval_vacation.go @@ -0,0 +1,19 @@ +package model + +var () + +type ApprovalVacation struct { + Id int64 + Username string + Month string + SpNo string + VacationType string + VacationDate string + VacationStartTime string + VacationEndTime string + VacationDuration float64 + VacationRemark string + ApplyTime string + CreateTime int64 + UpdateTime int64 +} diff --git a/common/weixin/qyweixin_approve.go b/common/weixin/qyweixin_approve.go index 6afcf69..2dc98ce 100644 --- a/common/weixin/qyweixin_approve.go +++ b/common/weixin/qyweixin_approve.go @@ -3,10 +3,13 @@ package weixin import ( "encoding/json" butil "enterprise/base/util" + "enterprise/common/model" "fmt" log "github.com/sirupsen/logrus" "github.com/smbrave/goutil" "github.com/spf13/cast" + "strings" + "time" ) type Applyer struct { @@ -104,14 +107,12 @@ func (d *ApproveDetail) GetValue(title string) string { value = content.Value.NewMoney } else if content.Control == "File" { value = content.Value.Files[0].FileId - } else if content.Control == "Vacation" { //请假 : 请假类型,请假时长 + } else if content.Control == "Vacation" { //请假 : 请假类型,开始时间,结束时间,请假时长 tp := content.Value.Vacation.Selector.Options[0].Value[0].Text - duration := cast.ToString(content.Value.Vacation.Attendance.DateRange.NewDuration) - value = tp + "," + duration + value = tp + "," + cast.ToString(content.Value.Vacation.Attendance.DateRange.NewBegin) + + "," + cast.ToString(content.Value.Vacation.Attendance.DateRange.NewEnd) + + "," + cast.ToString(content.Value.Vacation.Attendance.DateRange.NewDuration) } else if content.Control == "PunchCorrection" { //补卡:日期,时间,状态 - if d.SpNo == "202312010001" { - fmt.Println(goutil.EncodeJSON(d.ApplyData)) - } mp := cast.ToStringMap(content.Value.PunchCorrection) ddate := cast.ToString(mp["daymonthyear"]) dtime := cast.ToString(mp["time"]) @@ -133,6 +134,53 @@ func (d *ApproveDetail) GetUserid() string { return d.Applyer.Userid } +func (d *ApproveDetail) ToVacation() *model.ApprovalVacation { + vacation := new(model.ApprovalVacation) + vacation.SpNo = d.SpNo + vacation.Username = d.GetUserid() + vacation.ApplyTime = goutil.TimeToDateTime(d.ApplyTime) + + fields := strings.SplitN(d.GetValue("请假类型"), ",", 4) + dTime := cast.ToInt64(fields[1]) + vacation.VacationType = fields[0] + vacation.VacationDate = goutil.TimeToDate(dTime) + vacation.VacationStartTime = goutil.TimeToDateTime(cast.ToInt64(fields[1])) + vacation.VacationEndTime = goutil.TimeToDateTime(cast.ToInt64(fields[2])) + vacation.VacationDuration = float64(cast.ToInt64(fields[3])) / float64(3600*8) + vacation.VacationRemark = d.GetValue("请假事由") + vacation.Month = time.Unix(dTime, 0).Format("200601") + return vacation +} + +func (d *ApproveDetail) ToRefund() *model.ApprovalRefund { + refund := new(model.ApprovalRefund) + refund.SpNo = d.SpNo + refund.Username = d.GetUserid() + refund.ApplyTime = goutil.TimeToDateTime(d.ApplyTime) + refund.Status = model.ApprovalRefundStatusCreated + refund.RefundType = d.GetValue("报销类型") + refundTime := cast.ToInt64(d.GetValue("发生时间")) + refund.Month = time.Unix(refundTime, 0).Format("200601") + refund.RefundDate = goutil.TimeToDateTime(refundTime) + refund.RefundAmount = cast.ToFloat64(d.GetValue("报销费用")) + refund.RefundRemark = d.GetValue("报销说明") + return refund +} + +func (d *ApproveDetail) ToCheckin() *model.ApprovalCheckin { + ac := new(model.ApprovalCheckin) + value := strings.SplitN(d.GetValue("补卡"), ",", 3) + ac.SpNo = d.SpNo + ac.Username = d.GetUserid() + ac.ApplyTime = goutil.TimeToDateTime(d.ApplyTime) + ac.CheckinRemark = d.GetValue("补卡事由") + ac.CheckinDate = goutil.TimeToDate(cast.ToInt64(value[0])) + ac.Month = time.Unix(cast.ToInt64(value[0]), 0).Format("200601") + ac.CheckinTime = goutil.TimeToDateTime(cast.ToInt64(value[1])) + ac.CheckinType = value[2] + return ac +} + func NewQyWeixinApprove(corpId, secret, agent string) *QyWeixinApprove { return &QyWeixinApprove{ QyWeixin: QyWeixin{ diff --git a/server/service/qyweixin_approve.go b/server/service/qyweixin_approve.go index d78a4df..208ecda 100644 --- a/server/service/qyweixin_approve.go +++ b/server/service/qyweixin_approve.go @@ -11,9 +11,7 @@ import ( "fmt" log "github.com/sirupsen/logrus" "github.com/smbrave/goutil" - "github.com/spf13/cast" "strings" - "time" ) var ( @@ -56,59 +54,87 @@ func (a *Approve) handle(msg *message.MixMessage) { func (a *Approve) handleApprovalChange(msg *message.MixMessage) { spStatus := msg.ApprovalInfo.SpStatus spNo := msg.ApprovalInfo.SpNo - spName := msg.ApprovalInfo.SpName + templateId := msg.ApprovalInfo.TemplateId if spStatus != SpStatusPassed { return } - if spName == "费用报销" { - a.handleRefund(spNo) - } else if spName == "请假" { - a.handleHoliday(spNo) - } else if spName == "打卡补卡" { - a.handleCheckin(spNo) - } -} - -func (a *Approve) handleHoliday(spNo string) { - -} - -func (a *Approve) handleCheckin(spNo string) { - -} -func (a *Approve) handleRefund(spNo string) { detail, err := a.approveClient.GetDetail(spNo) if err != nil { log.Errorf("get spn detail error :%s", err.Error()) return } + if templateId == model.ApprovalTypeRefund { + a.handleRefund(detail) + } else if templateId == model.ApprovalTypeVacation { + a.handleVacation(detail) + } else if templateId == model.ApprovalTypeCheckin { + a.handleCheckin(detail) + } +} - refund, err := dao.NewApprovalRefundDao().GetBySpNo(spNo) +func (a *Approve) handleVacation(detail *weixin.ApproveDetail) { + newData := detail.ToVacation() + dbDao := dao.NewApprovalVacationDao() + + old, err := dbDao.GetBySpNo(detail.SpNo) if err != nil { log.Errorf("db error :%s", err.Error()) return } - - isUpdate := true - if refund == nil { - refund = new(model.ApprovalRefund) - refund.SpNo = detail.SpNo - isUpdate = false - } - refund.Username = detail.Applyer.Userid - refund.ApplyTime = goutil.TimeToDateTime(detail.ApplyTime) - refund.Status = model.ApprovalRefundStatusCreated - refund.RefundType = detail.GetValue("报销类型") - refund.RefundDate = time.Unix(cast.ToInt64(detail.GetValue("发生时间")), 0).Format("2006-01-02") - refund.RefundAmount = cast.ToFloat64(detail.GetValue("报销费用")) - refund.RefundRemark = detail.GetValue("报销说明") - - if isUpdate { - err = dao.NewApprovalRefundDao().Update(refund) + if old != nil { + newData.Id = old.Id + newData.CreateTime = old.CreateTime + err = dbDao.Update(newData) } else { - _, err = dao.NewApprovalRefundDao().Create(refund) + _, err = dbDao.Create(newData) } + + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } +} + +func (a *Approve) handleCheckin(detail *weixin.ApproveDetail) { + newData := detail.ToCheckin() + dbDao := dao.NewApprovalCheckinDao() + + old, err := dbDao.GetBySpNo(detail.SpNo) + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } + if old != nil { + newData.Id = old.Id + newData.CreateTime = old.CreateTime + err = dbDao.Update(newData) + } else { + _, err = dbDao.Create(newData) + } + + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } +} +func (a *Approve) handleRefund(detail *weixin.ApproveDetail) { + newData := detail.ToRefund() + dbDao := dao.NewApprovalRefundDao() + + old, err := dbDao.GetBySpNo(detail.SpNo) + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } + if old != nil { + newData.Id = old.Id + newData.CreateTime = old.CreateTime + err = dbDao.Update(newData) + } else { + _, err = dbDao.Create(newData) + } + if err != nil { log.Errorf("db error :%s", err.Error()) return @@ -116,27 +142,27 @@ func (a *Approve) handleRefund(spNo string) { // 支付费用 var req weixin.RedMoneyReq - req.BillNo = fmt.Sprintf("BX%s%s", refund.SpNo, butil.CutTail(refund.Username, 12)) - req.Title = fmt.Sprintf("【%s】报销", refund.RefundType) - req.Userid = refund.Username - req.TotalAmount = int64(100 * refund.RefundAmount) + req.BillNo = fmt.Sprintf("BX%s%s", newData.SpNo, butil.CutTail(newData.Username, 12)) + req.Title = fmt.Sprintf("【%s】报销", newData.RefundType) + req.Userid = newData.Username + req.TotalAmount = int64(100 * newData.RefundAmount) if err := weixin.NewQyPay().PayRedMoney(&req); err != nil { log.Errorf("pay error :%s", err.Error()) return } message := make([]string, 0) - message = append(message, fmt.Sprintf("【红包发放】[%s]", refund.RefundType)) - message = append(message, fmt.Sprintf("发放金额:%s", fmt.Sprintf("%.2f", refund.RefundAmount))) - message = append(message, fmt.Sprintf("员工名称:%s", refund.Username)) - message = append(message, fmt.Sprintf("费用说明:%s", refund.RefundRemark)) + message = append(message, fmt.Sprintf("【红包发放】[%s]", newData.RefundType)) + message = append(message, fmt.Sprintf("发放金额:%s", fmt.Sprintf("%.2f", newData.RefundAmount))) + message = append(message, fmt.Sprintf("员工名称:%s", newData.Username)) + message = append(message, fmt.Sprintf("费用说明:%s", newData.RefundRemark)) if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil { log.Errorf("send message error :%s", err.Error()) } - refund.Status = model.ApprovalRefundStatusPayed - if err := dao.NewApprovalRefundDao().Update(refund); err != nil { + newData.Status = model.ApprovalRefundStatusPayed + if err := dao.NewApprovalRefundDao().Update(newData); err != nil { log.Errorf("db error :%s", err.Error()) } } diff --git a/worker/approval.go b/worker/approval.go index cf169f5..03d4404 100644 --- a/worker/approval.go +++ b/worker/approval.go @@ -6,17 +6,25 @@ import ( "enterprise/common/model" "enterprise/common/weixin" log "github.com/sirupsen/logrus" - "github.com/smbrave/goutil" - "github.com/spf13/cast" - "strings" "time" ) type Approval struct { } -func (s *Approval) SyncCheckinMonth(month string) { - templateId := "C4UCJS891Afmu1rE1Ws6cvph7YHqebWtt7KRFqh8c" +func (s *Approval) getTemplateId(tp string) string { + if tp == model.ApprovalTypeCheckin { + return "C4UCJS891Afmu1rE1Ws6cvph7YHqebWtt7KRFqh8c" + } else if tp == model.ApprovalTypeRefund { + return "C4UE6NT3ZE7XzER9TBk2ynHEeqA11NE2GGCuBq5yH" + } else if tp == model.ApprovalTypeVacation { + return "3WLJF6naF5jhnXvwisuPmE85wVMYcy1S1ZvYibkw" + } + return "" +} + +func (s *Approval) Sync(month, tp string) { + templateId := s.getTemplateId(tp) cfg := config.GetConfig().QyWeixin approve := weixin.NewQyWeixinApprove(cfg.Corpid, cfg.ApproveSecret, cfg.ApproveAgent) startTime, _ := time.ParseInLocation("200601", month, time.Local) @@ -26,42 +34,81 @@ func (s *Approval) SyncCheckinMonth(month string) { log.Errorf("approve getlist error :%s", err.Error()) return } - //result := make(map[string]float64) + for _, spNo := range spNos { detail, err := approve.GetDetail(spNo) if err != nil { log.Errorf("approve GetDetail error :%s", err.Error()) continue } - - value := strings.SplitN(detail.GetValue("补卡"), ",", 3) - - ac, err := dao.NewApprovalCheckinDao().GetBySpNo(spNo) - if err != nil { - log.Errorf("db error :%s", err.Error()) - continue - } - isNew := false - if ac == nil { - ac = new(model.ApprovalCheckin) - ac.SpNo = detail.SpNo - isNew = true - } - - ac.Username = detail.GetUserid() - ac.ApplyTime = goutil.TimeToDateTime(detail.ApplyTime) - ac.CheckinRemark = detail.GetValue("补卡事由") - ac.CheckinDate = goutil.TimeToDate(cast.ToInt64(value[0])) - ac.CheckinTime = goutil.TimeToDateTime(cast.ToInt64(value[1])) - ac.CheckinType = value[2] - if isNew { - _, err = dao.NewApprovalCheckinDao().Create(ac) - } else { - err = dao.NewApprovalCheckinDao().Update(ac) - } - if err != nil { - log.Errorf("db error :%s", err.Error()) + if tp == model.ApprovalTypeCheckin { + s.saveCheckin(detail) + } else if tp == model.ApprovalTypeRefund { + s.saveRefund(detail) + } else if tp == model.ApprovalTypeVacation { + s.saveVacation(detail) } } + return } + +func (s *Approval) saveCheckin(detail *weixin.ApproveDetail) { + dbDao := dao.NewApprovalCheckinDao() + newData := detail.ToCheckin() + old, err := dbDao.GetBySpNo(detail.SpNo) + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } + if old == nil { + _, err = dbDao.Create(newData) + } else { + newData.Id = old.Id + newData.CreateTime = old.CreateTime + err = dbDao.Update(newData) + } + if err != nil { + log.Errorf("db error :%s", err.Error()) + } +} + +func (s *Approval) saveRefund(detail *weixin.ApproveDetail) { + dbDao := dao.NewApprovalRefundDao() + newData := detail.ToRefund() + old, err := dbDao.GetBySpNo(detail.SpNo) + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } + if old == nil { + _, err = dbDao.Create(newData) + } else { + newData.Id = old.Id + newData.CreateTime = old.CreateTime + err = dbDao.Update(newData) + } + if err != nil { + log.Errorf("db error :%s", err.Error()) + } +} + +func (s *Approval) saveVacation(detail *weixin.ApproveDetail) { + dbDao := dao.NewApprovalVacationDao() + newData := detail.ToVacation() + old, err := dbDao.GetBySpNo(detail.SpNo) + if err != nil { + log.Errorf("db error :%s", err.Error()) + return + } + if old == nil { + _, err = dbDao.Create(newData) + } else { + newData.Id = old.Id + newData.CreateTime = old.CreateTime + err = dbDao.Update(newData) + } + if err != nil { + log.Errorf("db error :%s", err.Error()) + } +}