calculator

This commit is contained in:
jiangyong27 2025-03-13 19:19:30 +08:00
parent d5ff34e7e7
commit fababb11d3
10 changed files with 164 additions and 29 deletions

View File

@ -1,5 +1,5 @@
FROM registry.cn-shanghai.aliyuncs.com/devcon/godev:v1.0.18
ADD . /app/src
#ADD . /app/src
WORKDIR /app/src
RUN mkdir -p /app/bin /app/log

View File

@ -58,8 +58,21 @@ func (d *DBLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql st
func initDB() error {
cfg := config.GetConfig()
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", cfg.Mysql.User,
cfg.Mysql.Pass, cfg.Mysql.Host, cfg.Mysql.Port, cfg.Mysql.Db)
/*
[mysql]
host = "10.0.2.157"
port = 3308
user = "root"
pass = "ZW5aaGVuMIIBIj"
db = "enterprise"
host = "14.22.113.49"
port = 9352
*/
dsn := "root:ZW5aaGVuMIIBIj@tcp(10.0.2.157:3308)/enterprise"
if config.IsDevEnv() {
dsn = "root:ZW5aaGVuMIIBIj@tcp(14.22.113.49:9352)/enterprise"
}
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})

View File

@ -14,13 +14,13 @@ func init() {
}
type SalaryCalculator interface {
Calculate(salary *model.StaffSalary)
Calculate(salary *model.StaffSalary) map[string]interface{}
}
type SalaryCalculatorFactory func(corp *model.Corp, user *model.StaffUser) SalaryCalculator
func RegisterSalaryCalculator(name string, factory SalaryCalculatorFactory) {
salaryFactory[name] = factory
func RegisterSalaryCalculator(key string, factory SalaryCalculatorFactory) {
salaryFactory[key] = factory
}
func NewSalaryCalculator(corp *model.Corp, user *model.StaffUser) SalaryCalculator {

View File

@ -7,7 +7,7 @@ log_level = 6
host = "14.22.113.49"
port = 9352
user = "root"
pass = "ZW5aaGVuMIIBIj"
pass = "fffasda#@2error"
db = "enterprise"
[unify_mysql]

View File

@ -4,10 +4,10 @@ address = "0.0.0.0:9283"
log_level = 6
[mysql]
host = "10.0.2.157"
port = 3308
host = ""
port = 0
user = "root"
pass = "ZW5aaGVuMIIBIj"
pass = "aabcdewff@2error"
db = "enterprise"
[unify_mysql]

3
go.mod
View File

@ -16,6 +16,7 @@ require (
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/mitchellh/mapstructure v1.5.0
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/robertkrimen/otto v0.5.1
github.com/sirupsen/logrus v1.9.3
github.com/smartwalle/alipay/v3 v3.2.23
github.com/smbrave/goutil v0.0.0-20250312151244-845a8a40e8aa
@ -30,7 +31,6 @@ require (
require (
github.com/ArtisanCloud/PowerLibs/v3 v3.2.3 // indirect
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 // indirect
github.com/Knetic/govaluate v3.0.0+incompatible // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
@ -96,5 +96,6 @@ require (
golang.org/x/text v0.23.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@ -28,7 +28,11 @@ func NewSalaryCalculator1000(corp *model.Corp, user *model.StaffUser) registry.S
}
}
func (s *SalaryCalculator1000) Calculate(salary *model.StaffSalary) {
func (s *SalaryCalculator1000) Calculate(salary *model.StaffSalary) map[string]interface{} {
return nil
}
func (s *SalaryCalculator1000) CalculateDe(salary *model.StaffSalary) {
userSlary := s.user.GetSalary()
userConfig := s.user.GetConfig()
if s.user.Status == model.StaffUserStatusAttach { //挂靠直接算工资

View File

@ -22,7 +22,11 @@ func NewSalaryCalculator1000Wujiefeng(corp *model.Corp, user *model.StaffUser) r
}
}
func (s *SalaryCalculator1000Wujiefeng) Calculate(salary *model.StaffSalary) {
func (s *SalaryCalculator1000Wujiefeng) Calculate(salary *model.StaffSalary) map[string]interface{} {
return nil
}
func (s *SalaryCalculator1000Wujiefeng) CalculateDel(salary *model.StaffSalary) {
baseCalculate := NewSalaryCalculator1000(s.corp, s.user)
baseCalculate.Calculate(salary)

View File

@ -21,7 +21,45 @@ func NewSalaryCalculator1002(corp *model.Corp, user *model.StaffUser) registry.S
}
}
func (s *SalaryCalculator1002) Calculate(salary *model.StaffSalary) {
func (s *SalaryCalculator1002) Calculate(salary *model.StaffSalary) map[string]interface{} {
data := make(map[string]interface{})
// 1.订单
monthTime, _ := time.ParseInLocation("200601", salary.Month, time.Local)
startTime := monthTime.Unix()
endTime := monthTime.AddDate(0, 1, 0).Unix() - 1
orders, err := dao.NewExternalCorpOrder().QueryOwnerOrder(s.user.Username, startTime, endTime)
if err != nil {
log.Errorf("db error:%s", err.Error())
}
data["order_num"] = cast.ToString(len(orders))
//2.处理的订单
processOrders, err := dao.NewExternalCorpOrder().QueryProcessOrder(s.user.Username, startTime, endTime)
if err != nil {
log.Errorf("db error:%s", err.Error())
}
data["process_num"] = cast.ToString(len(processOrders))
//3.下属订单
corpUser, err := dao.NewExternalCorpUser().Get(s.user.Username)
if err != nil {
log.Errorf("db error:%s", err.Error())
}
if corpUser != nil {
childOrders, err := dao.NewExternalCorpOrder().QueryChildOrder(corpUser.Id, startTime, endTime)
if err != nil {
log.Errorf("db error:%s", err.Error())
}
data["child_order_num"] = cast.ToString(len(childOrders))
}
return data
}
func (s *SalaryCalculator1002) CalculateDel(salary *model.StaffSalary) {
userSlary := s.user.GetSalary()
if s.user.Status == model.StaffUserStatusAttach { //挂靠直接算工资
salary.AttendSalary = cast.ToFloat64(userSlary.Base)

View File

@ -5,7 +5,7 @@ import (
"enterprise/common/dao"
"enterprise/common/model"
"enterprise/common/registry"
"fmt"
"github.com/robertkrimen/otto"
log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
@ -63,31 +63,106 @@ func (s *StaffSalary) CalcSalary(salary *model.StaffSalary, month string) (*mode
holiday, surplusHoliday := s.getRealVacationDay(month)
realWorkDays := s.getRealWorkDay(month)
approvalCheckinDay := s.getApprovalCheckinDay(s.user.CorpId, s.user.Username, month)
fmt.Println(s.user.Username, realWorkDays, holiday, surplusHoliday)
//approvalCheckinDay := s.getApprovalCheckinDay(s.user.CorpId, s.user.Username, month)
salary.HolidayDay = holiday
salary.AttendDay = realWorkDays + surplusHoliday
salary.Salary = cast.ToFloat64(userSalary.Base) + cast.ToFloat64(userSalary.Target)
salary.SocialDeduct = goutil.If(userConfig.SocialDeduct != "", cast.ToFloat64(userConfig.SocialDeduct), cast.ToFloat64(corpConfig.SocialDeduct))
salary.HouseDeduct = goutil.If(userConfig.HouseDeduct != "", cast.ToFloat64(userConfig.HouseDeduct), cast.ToFloat64(corpConfig.HouseDeduct))
extra := make(map[string]interface{})
extra["approvalCheckinDay"] = approvalCheckinDay //展示依赖
extra["entryDate"] = s.user.EntryDate //展示排序依赖
extra["leaveDate"] = s.user.LeaveDate //展示排序依赖
extra["baseSalary"] = userSalary.Base
extra["targetSalary"] = userSalary.Target
//计算工资
salary.Extra = goutil.EncodeJSONIndent(extra)
calculator := registry.NewSalaryCalculator(corp, s.user)
if calculator != nil {
calculator.Calculate(salary)
}
s.formatFloat(salary)
return salary, nil
}
func (s *StaffSalary) calculate(corp *model.Corp, salary *model.StaffSalary) {
//获取基础数据
data := s.getCalcData(salary)
//获取业务数据
dataFactory := registry.NewSalaryCalculator(corp, s.user)
if dataFactory != nil {
data["biz"] = dataFactory.Calculate(salary)
}
salary.Extra = goutil.EncodeJSONIndent(data)
//获取计算器表达式
calculator, _ := dao.NewSalaryCalculatorDao().Get(cast.ToInt64(s.user.GetSalary().Calculator))
if calculator == nil {
log.Errorf("calculator[%d] is nil", s.user.GetSalary().Calculator)
return
}
//执行表达式
jsrun := otto.New()
jsrun.Set("data", data)
jsrun.Run(calculator.Expression)
//出勤工资
attendSalary, err := jsrun.Get("attend_salary")
if err != nil {
log.Errorf("attend_salary error :%s", err.Error())
} else {
salary.AttendSalary, err = attendSalary.ToFloat()
if err != nil {
log.Errorf("attendSalary foloat is error:%s", err.Error())
}
}
//绩效工资
targetSalary, err := jsrun.Get("target_salary")
if err != nil {
log.Errorf("attend_salary error :%s", err.Error())
} else {
salary.TargetSalary, err = targetSalary.ToFloat()
if err != nil {
log.Errorf("targetSalary foloat is error:%s", err.Error())
}
}
//奖金
awardSalary, err := jsrun.Get("award_salary")
if err != nil {
log.Errorf("attend_salary error :%s", err.Error())
} else {
salary.AwardSalary, err = awardSalary.ToFloat()
if err != nil {
log.Errorf("awardSalary foloat is error:%s", err.Error())
}
}
}
func (s *StaffSalary) getCalcData(mSalary *model.StaffSalary) map[string]interface{} {
userSalary := s.user.GetSalary()
userConfig := s.user.GetConfig()
data := make(map[string]interface{})
user := make(map[string]interface{})
salary := make(map[string]interface{})
user["username"] = s.user.Username //账户名称
user["status"] = s.user.Status //状态
user["entryDate"] = s.user.EntryDate //入职时间
user["officalDate"] = s.user.OfficialDate //转正时间
user["leaveDate"] = s.user.LeaveDate //离职时间
user["baseSalary"] = userSalary.Base //基本工资
user["targetSalary"] = userSalary.Target //绩效工资
user["target"] = userConfig.PerftTarget //绩效目标
salary["month"] = mSalary.Month //工资月份
salary["shouldDay"] = mSalary.ShouldDay //应出勤天数
salary["attendDay"] = mSalary.AttendDay //实际出勤天数
salary["holidayDay"] = mSalary.HolidayDay //休假天数
data["user"] = user
data["salary"] = salary
return data
}
func (s *StaffSalary) formatFloat(salary *model.StaffSalary) {
salary.AwardSalary = butil.FloatCut(salary.AwardSalary)
salary.AttendSalary = butil.FloatCut(salary.AttendSalary)